一,总体概要

1,笔者浅谈

说起设计模式其实并不是什么很新奇的概念,它也不是基于特定语言所形成的产物,它是基于软件设计原则以及相关的方法论和经过特定时期衍生出的若干解决方案。本文会以一个实例带入大家学习设计模式以及与之对应的软件设计原则来从不同角度阐述和分析代码,并且会给大家提供一些第三方的的实现方式来供参考,还会拿出开源代码案例来更深入的理解如何使用设计模式。

2,直入话题工厂模式是我们最常用的模式了,著名的前端框架Bootstrap以及服务端基于NodeJS的框架(ExpressJS) ,就使用了工厂模式,工厂模式在JS程序中可以说是随处可见。为什么工厂模式是如此常用?因为工厂模式就相当于创建实例对象的new,我们经常要根据类生成实例对象,如var button = new Button({}); 工厂模式也是用来创建实例对象的,所以以后当我们通过new创建对象时就可以思考一下是否可以用工厂模式来代替,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。

(1),简单工厂------简单工厂的特点就是参数化创建对象,简单工厂必须知道每一种产品以及何时提供给客户端。有人会说简单工厂还是换汤不换药,添加新类的时候还是需要修改这部分的代码!那么我们获得了什么好处呢?集中变化! 这很好的符合了DRY原则,DRY———Don't Repeat Yourself Principle,直译为“不要重复自己”原则^_^ 创建逻辑存放在单一的位置,即使它变化,我们也只需要修改一处就可以了。DRY 很简单,但却是确保我们代码容易维护和复用的关键。DRY原则同时还提醒我们:对系统职能进行良好的分割!职责清晰的界限一定程度上保证了代码的单一性。这句话对我们后续的分析极具指导意义,毕竟简单工厂只是低层次上的代码复用,以下是一个简单的例子

 var FullTime = function () {
this.hourly = "$12" ;
}; var PartTime = function () {
this.hourly = "$11" ;
}; var Temporary = function () {
this.hourly = "$10" ;
}; var Contractor = function () {
this.hourly = "$15" ;
};
function Factory() {
this.createEmployee = function (type) {
var employee ;
if (type === "fulltime") {
employee = new FullTime() ;
} else if (type === "parttime") {
employee = new PartTime() ;
} else if (type === "temporary") {
employee = new Temporary() ;
} else if (type === "contractor") {
employee = new Contractor() ;
}
employee.type = type ;
employee.say = function () {
console.log(this.type + ": rate " + this.hourly + "/hour") ;
}
return employee ;
} ;
}
var factory = new Factory() ;
factory.createEmployee("fulltime").say() ;

(2),抽象工厂------抽象工厂向客户端提供了一个接口,使得客户端在不指定具体产品类型的时候就可以创建产品中的产品对象。这就是抽象工厂的用意。抽象工厂面的问题是多个等级产品等级结构的系统设计。抽象工厂和工厂方法模式最大的区别就在于后者只是针对一个产品等级结构;而抽象工厂则是面对多个等级结构。同样出色的完成了把应用程序从特定的实现中解耦,工厂方法使用的方法是继承,而抽象工厂使用的对象组合。抽象工厂提供的是一个产品家族的抽象类型,这个类型的子类完成了产品的创建。以下是一个简单的例子

 function Employee(name) {
this.name = name;
this.say = function () {
console.log("I am employee " + name) ;
} ;
} function EmployeeFactory() {
this.create = function(name) {
return new Employee(name);
} ;
}
function Vendor(name) {
this.name = name;
this.say = function () {
console.log("I am vendor " + name);
} ;
}
function VendorFactory() {
this.create = function(name) {
return new Vendor(name);
} ;
} var employeeFactory = new EmployeeFactory() ;
employeeFactory.create("BigBear") ;

在实际的的使用中,抽闲产品和具体产品之间往往是多层次的产品结构,正如上图所示

