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

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

时间: 2024-10-04 12:58:44

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

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

温故而知新,看了以前写的博文<Asp.net读取Excel文件 2>http://www.cnblogs.com/insus/archive/2011/05/05/2037808.html 觉得第一段代码示例,可以使用设计模式的简单工厂来实现. 也就是说,使用两个全新的类,替代两个Switch分支. Xls类: Xlsx类: 经这样分离之后,Switch代码,就可以写成下面这样子: 上面的高亮的方法是相同的,两个类的方法相同,我们可以抽取至父类作为父类的public的方法,但是Insus.NE

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

二十三种设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式. 1 <?php 2 /* 3 * php设计模式——抽象工厂模式(Abstract Factory) 4 */ 5 6 7 /* 8 * I

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

原文见:http://www.jb51.net/article/62068.htm 这篇文章主要介绍了Java设计模式之工厂模式(Factory模式)介绍,本文讲解了为何使用工厂模式.工厂方法.抽象工厂.Java工厂模式举例等内容,需要的朋友可以参考下 工厂模式定义:提供创建对象的接口. 为何使用工厂模式 工厂模式是我们最常用的模式了,著名的Jive论坛,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见. 为什么工厂模式是如此常用?因为工厂模式就相当于创建实例对象的new,我们经

JS 设计模式(工厂模式环境搭建)

<!--引入的核心JS文件--> <script type="text/javascript" src="CommonUtil.js"></script> <script type=text/javascript charset=utf-8> <!--JS设计模式(工厂模式)--> //搭建一个工厂环境 //卖车店 function CarShop(){}; CarShop.prototype={ cons

设计模式 - 抽象工厂模式(abstract factory pattern) 详解

抽象工厂模式(abstract factory pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy/article/details/27091671 参考工厂模式: http://blog.csdn.net/caroline_wendy/article/details/27081511 抽象工厂模式: 提供一个接口, 用于创建相关或依赖对象的家族, 而不需要明确指定具体类. 全部代码: http://download.csdn.net/de

设计模式 - 抽象工厂模式(abstract factory pattern) 具体解释

抽象工厂模式(abstract factory pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/27091671 參考工厂模式: http://blog.csdn.net/caroline_wendy/article/details/27081511 抽象工厂模式: 提供一个接口, 用于创建相关或依赖对象的家族, 而不须要明白指定详细类. 所有代码: http://download.csdn.net/

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

二十三种设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式. 1 package com.example.main; 2 3 import android.app.Activity; 4 import

设计模式一 工厂模式Factory

设计模式一 工厂模式Factory 在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的.但是在一些情况下, new操作符直接生成对象会带来一些问题.举例来说, 许多类型对象的创造需要一系列的步骤: 你可能需要计算或取得对象的初始设置; 选择生成哪个子对象实例; 或在生成你需要的对象之前必须先生成一些辅助功能的对象. 在这些情况,新对象的建立就是一个 "过程",不仅是一个操作,像一部大机器中的一个齿轮传动. 模式的问题:你如何能轻松方便

js设计模式:工厂模式、构造函数模式、原型模式、混合模式

一.js面向对象程序 var o1 = new Object(); o1.name = "宾宾"; o1.sex = "男"; o1.age = "27"; o1.msg = function(){ console.log("姓名:"+this.name+"  性别:"+this.sex+"  年龄:"+this.age); } var o2 = new Object(); o2.nam