MyException - 我的异常网
当前位置:我的异常网» 设计模式 » 聊聊JS与设计模式之(工场Factory)篇-(麦当劳的故

聊聊JS与设计模式之(工场Factory)篇-(麦当劳的故事)

www.MyException.Cn  网友分享于:2014-12-23  浏览:0次
聊聊JS与设计模式之(工厂Factory)篇------(麦当劳的故事)

一,总体概要

1,笔者浅谈

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

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

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

 1 var FullTime = function () {
 2     this.hourly = "$12" ;
 3 };
 4  
 5 var PartTime = function () {
 6     this.hourly = "$11" ;
 7 };
 8  
 9 var Temporary = function () {
10     this.hourly = "$10" ;
11 };
12  
13 var Contractor = function () {
14     this.hourly = "$15" ;
15 };
16 function Factory() {
17     this.createEmployee = function (type) {
18         var employee ;
19         if (type === "fulltime") {
20             employee = new FullTime() ;
21         } else if (type === "parttime") {
22             employee = new PartTime() ;
23         } else if (type === "temporary") {
24             employee = new Temporary() ;
25         } else if (type === "contractor") {
26             employee = new Contractor() ;
27         }
28         employee.type = type ;
29         employee.say = function () {
30             console.log(this.type + ": rate " + this.hourly + "/hour") ;
31         }
32         return employee ;
33     } ;
34 }
35 var factory = new Factory() ;
36 factory.createEmployee("fulltime").say() ;

 

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

 

 1 function Employee(name) {
 2     this.name = name;
 3     this.say = function () {
 4         console.log("I am employee " + name) ;
 5     } ;
 6 }
 7  
 8 function EmployeeFactory() {
 9     this.create = function(name) {
10         return new Employee(name);
11     } ;
12 }
13 function Vendor(name) {
14     this.name = name;
15     this.say = function () {
16         console.log("I am vendor " + name);
17     } ;
18 }
19 function VendorFactory() {
20     this.create = function(name) {
21         return new Vendor(name);
22     } ;
23 }
24 
25 var employeeFactory = new EmployeeFactory() ;
26 employeeFactory.create("BigBear") ;

 

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

 

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

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

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

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

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

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

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

 

二,源码案例参考

1,ExpressJS

见下图

 

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

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

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

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

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

(1),创建麦香鸡类

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

 

(2),创建薯条类

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

 

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

 

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

文章评论

如何成为一名黑客
如何成为一名黑客
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
程序员和编码员之间的区别
程序员和编码员之间的区别
每天工作4小时的程序员
每天工作4小时的程序员
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
中美印日四国程序员比较
中美印日四国程序员比较
总结2014中国互联网十大段子
总结2014中国互联网十大段子
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
编程语言是女人
编程语言是女人
老程序员的下场
老程序员的下场
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
旅行,写作,编程
旅行,写作,编程
程序员的鄙视链
程序员的鄙视链
鲜为人知的编程真相
鲜为人知的编程真相
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
 程序员的样子
程序员的样子
我是如何打败拖延症的
我是如何打败拖延症的
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
程序员必看的十大电影
程序员必看的十大电影
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
代码女神横空出世
代码女神横空出世
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
漫画:程序员的工作
漫画:程序员的工作
Java程序员必看电影
Java程序员必看电影
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
10个调试和排错的小建议
10个调试和排错的小建议
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
我的丈夫是个程序员
我的丈夫是个程序员
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
那些争议最大的编程观点
那些争议最大的编程观点
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
程序员应该关注的一些事儿
程序员应该关注的一些事儿
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有