zoukankan      html  css  js  c++  java
  • 抽象工厂模式

    一、定义

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

    二、抽象工厂模式

      继承抽象类是很有用的,因为定义了一种类,并定义了该类所必要的方法,如果在子类中没有重写这些方法,那么当调用时能找到这些方法,但会报错。这一特点在大型项目中是很有效的,总会有一些子类去继承另一些父类,这些父类经常会定义一些必要的方法,却没有具体实现,子类如果没有重写,父类有友好的提示,这样对于忘记重写子类的这些错误遗漏的避免是很帮助的。

     1 // 抽象工厂方法
     2 var VehicleFactory = function(subType, superType) {
     3     // 判断抽象工厂中是否有该抽象类
     4     if(typeof VehicleFactory[superType] === 'function') {
     5         // 缓存类
     6         function F() {};
     7         // 继承父类属性和方法
     8         F.prototype = new VehicleFactory[superType]();
     9         // 将子类constructor指向子类
    10         subType.constructor = subType;
    11         // 子类原型继承‘父类’
    12         subType.prototype = new F();
    13     }else {
    14         // 不存在该抽象类抛出错误
    15         throw new Error('未创建该抽象类')
    16     }
    17 }
    18 // 小汽车抽象类
    19 VehicleFactory.Car = function() {
    20     this.type = 'car';
    21 };
    22 VehicleFactory.Car.prototype = {
    23     getPrice: function() {
    24         return new Error('抽象方法不能调用');
    25     },
    26     getSpeed: function() {
    27         return new Error('抽象方法不能调用')
    28     }
    29 };
    30 // 公交车抽象类
    31 VehicleFactory.Bus = function() {
    32     this.type = 'bus';
    33 };
    34 VehicleFactory.Bus.prototype = {
    35     getPrice: function() {
    36         return new Error('抽象方法不能调用');
    37     },
    38     getPassengerNum: function() {
    39         new Error('抽象方法不能调用');
    40     }
    41 }
    42 // 货车抽象类
    43 VehicleFactory.Truck = function() {
    44     this.type = 'truck';
    45 }
    46 VehicleFactory.Truck.prototype = {
    47     getPrice: function() {
    48         return new Error('抽象方法不能调用');
    49     },
    50     getTrainload: function() {
    51         new Error('抽象方法不能调用');
    52     }
    53 }

      抽象工厂其实是一个实现子类继承父类的方法,通过传递子类以及要继承父类(抽象类)的名称,在抽象工厂方法中又增加了一次对抽象类存在性的一次判断,如果存在,则将子类继承父类的方法。子类通过寄生式继承,在继承父类过程中需要注意,在对过渡类的原型继承时,不是继承父类的原型,而是通过new关键字复制的父类的一个实例,这么做事因为过渡类不仅要继承父类的原型方法,还要继承父类的对象属性。

    三、抽象与实现

     1 // 宝马汽车子类
     2 var BMW = function(price, speed) {
     3     this.price = price;
     4     this.speed = speed;
     5 }
     6 // 抽象工厂实现对Car抽象类的继承
     7 VehicleFactory(BMW, 'Car');
     8 BMW.prototype.getPrice = function() {
     9     return this.price;
    10 }
    11 BMW.prototype.getSpeed = function() {
    12     return this.speed;
    13 }
    14 // 兰博基尼汽车子类
    15 var Lamborghini = function(price, speed) {
    16     this.price = price;
    17     this.speed = speed;
    18 }
    19 // 抽象工厂实现对Car抽象类的继承
    20 VehicleFactory(Lamborghini, 'Car');
    21 Lamborghini.prototype.getPrice = function() {
    22     return this.price;
    23 }
    24 Lamborghini.prototype.getSpeed = function() {
    25     return this.speed;
    26 }
    27 // 抽象工厂实现对Car抽象类的继承
    28 VehicleFactory(Lamborghini, 'Car');
    29 Lamborghini.prototype.getPrice = function() {
    30     return this.price;
    31 };
    32 Lamborghini.prototype.getSpeed = function() {
    33     return this.speed;
    34 };
    35 // 宇通汽车子类
    36 var YUTONG = function(price, passenger) {
    37     this.price = price;
    38     this.passenger = passenger;
    39 };
    40 // 抽象工厂实现时对Bus抽象类的继承
    41 VehicleFactory(YUTONG, 'Bus');
    42 YUTONG.prototype.getPassengerNum = function() {
    43     return this.passenger;
    44 };
    45 // 奔驰汽车子类
    46 var BenzTruck = function(price, trainLoad){
    47     this.price = price;
    48     this.trainLoad = trainLoad;
    49 }
    50 // 抽象工厂实现时对Truck抽象类的继承
    51 VehicleFactory(BenzTruck, 'Truck');
    52 BenzTruck.prototype.getPrice = function() {
    53     return this.price;
    54 }
    55 BenzTruck.prototype.getTrainload = function() {
    56     return this.trainLoad
    57 }
    58 
    59 // 测试类
    60 var truck = new BenzTruck(1000000, 1000);
    61 console.log(truck.getPrice()); // 1000000
    62 console.log(truck.type); // truck
    63 console.log(truck.trainLoad); // 1000

    参考资料:《JavaScript设计模式》

  • 相关阅读:
    js封装日期格式化函数
    原生js时间戳获取和转换
    自适应好用的一个css
    ES6五种遍历对象属性的方式
    ES6对象属性名简洁表示法和表达式、对象新方法、属性的遍历
    ES6数组扩展运算符(Rest+Spread)、类方法、原型方法
    正则表达式常见匹配
    typescript深copy和浅copy
    判断一个变量类型是对象还是数组
    npm 淘宝镜像的配置
  • 原文地址:https://www.cnblogs.com/daheiylx/p/13839935.html
Copyright © 2011-2022 走看看