题外话:简单工厂的确简单但是其背后的DRY原则在实践中让我们受益匪浅,去年我和我的搭档做站点的升级工作,写了很多重复的代码;代码重复,源代码组织混乱,没有做好规划和职责分析是原罪。今年新项目,DRY原则是我头顶的达摩克利斯之剑,不做重复的事情成为我进行项目计划组织管理的重要标准。

关于工厂模式的阶段总结:

识别变化隔离变化,简单工厂是一个显而易见的实现方式

简单工厂将创建知识集中在单一位置符合了DRY

客户端无须了解对象的创建过程,某种程度上支持了OCP

添加新的产品会造成创建代码的修改,这说明简单工厂模式对OCP支持不够

简单工厂类集中了所有的实例创建逻辑很容易违反高内聚的责任分配原则。

二,源码案例参考

1,ExpressJS

见下图

这是esxpress.js文件中创建app的代码,不难看出这就是一个典型的工厂模式,简单工厂。

这是application.js文件中的application的初始化代码。

这样就很容易看出来 TJ 大神(expressjs的作者)的用意了哈哈哈。好了我再来总结一下:

初始化工作如果是很长一段代码,说明要做的工作很多,将很多工作装入一个方法中,相当于将很多鸡蛋放在一个篮子里,是很危险的,这也是有背于面向对象的原则,面向对象的封装(Encapsulation)和分派(Delegation)告诉我们,尽量将长的代码分派"切割"成每段,将每段再"封装"起来(减少段和段之间偶合联系性),这样,就会将风险分散,以后如果需要修改,只要更改每段,不会再发生牵一动百的事情,最重要的一句话是将创建与初始化的工作进行分离

三,案例引入------麦当劳的例子

(1),创建麦香鸡类

 function McChicken(){
this.getFood = function(){
console.log("我来一份麦香鸡!") ;
} ;
} ;

(2),创建薯条类

 function Potato(){
this.getFood = function(){
console.log("我来一份薯条!") ;
} ;
} ;

(3),创建食物工厂类

function FoodFactory(){
return {
create : function(type){
var food ;
if(type === "McChicken"){
food = new McChicken() ;
}
else if(type === "Potato"){
food = new Potato() ;
}
return food ;
} ;
} ;
} ;

(4),创建客户端测试

function MClient(){
var food = FoodFactory().create("McChicken") ;
food.getFood() ;
} ;

现在如果我要在吃食物时前洗手如何办,需要做洗手的工作

修改代码

function createFood(){
// doWash(); 洗手工作
return FoodFactory.create("McChicken") ;
} ;

四,总结一下

(1),我们需要将创建实例的工作与使用实例的工作分开

(2),封装(Encapsulation)和分派(Delegation)告诉我们,尽量将长的代码分派"切割"成每段,将每段再"封装"起来(减少段和段之间偶合联系性),这样,就会将风险分散,以后如果需要修改,只要更改每段,不会再发生牵一动百的事情。

哈哈哈,本篇结束,未完待续,希望和大家多多交流够沟通,共同进步(*^__^*) 嘻嘻……

