跟着书本学JavaScript设计模式(抽象工厂模式)

234 阅读3分钟

抽象工厂模式

通过对类的工厂抽象使其业务用于对产品类簇的创建,而不是负责创建某一类产品的实例。


    // 汽车抽象类,当使用其实例对象的方法时会抛出错误
    var Car = function () { };
    Car.prototype = {
      getPrice: function () {
        return new Error('抽象方法不能调用')
      },
      getSpeed: function () {
        return new Error('抽象方法不能调用')
      }
    }

如果子类通过继承创建了实例,而没有去具体去重写实现,那么父类就会报出错误。


幽灵工厂 - 抽象工厂模式

面向对象语言中有一种很厂家你的模式叫抽象工厂模式,但是在JavaScirpt中如何实现抽象工厂模式呢。

    // 抽象工厂方法
    var VehicleFactory = function (subType, superType) {
      if (typeof VehicleFactory[superType] === 'function') {
        // 过渡类
        var F = function () { };
        // 继承父类的属性和方法
        F.prototype = new VehicleFactory[superType]();
        // 将子类的constructor指向子类
        subType.constructor = subType;
        // 子类继承父类
        subType.prototype = new F();
      } else {
        throw new Error('未创建该抽象类')
      }
    }

    // 汽车抽象类
    VehicleFactory.Car = function () {
      this.type = 'car';
    }
    VehicleFactory.Car.prototype = {
      getPrice: function () {
        return new Error('抽象方法不能调用')
      },
      getSpeed: function () {
        return new Error('抽象方法不能调用')
      }
    }

    // 公交车抽象类
    VehicleFactory.Bus = function () {
      this.type = 'bus';
    }
    VehicleFactory.Bus.prototype = {
      getPrice: function () {
        return new Error('抽象方法不能调用')
      },
      getSpeed: function () {
        return new Error('抽象方法不能调用')
      }
    }

    // 货车抽象类
    VehicleFactory.Truck = function () {
      this.type = 'truck';
    }
    VehicleFactory.Truck.prototype = {
      getPrice: function () {
        return new Error('抽象方法不能调用')
      },
      getSpeed: function () {
        return new Error('抽象方法不能调用')
      }
    }

抽象工厂其实就是一个实现子类继承父类的方法,在这个方法中我们需要通过传递子类以及要继承父类(抽象类)的名称,并且在抽象工厂方法中增加了一次对抽象类存在性的一次判断,如果存在,则将子类继承父类的方法,然后子类通过寄生式继承。


抽象与实现

通过创建的抽象工厂来创建子类,并对子类的具体的方法实现。

    // 宝马汽车子类
    var BMW = function (price, speed) {
      this.price = price;
      this.speed = speed;
    }

    VehicleFactory(BMW, 'Car');
    BMW.prototype.getPrice = function () {
      return this.price;
    }
    BMW.prototype.getSpeed = function () {
      return this.speed;
    }

    // 兰博基尼汽车子类
    var Lamborghini = function (price, speed) {
      this.price = price;
      this.speed = speed;
    }
    VehicleFactory(Lamborghini, 'Car');
    Lamborghini.prototype.getPrice = function () {
      return this.price;
    }
    Lamborghini.prototype.getSpeed = function () {
      return this.speed;
    }

    // 宇通汽车子类
    var YUTONG = function (price, speed) {
      this.price = price;
      this.speed = speed;
    }
    VehicleFactory(YUTONG, 'Car');
    YUTONG.prototype.getPrice = function () {
      return this.price;
    }
    YUTONG.prototype.getSpeed = function () {
      return this.speed;
    }

    // 测试代码
    var bmw = new BMW(1000000, 200);
    console.log(bmw.type); //  car
    console.log(bmw.getPrice()) // 1000000
    console.log(bmw.getSpeed()) // 200


总结

抽象工厂模式是设计模式中最抽象的一种,也是创建模式中唯一一种抽象化创建模式。改模式创建出的结果不是一个真实的对象实例,而是一个类簇,它制定了类的结构,这也就是区别于简单工厂模式创建单一对象,工厂方法模式创建多类对象,当然由于JavaScript中不支持抽象化创建与虚拟方法,所以导致这种模式不能像其他面向对象语言中应用的那么广泛.