我为什么把他们两个放在一起讲?我觉得这两个设计模式有相似之处,有时候会一个设计模式不能满足你的需求而采用另一种设计模式。基于这点考虑,而且为了大家更好地理解,我放到了一起,加深大家的印象,活学活用。

[这里我为了能更好的体现下设计模式与JS本体语言的结合,我用了一点继承关系.
有的同学都不知道JS能继承,就算大家不懂继承也希望大家能看下去,弄懂它!]
复制代码

本文扩展

掘金有个文章继承还是蛮透彻的 JS原型链与继承别再被问倒了

工厂模式

  • 创建对象跟对不同需求进行不同的实例化

在我们Team协作开发过程当中,不同于我们写个人项目,对全局变量的限制很大,我们要尽量少的使用全局变量,对于一类对象在不同需求上的不同使用,甚至将一些有些类似的方法抽象化,可以用工厂模式来负责创建这些对象,调用者可以使用一部分资源也可以在基础上私人订制一套资源。

就拿昨天入群的小伙伴举个栗子:他设计一个网页播放器有四个按钮:

我们不讨论他的实现方式,我们按照工厂模式来简单创建一个吧!

function wangyiMusicAction(action){var o = new Object;o.vender = '网易云音乐';o.playingMusic = 'see you again'switch (action){case 'last':o.information = {currentMusic:'Ich will',status:'200|404',message:'上一曲'}breakcase 'next':o.information = {currentMusic:'一人我编程累',status:'200|404',message:'下一曲'}breakcase 'play':o.information = {currentMusic:'see you again',status:'200|500',message:'播放'}breakcase 'mute':o.information = {currentMusic:'see you again',status:'200|500',message:'静音'}break}return o;}
var music = wangyiMusicAction('next')
console.log('音乐提供商 : '+music.vender);
console.log('正在播放 : '+music.playingMusic);
console.log('执行动作 : ' +music.information.message);
console.log('接口状态 : ' +music.information.status);
console.log('执行动作后歌曲 : ' +music.information.currentMusic);----------执行结果--------音乐提供商 : 网易云音乐
正在播放 : see you again
执行动作 : 下一曲
接口状态 : 200|404
执行动作后歌曲 : 一人我编程累
复制代码

这其实使我们经常使用的,不过这是面向过程的,不太符合我们的设计模式。我们用上篇学到的模式:对象

我们可以修改一下:

var WangyiMusicAction = function(action){this.vender = '网易云音乐';this.playingMusic = 'see you again'}WangyiMusicAction.prototype = {last : function() {this.information = {currentMusic:'Ich will',status:'200|404',message:'上一曲'}},next : function() {this.information = {currentMusic:'一人我编程累',status:'200|404',message:'下一曲'}},play : function() {this.information = {currentMusic:'see you again',status:'200|500',message:'播放'}},mute : function() {this.information = {currentMusic:'see you again',status:'200|500',message:'静音'}}}var music = new WangyiMusicAction()
music.next(); //执行下一曲动作
console.log('音乐提供商 : '+music.vender);
console.log('正在播放 : '+music.playingMusic);
console.log('执行动作 : ' +music.information.message);
console.log('接口状态 : ' +music.information.status);
console.log('执行动作后歌曲 : ' +music.information.currentMusic);
音乐提供商 : 网易云音乐
正在播放 : see you again
执行动作 : 下一曲
接口状态 : 200|400----------执行结果--------执行动作后歌曲 : 一人我编程累复制代码

这样就算是面向对象的了,虽然达到目的,但是上面所说的,但是这算是Music的网易云音乐实现版本、总不能再来一个QQMusicXiaMiMusic吧?我们建立一个Factory工厂来管理所有的音乐:


var WangyiMusicAction = function(action){this.vender = '网易云音乐';this.playingMusic = 'see you again'}//为网易音乐提供共有方法
WangyiMusicAction.prototype = {last : function() {this.information = {currentMusic:'Ich will',status:'200|404',message:'上一曲'}},next : function() {this.information = {currentMusic:'一人我编程累',status:'200|404',message:'下一曲'}},play : function() {this.information = {currentMusic:'see you again',status:'200|500',message:'播放'}},mute : function() {this.information = {currentMusic:'see you again',status:'200|500',message:'静音'}}}var QQMusicAction = function(action){this.vender = 'QQ音乐';this.playingMusic = '其实我不low'}//为QQ音乐提供共有方法
QQMusicAction.prototype = {last : function() {this.information = {currentMusic:'Ich will',status:'200|404',message:'上一曲'}},next : function() {this.information = {currentMusic:'网易才low',status:'200|404',message:'下一曲'}},play : function() {this.information = {currentMusic:'see you again',status:'200|500',message:'播放'}},mute : function() {this.information = {currentMusic:'see you again',status:'200|500',message:'静音'}}}
//音乐工厂
var MusicFactory = function(type){switch (type){case 'qq':return new QQMusicAction();case 'wangyi':return new WangyiMusicAction()}
}var music = new MusicFactory('qq')
music.next(); //执行下一曲动作
console.log('音乐提供商 : '+music.vender);
console.log('正在播放 : '+music.playingMusic);
console.log('执行动作 : ' +music.information.message);
console.log('接口状态 : ' +music.information.status);
console.log('执行动作后歌曲 : ' +music.information.currentMusic);----------执行结果--------音乐提供商 : QQ音乐
正在播放 : 其实我不low
执行动作 : 下一曲
接口状态 : 200|404
执行动作后歌曲 : 网易才low复制代码

这样调用者需要用音乐接口,只需要记住MusicFactory就可以了,MusicFactory就像一个大工厂,对于music可以返回他要的一切。

好,我们回过头来看一下:

第一种方法:是创建一个新的对象 o 对他来增强 属性 的功能来实现的. 第二种方法:是实例化对象来创建的。 第二种方法:如果他们继承同一个父类 BaseMusic 那么他们父类的原型方法是可以和它们公用的! 第一种方法:我们内部 new 了一个新的个体,就不能与父类共用了.

具体哪种还是看你需求的,不过我更倾向第二种,因为他扩展性高,需求多的时候我们甚至可以将通用的抽离出来放到父类BaseMusic中。

在下面的继承中我运用了类式继承

ps:(大家可以看看构造函数继承和组合继承链接在最下面)
复制代码

//基类(父类)music方法
var BaseMusic = function(){this.playingMusic = 'see you again'
}
//实现通用方法
BaseMusic.prototype = {last : function() {this.information = {status:'200|404',message:'上一曲'}},next : function() {this.information = {currentMusic:'一人我编程累',status:'200|404',message:'下一曲'}},play : function() {this.information = {currentMusic:'see you again',status:'200|500',message:'播放'}},mute : function() {this.information = {currentMusic:'see you again',status:'200|500',message:'静音'}}
}
//网易云的不同于父类的构造方法
var WangyiMusicAction = function(action){this.vender = '网易云音乐';}
//这里通过prototype实现类继承
WangyiMusicAction.prototype = new BaseMusic();//这些动作我都放在基类了,达到代码复用的目的//QQ
var QQMusicAction = function(action){this.vender = 'QQ音乐';this.playingMusic = '其实我不low'}
QQMusicAction.prototype = new BaseMusic() //这些动作我都放在基类了,达到代码复用的目的//音乐工厂
var MusicFactory = function(type){switch (type){case 'qq':return new QQMusicAction();case 'wangyi':return new WangyiMusicAction()}
}var music = new MusicFactory('wangyi')
music.next(); //执行下一曲动作
console.log('音乐提供商 : '+music.vender);
console.log('正在播放 : '+music.playingMusic);
console.log('执行动作 : ' +music.information.message);
console.log('接口状态 : ' +music.information.status);
console.log('执行动作后歌曲 : ' +music.information.currentMusic);----------执行结果--------音乐提供商 : 网易云音乐
正在播放 : see you again
执行动作 : 下一曲
接口状态 : 200|404
执行动作后歌曲 : 一人我编程累
复制代码

