• js-工厂模式


    首先需要说一下工厂模式。工厂模式根据抽象程度的不同分为三种

    • 简单工厂模式
    • 工厂方法模式
    • 抽象工厂模式

    1.简单工厂模式

    简单工厂模式:又称为静态工厂方法模式,它属于类创建型模式。
    在简单工厂模式中,可以根据参数的不同返回不同类的实例。
    由工厂对象决定创建某一种产品对象类的实例。

    let Ball= function(name){
            let A = new Object();
            A.name = name;
            A.play = function(){
                console.log(`我在打${name}`)
            }
            return A
        }
        let football =  Ball('足球');
        console.log(football)
        football.play(); // 我在打足球
        let basketball =  Ball('篮球');
        basketball.play()  // 我在打篮球
    

    这段案例可以这么去理解,假设我们需要多个球,我们希望在使用球
    的时候,只需要告诉管理员我们需要的球的类型,不需要一个个去找对应的球
    这个管理员就相对于工厂函数。
    简单讲就是使用简单工厂模式,那么你就不需要关心它的具体实现,
    你只需要知道你要使用的类型,那么工厂函数会自动帮你去做对应的事情

    简单模式的优点

    • 简单讲就是使用简单工厂模式,那么你就不需要关心它的具体实现,
      你只需要知道你要使用的类型,那么工厂函数会自动帮你去做对应的事情。
    • 简单工厂模式最大的优点在于实现对象的创建和对象的使用分离,将对象的创建交给专门的工厂类负责

    简单模式的缺点

    • 由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响
    • 使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
    • 工厂类不够灵活,增加新的具体产品需要修改工厂类的判断逻辑代码,而且产品较多时,工厂方法代码将会非常复杂。

    2.工厂方法模式

    工厂方法模式:又称为工厂模式,也叫虚拟构造器模式或者多态工厂模式
    它属于类创建型模式。在工厂方法模式中,工厂父类负责定义创建产品对
    象的公共接口,而工厂子类则负责生成具体的产品对象,
    这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,
    即通过工厂子类来确定究竟应该实例化哪一个具体产品类

     let UserFactory = function(role) {
      if(this instanceof UserFactory) {
        var s = new this[role]();
        return s;
      } else {
        return new UserFactory(role);
      }
    }
    
    //工厂方法函数的原型中设置所有对象的构造函数
    UserFactory.prototype = {
      SuperAdmin: function() {
        this.name = "超级管理员",
        this.viewPage = ['首页', '通讯录', '发现页', '应用数据', '权限管理']
      },
      Admin: function() {
        this.name = "管理员",
        this.viewPage = ['首页', '通讯录', '发现页', '应用数据']
      },
      NormalUser: function() {
        this.name = '普通用户',
        this.viewPage = ['首页', '通讯录', '发现页']
      }
    }
    
    //调用
    let superAdmin = UserFactory('SuperAdmin');
    let admin = UserFactory('Admin') 
    let normalUser = UserFactory('NormalUser')
    

    工厂方法模式的优点

    • 在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节,用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。
    • 基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够使工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。工厂方法模式之所以又被称为多态工厂模式,是因为所有的具体工厂类都具有同一抽象父类。
    • 使用工厂方法模式的另一个优点是在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了。这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”。

    工厂方法模式的缺点

    • 在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
    • 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度

    3.抽象工厂模式

    抽象工厂其实是一个实现子类继承父类的方法,在这个方法种我我们需要传入子类以及要继承父类的名称.
    过渡类的原型继承,不是继承父类的原型,而是通过new 复制一个父类的实例,过渡类不仅仅继承了父类的原型方法,还继承了父类的对象属性.
    使用方法

    let AccountAbstractFactory = function(subType, superType) {
      //判断抽象工厂中是否有该抽象类
      if(typeof AccountAbstractFactory[superType] === 'function') {
        //缓存类
        function F() {};
        //继承父类属性和方法
        F.prototype = new AccountAbstractFactory[superType] ();
        //将子类的constructor指向子类
        subType.constructor = subType;
        //子类原型继承父类
        subType.prototype = new F();
    
      } else {
        throw new Error('抽象类不存在!')
      }
    }
    //微信用户抽象类
    AccountAbstractFactory.WechatUser = function() {
      this.type = 'wechat';
    }
    AccountAbstractFactory.WechatUser.prototype = {
      getName: function() {
        return new Error('抽象方法不能调用');
      }
    }
    //普通微信用户子类
    function UserOfWechat(name) {
      this.name = name;
      this.viewPage = ['首页', '通讯录', '发现页']
    }
    //抽象工厂实现WechatUser类的继承
    AccountAbstractFactory(UserOfWechat, 'WechatUser');
    //子类中重写抽象方法
    UserOfWechat.prototype.getName = function() {
      return this.name;
    }
    //实例化微信用户
    let wechatUserA = new UserOfWechat('微信小李');
    console.log(wechatUserA.getName(), wechatUserA.type); //微信小李 wechat
    let wechatUserB = new UserOfWechat('微信小王');
    console.log(wechatUserB.getName(), wechatUserB.type); //微信小王 wechat
    
  • 相关阅读:
    Java设计模式(学习整理)---工厂模式
    Java Swing 使用总结(转载)
    Java-生成验证码图片(自定义内容,尺寸,路径)
    二维码(带有图片)的生成
    J2se中的声音---AudioPlayer
    文件的读取和写入(指定路径)
    ASP.NET:使用Flurl制作可复用的分页组件
    ASP.NET:Forms身份验证和基于Role的权限验证
    ASP.NET:MVC模板化机制
    ASP.NET:MVC中文件上传与地址变化处理
  • 原文地址:https://www.cnblogs.com/mengxiangji/p/10403867.html
Copyright © 2020-2023  润新知