zoukankan      html  css  js  c++  java
  • 【Javascript设计模式】第四课 幽灵工厂——抽象工厂模式

    在JavaScript中abstract是一个保留字,所谓的抽象类是一种声明但是不能使用的类,当你使用时就会报错,这时我们可以手动将错误抛出;
    1. var Car = function(){};
    2. Car.prototype = {
    3. getPrice : function () {
    4. throw new Error("抽象方法不能调用");
    5. },
    6. getSpeed : function () {
    7. throw new Error("抽象方法不能调用");
    8. }
    9. };
    如果调用的话,使用debug调试得出
    1. var car = new Car();
    2. car.getPrice();//Car is not defined

    我们创建的这个Car类,其实什么都不能做,类中没有定义属性,原型的方法也不能使用。但是在继承上很有用,因为定义了一个类,并且定义了该类所具备的方法,如果在子类中继承父类,没有重写这些方法,那么当调用时没有找到这些方法就会报错。

    对于抽象类有一个对应的模式——抽象工厂模式
    1. /*******************************************
    2. * 抽象工厂模式
    3. ******************************************/
    4. var VehicleFactory = function (subType, superType) {
    5. //判断抽象工厂中是否有该抽象类
    6. if(typeof VehicleFactory[superType] === 'function'){
    7. //定义一个缓存类
    8. function F(){};
    9. //继承父类的属性和方法
    10. F.prototype = new VehicleFactory[superType]();
    11. //将子类constructor指向子类
    12. subType.constructor = subType;
    13. //子类原型继承父类
    14. subType.prototype = new F();
    15. }else{
    16. throw new Error('未创建该抽象类');
    17. }
    18. }
    1. //定义一个小汽车类
    2. VehicleFactory.Car= function () {
    3. this.type = 'car';
    4. }
    5. VehicleFactory.Car.prototype = {
    6. getPrice : function(){
    7. throw new Error('未创建该抽象类');
    8. },
    9. getSpeed : function () {
    10. throw new Error('未创建该抽象类');
    11. }
    12. }
    13. //定义一个公交车类
    14. VehicleFactory.Bus= function () {
    15. this.type = 'bus';
    16. }
    17. VehicleFactory.Bus.prototype = {
    18. getPrice : function () {
    19. throw new Error('未创建该抽象类');
    20. },
    21. getSpeed : function () {
    22. throw new Error('未创建该抽象类');
    23. }
    24. }
    从上面可以看到抽象工厂其实就是一个实现子类继承父类的方法,在这个方法中我们需要通过传递子类以及要继承父类(抽象类)的名称,并且在抽象工厂方法中添加了一次对抽象类存在性的判断,如果存在,则将子类继承父类的方法,然后子类通过寄生式继承。
    测试如下:
    1. var BMW = function (price, speed) {
    2. this.price = price;
    3. this.speed = speed;
    4. }
    5. VehicleFactory(BMW,'Car');
    6. BMW.prototype.getPrice = function () {
    7. return this.price;
    8. }
    9. BMW.prototype.getSpeed = function () {
    10. return this.speed;
    11. }
    12. var bmw = new BMW(1000,100);
    13. console.info(bmw.getSpeed());
    14. console.info(bmw.getPrice());
    抽象工厂模式、工厂方法模式以及简单工厂模式的异同点及其关系
        简单工厂,工厂方法以及抽象工厂都属于设计模式中的创建型模式,其主要功能都是帮助我们把对象实例化部分抽取出来,优化了系统的架构,增强了系统的扩展性。

    三者的共同点是:

    1、都有两种作用不同的类:产品类和工厂类。其中,工厂类在自己的方法中实例化产品类(即使用new命令生成产品类的对象),并将生成的产品类的对象提供给外部使用。

    2、创建的过程,都是类似的:工厂类得到一个标志(可以由程序输入,也可以读取配置文件中的内容),返回一个产品对象。 

    三者的不同点

    1、简单工厂

    简单工厂方法中,包括一个“抽象产品类(该类可以是接口Interface,也可以是实际的类Class),所有需要的产品类都是该抽象产品类的子类(如果是接口的话,那么就是说所有产品类都继承了该接口)。

    简单工厂一般只包含一个具体的工厂类,由该工厂类生成所有的产品类的对象。生成产品类的方法,其内部一般是类似于switch的结构,根据输入的标志,选择创建不同类型的对象。由于不知道创建的对象到底是哪个类的,所以方法的返回值的类型是抽象产品类

     

    2、工厂方法

    抽象工厂中,包括“抽象工厂类抽象产品类,同时包含不只一个工厂类。所有的工厂类都必须是抽象工厂类的子类,所有的产品都必须是抽象产品类的子类。

    和简单工厂比起来,工厂方法一般是从抽象工厂开始的。一般都是在抽象工厂类中提供一个静态方法,由该方法根据输入的标志,生成不同的具体工厂类,然后由具体的产品类生成具体的产品。注意,一个具体工厂类只能生成一种具体的产品类的对象,不同的具体工厂生成不同的产品,而不是像简单工厂中那样,一个工厂类可以生成多种不同产品类的对象。可以这么理解,在选择不同的具体工厂类的时候,就选择了生成的产品,相对于简单工厂,相当于将选择产品的动作提前了。

    因为不知道创建的具体工厂类到底是哪一个,所以生成具体工厂类的静态方法的返回值的类型是“抽象工厂类。具体工厂类生成产品类的方法,返回值的类型也要求是抽象产品类(因为前端调用的时候,需要使用同样的代码来访问)。 

    3、抽象工厂

    抽象工厂和工厂方法很类似,区别如下: 

    工厂方法模式:
    一个抽象产品类,可以派生出多个具体产品类。   
    一个抽象工厂类,可以派生出多个具体工厂类。   
    每个具体工厂类只能创建一个具体产品类的实例。 

    抽象工厂模式:
    多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。   
    一个抽象工厂类,可以派生出多个具体工厂类。   
    每个具体工厂类可以创建多个具体产品类的实例。       
    区别:
    工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。   
    工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个







    高质量的代码就是对程序自己最好的注释。当你打算要添加注释时,问问自己,“我如何能改进编码以至于根本不需要添加注释?”改进你的代码,然后才是用注释使它更清楚。
  • 相关阅读:
    中断向量表
    内核进程的堆栈 [转]
    int指令理解
    Linux进程创建和结束
    Linux 信号signal处理机制
    wait和waitpid详解
    linux 如何清理僵尸进程
    API:System V & POSI
    shell
    Code POJ
  • 原文地址:https://www.cnblogs.com/endy-blog/p/5967776.html
Copyright © 2011-2022 走看看