当前位置: 首页 > news >正文

JS设计模式之工厂模式

1 什么是工厂模式?

  工厂模式是用来创建对象的一种最常用的设计模式。我们不暴露创建对象的具体逻辑,而是将将逻辑封装在一个函数中,那么这个函数就可以被视为一个工厂。工厂模式根据抽象程度的不同可以分为:

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

 1-1 简单工厂模式

  简单工厂模式,又叫静态工厂方法,由一个工厂对象来决定创建某一种产品对象类的实例,主要用来创建同一类对象。

var basketball  = function(){
    this.title = '篮球';
}

basketball.prototype  = {
    getMenberNum :function(){
        console.log('5个人');
    },
    getPlayAction:function(){
        console.log('投篮')
    }
}

var football = function(){
    this.title = '足球';
}

football.prototype = {
    getMenberNum :function(){
        console.log('11个人');
    },
    getPlayAction:function(){
        console.log('射门')
    }
}

var factory = function(type){
    switch(type){
        case 'basketball': return new basketball();
        case 'football': return new football();
    }
}

//然后我们就可以这么用
oPlay = factory('basketball');
oPlay.getMenber();

oPlay2 = factory('football');
oPlay2.getPlayAction();
如果两个类的共有属性比较多的时候,我们可以这样用
var factory = function(name,age,sex,national){
    var obj = {};
    obj.name = name;
    obj.age = age;
    obj.sex = sex;
    switch(national){
        case 'Chinese':
            obj.speak = function(){
                console.log('Speak Chinese');
            };
            break;
        case 'England':
            obj.speak = function(){
                console.log('SpeakEnglish')
            };
            break;
    }
    return obj;
}

var person = new factory("Jack",'15','Man',"Chinese");
person.speak();
简单工厂的优点在于,你只需要一个正确的参数,就可以获取到你所需要的对象,而无需知道其创建的具体细节。但是在函数内包含了所有对象的创建逻辑(构造函数)和判断逻辑的代码,每增加新的构造函数还需要修改判断逻辑代码。当我们的对象不是上面的3个而是30个或更多时,这个函数会成为一个庞大的超级函数,便得难以维护。所以,简单工厂只能作用于 创建的对象数量较少,对象的创建逻辑不复杂时使用
 

 1-2 工厂方法模式

工厂方法模式,通过对产品类的抽象使其创建业务主要负责用于创建多类产品的实例。

  var Court = function (type, content) {
      if (this instanceof Court) {
        return new this[type](content);
      } else {
        return new Court(type, content);
      }
    }

    Court.prototype = {
      basketball : function (content) {
        this.content = content;
        (function (content) {
          console.log(content + 'basketball');
        })(content);
      },
      football : function (content) {
        this.content = content;
        (function (content) {
          console.log(content + 'football');
        })(content);
      }
    }

    var data = [{
        type: 'basketball',
        content: '5人打'
      },
      {
        type: 'football',
        content: '11人踢'
      }
    ];

    for (var i = 0; i < data.length; i++) {
      Court(data[i].type, data[i].content);
    }

    // 5人打basketball
    // 11人踢football

  对于创建多类对象,简单工厂就不太实用了。

   通过工厂方法模式可以轻松的创建多个类的实例对象,而且创建对象的方式避免了使用者与对象类之间的耦合,用户不必关心创建该对象的具体类,只需调用工厂方法即可。

 

  1-3 抽象工厂模式

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

/*定义一个抽象类 AbsProducer(生产商),该生产商有两个行为,一个生产,一个出售,其中生产方法为抽象方法,由具体的厂家去实现*/
 var AbsProducer = function(){};
   AbsProducer.prototype = {
    
     sell:function(name){
         var product = this.create(model);
         product.showName();
         return product;
     },
     create:function(name){
         throw new Error("抽象类不支持该操作");
     }
 }

  联想工厂:LenovoFactory.js

var LenovoFactory = function () {};
    extend(LenovoFactory, AbsProducer);
    LenovoFactory.prototype.create = function (name) {
      var product;
      switch (name) {
        case "phone":
          product = new LenovoPhone();
          break;
        case "computer":
          product = new LenovoComputer();
          break;
      }
      Interface.ensureImplements(product, ElectronicProduct);
      product.showName();
      return product;
    }

    function LenovoPhone() {};
    LenovoPhone.prototype = {
      showName: function () {
        console.log("我是联想厂商生产的手机,取名为Lenovo-phone");
      },
      showCpu: function () {
        console.log("联想手机cpu一般般咯");
      },
      showSysType: function () {
        console.log("姑且认为联想手机系统为WP吧");
      }
    };

    function LenovoComputer() {};
    LenovoComputer.prototype = {
      showName: function () {
        console.log("我是联想厂商生产的电脑,型号为Y系列");
      },
      showCpu: function () {
        console.log("联想电脑cpu,四代I7处理器");
      },
      showSysType: function () {
        console.log("联想电脑系统为正版win7");
      }
    };

  苹果工厂:AppleFactory.js