这样看起来是不是更好、更简洁呢?

创建者模式

  • 工厂模式职责:我不管你想干啥,我只返回给你一个你想要的对象
  • 创建者模式职责:主要针对复杂业务的解耦,算是工厂的一种拆解、拼接。我可以将你的需求分解多个对象创建,更关心的是创建对象的过程。

不复杂不能突显出他的魅力,举个稍微复杂栗子:

我们公司是卖车的,用户下单要买车,这个车呢:

品牌:迈巴赫、林肯、宾利、特斯拉[如果不选品牌,默认特斯拉]
颜色:赤橙黄绿青蓝紫...[如果不选颜色,默认黄色]
动力:燃油、电力、混合动力[如果不选动力,默认电力]
购买人的一些备注信息[购买人可能会修改备注需要提供方法]
针对购买人选择的车型返回对车型的简单描述[描述可以修改]复制代码

最终根据用户选择来生成一个订单: 想下这用工厂模式是不是要写很多的if else来返回这么一个Car的对象呢?

我们先将 购买人的动作 反馈 分解为三个对象再在最后进行拼接 :

//创建一个汽车
var Car  = function(param){this.color = param && param.color || 'yellow';this.brand = param && param.brand || 'Tesla';this.power = param && param.power || 'electric';
}
//提供原型方法
Car.prototype = {getColor : function () {return this.color;},getBrand : function () {return this.brand;},getPower : function () {return this.power;}
}//创建一个反馈
var FeedBack = function(brand){var that = this;(function(brand,that){switch (brand){case 'Tesla':// that.brand = brand;that.information = '特斯拉是好车'breakcase 'Rolls' :that.information = '劳斯来时是好车'}})(brand,that)
}FeedBack.prototype.changeBrand = function (information) {this.information = information;
}//创建一个顾客
var Client = function(name,message){this.name = name;this.message = message || '无留言';
}
//顾客修改备注
Client.prototype.changeMessage = function(message){this.message = message;
}
//然后重点在这里!我们在这里将我们分解的拼接起来。
var Order = function(name){var object = new Car();object.client  = new Client(name);object.feedBack = new FeedBack(object.brand);return object;
}var orderCar = new Order('Vendar-MH');
console.log('The' + orderCar.client.name + '先生、下单一辆' + orderCar.color + '的' + orderCar.brand +' 留言内容 : ' +orderCar.client.message );
orderCar.client.changeMessage('请马上电话联系我')
console.log('The' + orderCar.client.name + '先生、下单一辆' + orderCar.color + '的' + orderCar.brand +' 留言内容 : ' +orderCar.client.message );----------执行结果--------TheVendar-MH先生、下单一辆yellow的Tesla 留言内容 : 无留言
TheVendar-MH先生、下单一辆yellow的Tesla 留言内容 : 请马上电话联系我复制代码

好了,就算是关于这个订单的更加复杂的需求,或者修改需求,不管我们多少各功能在用,我们只要微微一笑,修改下prototype等实现就好了0.0

如果您觉得还算不错可以关注我持续看我的文章,大概方向:前后端语言设计模式如何设计好一款框架源码导读技术实践

  • 青年才俊可以入群交流:147255248

JavaScript 设计模式 : 巧用'工厂模式'和'创建者'模式相关推荐

  1. javaScript设计模式之常用工厂模式

    工厂函数 定义 由一个工厂对象决定创建某一种产品对象类的实例,主要用来创建同一类对象. 使用场景 比如说你是到一个买宠物的店,里面有很多不同的宠物,你只需要说出宠物的名字给店员就行了. // 狗的类 ...

  2. GOLANG工厂模式、简单工厂模式、抽象工厂模式、创建者模式

    设计模式可以大大提高代码复用性,使得程序的修改更加灵活.另外将各个功能模块抽象解耦出来,在某个模块需要更改时不至于会对整体代码进行修改,解耦的好的话只简单修改几个地方即可以切换某个模块在实现上的切换, ...

  3. 【java设计模式】之 工厂(Factory)模式

    1.工厂模式的定义 工厂模式使用的频率很高.我们在开发中总能见到它们的身影.其定义为:Define an interface for creating an object, but let subcl ...

  4. JavaScript设计模式:观察者模式与发布订阅者模式实现

    观察者模式 当对象之间存在一对多的依赖关系时,其中一个对象的状态发生改变,所有依赖它的对象都会收到通知,这就是观察者模式. 在观察者模式中,只有两种主体:目标对象 (Subject) 和 观察者 (O ...

  5. 设计模式系列-创建者模式

    为什么80%的码农都做不了架构师?>>>    一.上篇回顾 上篇我们主要讲述了抽象工厂模式和工厂模式.并且分析了该模式的应用场景和一些优缺点,并且给出了一些实现的思路和方案,我们现 ...

  6. 【设计模式】五种创建者模式

    文章目录 创建者模式 单例设计模式 单例模式的结构 单例模式的实现 存在的问题 JDK源码解析-Runtime类 工厂模式 概述 简单工厂模式 结构 实现 优缺点 扩展 工厂方法模式 概念 结构 实现 ...

  7. 设计模式-创建者模式

    这里写目录标题 1.创建者模式 1.单例模式 2.说一说单例模式 2.工厂模式 **1.实现:不用设计模式** **2.简单工厂模式.(不是一种设计模式)** **3 工厂方法模式** **4.抽象工 ...

  8. 深入 JavaScript 设计模式,从此有了优化代码的理论依据

    点击蓝字 关注「前端小苑」 精品技术文章,热门资讯第一时间送达 一.设计模式综述 我想很多和我一样的朋友小时候都看过<天龙八部>,里面的女主角王语嫣是个武学博才,但自己却毫无实战.比如段誉 ...

  9. javascript 设计模式_用英雄联盟的方式讲解JavaScript设计模式(二)

    前言 大家好,这是第三篇作者对于设计模式的分享了,前两篇可以参考: 手写一下JavaScript的几种设计模式 (工厂模式,单例模式,适配器模式,装饰者模式,建造者模式) 用英雄联盟的方式讲解Java ...

最新文章

  1. java对cookie的操作
  2. 50k大牛告诉你Python怎么学,10个特性带你快速了解python
  3. H3C 交换机S5130S软件版本升级
  4. c++语言程序设计案...,C++程序设计案.ppt
  5. Spring boot定制错误数据携带出去
  6. 类中赋值运算符重载函数
  7. 全数字实时仿真平台SkyEye目标码覆盖率关键技术
  8. P1948 [USACO08JAN]Telephone Lines S(二分+spfa)
  9. 把zabbix图形整合至运维平台
  10. #centos7 创建内网yum源 OpenStack源部署
  11. 分类战车SVM全系列
  12. git输入 ssh-keygen -t rsa 后只显示Generating public/private rsa key pair. 然后就直接跳出了
  13. 2022考研资料每日更新(2021.07.28)
  14. Java数组的复制、扩容、删除
  15. 明星开餐饮店,逃不过凉凉的魔咒?
  16. 《MySQL必知必会》SQL文件
  17. 遇到程序员不修改bug时怎么办?我教你
  18. [乐意黎原创]访问Centos下Apache主机页面抛You don't have permission to access / on this server.
  19. 打印机 正在删除正在打印怎么也删除不了
  20. EAST托卡马克上光纤电流传感器的研制与实验应用笔记1

热门文章

  1. 1660s功耗多少w_1660显卡要多大电源?GTX1660用多大电源合适
  2. python修改数据库_python mysql修改数据库数据库
  3. oracle监听 客户 实例,oracle 数据库实例 监听
  4. mysql5.7.25源码安装_源码编译安装 mysql5.7.25
  5. android 动画多次使用,IOS使用animation引用同一个动画多次没反应,安卓可以
  6. qt 中的 quit() close()与 exit()
  7. 自动完形填空系统构建
  8. 整体管理6个过程及相关重点
  9. PMP知识点(九、风险管理)
  10. Nginx映射本地json文件,配置解决浏览器跨域问题,提供前端get请求模拟数据