zoukankan      html  css  js  c++  java
  • 工厂模式一之简单工厂

    工厂用来生产商品,然后卖给供应商,再由供应商转手给门店,再卖给顾客 。这样的一种生产到供应的过程,看看如何应用到我们的程序中。

    1.下面以衣服店为例子。

    第一步:创建衣服店类。

    clothes.js

    //创建一个衣服店模型。
    var ClothesShop = function (){}
    ClothesShop.prototype = {
        sellClothes: function (color){
            var clothesType = ['Red', 'Blue', 'Yello', 'Green', 'Gray'];
            var clothes;
            for(var i = 0, len = clothesType.length; i < len; i++) {
                if(color === clothesType[i]){
                    clothes = eval('new '+ color);   //new Red();
                }
            }
            //判断制造的是不是衣服。
            Interface.ensureImplements(clothes, Clothes);
            //出售
            return clothes;
        }
    }
    /*门店1
    var clothesShop1 = new ClothesShop();
    */

     创建一个门店模型。按照这个模型来实例化门店对象,可以创建多个门店clothesShop1,clothesShop2, clothesShop3..每个门店都有各种漂亮颜色红蓝黄绿灰的衣服。顾客通过type决定要买什么样的衣服。假设type为'Red',通过实例化衣服类new Red()来生产红色的衣服。Interface.ensureImplements在鸭式辨型中提过。这里用来检测衣服是否实现了衣服接口(检测商品到底合不合格)。

    Interface类

    var Interface = function (name, methods) {
        if(!methods) {
            throw new Error('Methods is undefined.');
        }
        if(!Array.isArray(methods)) {
            throw new Error('Methods is not an array.');
        }
        this.name = name;
        this.methods = [];
        //自定义方法作为类的依据
        for(var i = 0, len = methods.length; i < len; i++) {
            var method = methods[i];
            if(typeof method !== 'string') {
                throw new Error('Method name expected to be a string.');
                break;
            }
            this.methods.push(method);
        }
    }
    View Code

    ensureImplements方法

    Interface.ensureImplements = function () {
        var canFoundMethods = [];
        if(arguments.length < 2) {
            throw new Error('Arguments is expected at least 2.');
        }
        //取第二个参数("鸭子"的实例),称为参照对象
        for(var i = 1, len = arguments.length; i < len; i++) {
            var interface = arguments[i];
            //遍历参照对象的方法名称,对比检测对象。
            for(var j = 0, methodsLength = interface.methods.length; j < methodsLength; j++) {
                var method = interface.methods[j];
                if(!arguments[0][method] || typeof arguments[0][method] !== 'function') {
                    //检测对象没有的方法名称则记录
                    canFoundMethods.push(method);
                }
            }
        }
        //最后输出没有的方法
        if(canFoundMethods.length) {
            throw new Error ('Method ' + canFoundMethods.join(',') + ' was not found.');
        }
    }
    View Code

    第二步:定义衣服接口Clothes。

    //衣服接口。衣服是什么?自定义为衣服制造出来的,可以穿,可以洗,可以晒干的。
    var Clothes = new Interface('Clothes', ['make', 'ware', 'wash', 'dry']);

    定义一个衣服接口,并且自定义具有这四个特点的就是衣服。接口就是一个规则,用来检测对象具有某些方法的手段。

    //定义红色衣服的模型。
    var Red = function (){};
    Red.prototype = {
        color: function (){return 'Red';},
        make: function (){},
        ware: function (){},
        wash: function (){},
        dry: function (){}
    }

    定义衣服模型。按照这个模型可以生产很多红色的衣服new Red()。当然这里也可以是其它的衣服模型var Green = function (){},Green.prototype = {..};

    第三步:实例化ClothesShop类,调用sellClothes方法。

    //按照衣服门面店的模型,创建一个衣服店。当然也可以创建N个店,clothesShop1,clothesShop2...
    var clothesShop = new ClothesShop();
    //指定你要的选的颜色,买新的衣服
    var yourNewClothes = clothesShop.sellClothes('Red');

    当clothesShop调用sellClothes方法时,就像顾客下订单,然后由店来生产衣服,检测,最后出售。简单的工厂模式完成了,可以高兴一下。但是还是存在着一点问题,这里存在clothesShop既是门店,也是生产衣服的工厂。明显不符合我们的逻辑。我们肯定想的是把工厂和门店要分开。

    第四步:创建工厂对象

    //===============工厂制造衣服==================
    
    //把制造工作交给工厂,商店只负责出售衣服,分工明确。
    var clothesFactory = {
        createClothes: function (color) {
            var clothesType = ['Red', 'Blue', 'Yello', 'Green', 'Gray'];
            var clothes;
            for(var i = 0, len = clothesType.length; i < len; i++) {
                if(color === clothesType[i]){
                    clothes = eval('new '+ color);   //new Red();
                }
            }
            //判断制造的是不是衣服。
            Interface.ensureImplements(clothes, Clothes);
            //衣服出厂
            return clothes;
        }
    }

    用一个名为clothesFactory的工厂对象来实现createClothes方法。这样要需要的时候就可以在sellClothes调用createClothes方法。

    第五步:修改ClothesShop类

    //创建一个衣服门店模型。
    var ClothesShop = function (){}
    ClothesShop.prototype = {
        sellClothes: function (color){
            var clothes = clothesFactory.createClothes(color);
            //出售
            return clothes;
        }
    }

    修改ClothesShop门店模型,只负责出售衣服。到这里简单工厂完成了。

    完整代码:

    clothes.js

      1 /**
      2  * Created by Song_yc on 2015/2/2.
      3  */
      4 //创建一个衣服门面店模型。
      5 var ClothesShop = function (){}
      6 ClothesShop.prototype = {
      7     sellClothes: function (color){
      8         var clothes = clothesFactory.createClothes(color);
      9         //出售
     10         return clothes;
     11     }
     12 }
     13 /*门店1
     14 var clothesShop1 = new ClothesShop();
     15 门店2
     16 var clothesShop2 = new ClothesShop();
     17 门店3
     18 var clothesShop3 = new ClothesShop();*/
     19 
     20 var Interface = function (name, methods) {
     21     if(arguments.length !== 2) {
     22         throw new Error('Interface constructor called with' + arguments.length + 'arguments, but expected exactly 2.');
     23     }
     24     this.name = name;
     25     this.methods = [];
     26     if(!Array.isArray(methods)) {
     27         throw new Error('The second argument is expected array object instance of ' + typeof method+ '.');
     28     }
     29     for(var i = 0, len = methods.length; i < len; i++) {
     30         var method = methods[i];
     31         if(typeof method !== 'string') {
     32             throw new Error('Interface constructor expects method names to be as a string.');
     33             break;
     34         }
     35         this.methods.push(method);
     36     }
     37 }
     38 
     39 Interface.ensureImplements = function () {
     40     var canFoundMethods = [];
     41     //First to determine argument's length.
     42     if(arguments.length < 2) {
     43         throw new Error('Arguments is expected at least 2.');
     44     }
     45     //Second to determine instance class.
     46     for(var i = 1, len = arguments.length; i < len; i++) {
     47         var interface = arguments[i];
     48         if(interface.constructor !== Interface) {
     49             throw new Error(interface.name + 'object is not instanced of Interface Class.');
     50         }
     51         for(var j = 0, methodsLength = interface.methods.length; j < methodsLength; j++) {
     52             var method = interface.methods[j];
     53             if(!arguments[0][method] || typeof arguments[0][method] !== 'function') {
     54                 //throw new Error('Method ' + method + 'was not found.');
     55                 canFoundMethods.push(method);
     56             }
     57         }
     58     }
     59     //canFoundMethods.forEach(function (methodName) {
     60     //    throw new Error('Method ' + methodName + 'was not found.');
     61     //})
     62     if(canFoundMethods.length) {
     63         throw new Error ('Method ' + canFoundMethods.join(',') + ' was not found.');
     64     }
     65 }
     66 //定义衣服类。衣服是什么?被制造出来的,可以穿,可以洗,可以晒干的。
     67 var Clothes = new Interface('Clothes', ['make', 'ware', 'wash', 'dry']);
     68 //定义红色衣服的模型。
     69 var Red = function (){};
     70 Red.prototype = {
     71     color: function (){return 'red';},
     72     make: function (){},
     73     ware: function (){},
     74     wash: function (){},
     75     dry: function (){}
     76 }
     77 
     78 //===============工厂制造衣服==================
     79 
     80 //把制造工作交给工厂,商店只负责出售衣服,分工明确。
     81 var clothesFactory = {
     82     createClothes: function (color) {
     83         var clothesType = ['Red', 'Blue', 'Yello', 'Green', 'Gray'];
     84         var clothes;
     85         for(var i = 0, len = clothesType.length; i < len; i++) {
     86             if(color === clothesType[i]){
     87                 clothes = eval('new '+ color);   //new Red();
     88             }
     89         }
     90         //判断制造的是不是衣服。
     91         Interface.ensureImplements(clothes, Clothes);
     92         //衣服出厂
     93         return clothes;
     94     }
     95 }
     96 
     97 //按照衣服门面店的模型,创建一个衣服店。当然也可以创建N个店,clothes1,clothes2...
     98 var clothesShop = new ClothesShop();
     99 //选择喜欢的颜色
    100 var yourNewClothes = clothesShop.sellClothes('Red');
    View Code

    index.html

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    
    <script src="clothes.js"></script>
    </body>
    </html>
    View Code

    最后看看新的衣服。

    2.总结:

    回顾一下:首先创建一个门店模型,拥有生产各色衣服的方法。然后定义衣服接口,创建红色衣服模型,通过接口检测衣服是否合格。实例化门店,门店按照顾客的喜好进行生产衣服,检测,出售。最后把门店生产独立设计成简单工厂,生产和门店分离。

    • 简单工厂方法就是把创建类实例的方法放在外部对象,当实例化对象时在外部对象中进行。
  • 相关阅读:
    我的WCF之旅(1):创建一个简单的WCF程序
    与众不同 windows phone (15) Media(媒体)之后台播放音频
    与众不同 windows phone (14) Media(媒体)之音频播放器, 视频播放器, 与 Windows Phone 的音乐和视频中心集成
    与众不同 windows phone (10) Push Notification(推送通知)之推送 Tile 通知, 推送自定义信息
    与众不同 windows phone (17) Graphic and Animation(画图和动画)
    与众不同 windows phone (5) Chooser(选择器)
    与众不同 windows phone (26) Contacts and Calendar(联系人和日历)
    与众不同 windows phone (7) Local Database(本地数据库)
    与众不同 windows phone (19) Device(设备)之陀螺仪传感器, Motion API
    与众不同 windows phone (16) Media(媒体)之编辑图片, 保存图片到相册, 与图片的上下文菜单“应用程序...”和“共享...”关联, 与 Windows Phone 的图片中心集成
  • 原文地址:https://www.cnblogs.com/Songyc/p/4268194.html
Copyright © 2011-2022 走看看