聊聊JS与设计模式之(工厂Factory)篇------(麦当劳的故事)的更多相关文章

  1. 设计模式--简单工厂(Factory)模式

    温故而知新,看了以前写的博文<Asp.net读取Excel文件 2>http://www.cnblogs.com/insus/archive/2011/05/05/2037808.html ...

  2. [设计模式3]--工厂(Factory)模式

    原文出处:http://blog.csdn.net/lwbeyond/article/details/7528309 工厂模式属于创建型模式,大致可以分为三类,简单工厂模式.工厂方法模式.抽象工厂模式 ...

  3. Head First 设计模式 —— 04. 工厂 (Factory) 模式

    思考题 如何将实例化具体类的代码从应用中抽离,或者封装起来,使它们不会干扰应用的其他部分? P111 将实例化具体类的代码放入一个对象中管理,通过不同入参决定实例化具体的类 简单工厂 不是23种GOF ...

  4. 设计模式——(Abstract Factory)抽象工厂

    设计模式——(Abstract Factory)抽象工厂 设计面向对象软件比较困难,而设计可复用的面向对象软件就更加困难.你必须设计相关类,并设计类的接口和继承之间的关系.设计必须可以解决当前问题,同 ...

  5. [JS设计模式]:工厂模式(3)

    简单工厂模式是由一个方法来决定到底要创建哪个类的实例, 而这些实例经常都拥有相同的接口. 这种模式主要用在所实例化的类型在编译期并不能确定, 而是在执行期决定的情况. 说的通俗点,就像公司茶水间的饮料 ...

  6. Java设计模式之工厂模式(Factory模式)介绍(转载)

    原文见:http://www.jb51.net/article/62068.htm 这篇文章主要介绍了Java设计模式之工厂模式(Factory模式)介绍,本文讲解了为何使用工厂模式.工厂方法.抽象工 ...

  7. Java设计模式之工厂模式(Factory)

    前言: 前面学习了建造者设计模式,接下来学习一下Retrofit中使用的另外一个设计模式,工厂设计模式!!!里面采用工厂模式使得数据转换得到完全解耦,工厂模式的好处用到了极致,如此好的设计模式我们怎能 ...

  8. 设计模式之工厂模式(Factory)

    设计模式的工厂模式一共有三种:简单工厂模式,工厂模式,抽象工厂模式 简单工厂模式原理:只有一个工厂类,通过传参的形式确定所创建的产品对象种类 代码如下: #include <stdio.h> ...

  9. 乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pattern)

    原文:乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pa ...

随机推荐

  1. MySQL的数据库无法插入中文是怎么回事?

    插入中文就报错: Incorrect string value: '\xE7\x8F\xBD\xE7\x8F\xBA' for column 'name' at row 1 用set names ut ...

  2. error C2259: 'CException' : cannot instantiate abstract class

    vc6.0编译通过,VS2008则报错 解决方法: 把CException改为CUserException

  3. 线程池的使用ExecutorService

    private ExecutorService executorService = Executors.newFixedThreadPool(5); // 引入线程池来管理多线程 private vo ...

  4. ghost系统到硬盘完后,重启进入winxp安装的画面变成了蓝屏

    ghost系统到硬盘完后,重启进入winxp安装的画面变成了蓝屏 原因分析: 一.系统集成的驱动和主板不兼容  这种原因引起的故障在部份品牌机上较常见,主要症状是系统能正常安装完成,但完成后重启进入系 ...

  5. 8.12 CSS知识点5

    背景原点 background-origin 设置元素背景图片的原始起始位置,必须保证背景是background-repeat为no-repeat此属性才会生效. 语法: background-ori ...

  6. 在本地机器上能访问tomcat,远程机器访问不了的解决方法

    问题描述:在测试服务器上搭建了一个tomcat,在测试服务器上能用ip打开tomcat.我用自己的机器能远程桌面能登录到测试服务器上,但在自己的机器上无法通过ip来访问测试服务器上的tomcat. 解 ...

  7. SQL 基础:Select语句,各种join,union用法

    一.基本的SELECT语句 1. “*”的注意事项:在SELECT语句中,用*来选取所有的列,这是一个应该抵制的习惯. 虽然节省了输入列名的时间,但是也意味着获得的数据比真正需要的数据多的多.相应的, ...

  8. cs0006 未能找到元数据文件 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files

    翻阅了一些资料后发现是需要重新注册IIS服务扩展,在“开始”-“运行”里输入如入命令,回车,搞定 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspne ...

  9. MySQL里的wait_timeout

    如果你没有修改过MySQL的配置,缺省情况下,wait_timeout的初始值是28800. wait_timeout过大有弊端,其体现就是MySQL里大量的SLEEP进程无法及时释放,拖累系统性能, ...

  10. 基于阿里云服务器的git服务器搭建

    使用阿里云Ubuntu 12.0.4 64位操作系统做git服务器. 首先git服务器有两种访问方式可以选择:http方式和ssh的方式,http方式更容易使用. 1.http方式的git服务器搭建以 ...