var AppleFactory = function () {};
    extend(AppleFactory, AbsProducer);
    AppleFactory.prototype.create = function (name) {
      var product;
      switch (name) {
        case "phone":
          product = new Iphone();
          break;
        case "computer":
          product = new Mac();
          break;
      }
      Interface.ensureImplements(product, ElectronicProduct);
      product.showName();
      return product;
    };

    function Iphone() {};
    Iphone.prototype = {
      showName: function () {
        console.log("我是苹果公司生产的手机,取名为Iphone");
      },
      showCpu: function () {
        console.log("iphone手机CPU是基于ARM架构重新设计的");
      },
      showSysType: function () {
        console.log("iphone系统为IOS9");
      }
    };

    function Mac() {};
    Mac.prototype = {
      showName: function () {
        console.log("我是苹果公司生产的电脑,取名为Mac");
      },
      showCpu: function () {
        console.log("mac cpu还不错吧");
      },
      showSysType: function () {
        console.log("mac系统为OS X");
      }
    };

  调用:

/*定义了一个ElectronicProduct电子产品的接口,该接口有以下几个名称*/
    var ElectronicProduct = new Interface("ElectronicProduct",["showName", "showCpu", "showSysType"]);
    //这里你想要哪个品牌的电子产品,直接new一个该品牌的工厂即可。
    var factory = new AppleFactory();
    var product = factory.create("phone");
    product.showSysType();
    product.showCpu();

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

转载于:https://www.cnblogs.com/Mr-Tao/p/10405848.html

相关文章:

  • Web前端开发必备手册(Cheat sheet)
  • 如何在招聘中考核.NET架构师
  • 《ActiveMQ 系列》- HelloWorld
  • SSM-Spring-02:Spring的DI初步加俩个实例
  • DOM的那些事
  • 【mysql】count(*),count(1)与count(column)区别
  • 北塔软件:BI+AI+DI,做IT运维数据掘金的使能者
  • 秋季学期学习总结
  • 如何解决微信端直接跳WAP端
  • iOS CAReplicatorLayer 简单动画
  • Java Activiti 工作流引擎 springmvc SSM 流程审批 后台框架源码
  • D-Uni 获斯道资本500万美元投资-「D-Uni颉一科技」
  • 阿里云宣布华北5地域十月开服,将部署国内首个全系Skylake+25G网络
  • 前嗅ForeSpider教程:链接抽取
  • 谷歌支付Purchases验证中的purchaseType
  • 002-读书笔记-JavaScript高级程序设计 在HTML中使用JavaScript
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • ES学习笔记(12)--Symbol
  • GitUp, 你不可错过的秀外慧中的git工具
  • Idea+maven+scala构建包并在spark on yarn 运行
  • Java 多线程编程之:notify 和 wait 用法
  • Java新版本的开发已正式进入轨道,版本号18.3
  • js数组之filter
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • Next.js之基础概念(二)
  • Python 反序列化安全问题(二)
  • React Native移动开发实战-3-实现页面间的数据传递
  • SpiderData 2019年2月25日 DApp数据排行榜
  • Vue 重置组件到初始状态
  • vue中实现单选
  • XForms - 更强大的Form
  • 从重复到重用
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 前端面试之CSS3新特性
  • 深度解析利用ES6进行Promise封装总结
  • 深入体验bash on windows,在windows上搭建原生的linux开发环境,酷!
  • 使用 @font-face
  • 我的zsh配置, 2019最新方案
  •  一套莫尔斯电报听写、翻译系统
  • 原生 js 实现移动端 Touch 滑动反弹
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • 长三角G60科创走廊智能驾驶产业联盟揭牌成立,近80家企业助力智能驾驶行业发展 ...
  • # 20155222 2016-2017-2 《Java程序设计》第5周学习总结
  • $(document).ready(function(){}), $().ready(function(){})和$(function(){})三者区别
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (七)Java对象在Hibernate持久化层的状态
  • (十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)
  • (转载)Google Chrome调试JS
  • (转载)利用webkit抓取动态网页和链接
  • .NET 4.0中使用内存映射文件实现进程通讯
  • .NET Framework 4.6.2改进了WPF和安全性
  • .net打印*三角形
  • /var/spool/postfix/maildrop 下有大量文件