• 05_工厂模式


    工厂模式

    1.简单工厂:通常另外使用一个类或对象来封装实例化操作。

    2.工厂模式:真正的工厂模式则是须要定义一个抽象的工厂方法并把实例化的工作推迟到子类中进行!(接口起着关键性的作用!

    )

    以下以一个简单的样例来说明工厂模式的用法:如果你须要开几个Pizza店。每一个Pizza店有几种不同类型的Pizza供客人选择。最初的代码可能是以下这种。

    版本号1:未使用不论什么设计模式: 每次增加新种类的pizza。都得改动pizzaStore的代码。虽然它的工作内容并没有改变(pizzaStore仅仅是负责订购pizza,并不负责pizza的创建)。这样显然不合情理。

    <script type="text/javascript" src="00_Interface.js"></script>
    <script type="text/javascript">
        /**
         * 定义Pizza接口。每一个披萨都具有“准备”,“烘烤”,“装箱”这几个方法
         * @type {Interface}
         */
        var Pizza new Interface("Pizza", ["prepare""bake""box"]);

        /**
         * 分别实现三种不同的Pizza类型
         * @constructor
         */
        function CheesePizza() {
        }
        CheesePizza.prototype = {
            constructor: CheesePizza,
            preparefunction () {
                //实现prepare方法
            }, bakefunction () {
                //实现bake方法
            }, boxfunction () {
                //实现box方法
            }
        }


        function CornPizza() {
        }
        CornPizza.prototype = {
            constructor: CornPizza,
            preparefunction () {
                //实现prepare方法
            }, bakefunction () {
                //实现bake方法
            }, boxfunction () {
                //实现box方法
            }
        }


        function PorkPizza() {
        }
        PorkPizza.prototype = {
            constructor: PorkPizza,
            preparefunction () {
                //实现prepare方法
            }, bakefunction () {
                //实现bake方法
            }, boxfunction () {
                //实现box方法
            }
        }

        /***
         * Pizza店的实现类
         * @type {{orderPizza: Function}}
         */
        var pizzaStore = {
            orderPizzafunction (type) {
                var pizza;
                if (type == "cheese") {
                    pizza new CheesePizza();
                } else if (type == "corn") {
                    pizza new CornPizza();
                } else if (type == "pork") {
                    pizza new PorkPizza();
                }

                Interface.ensureImplements(pizza, [Pizza]);
                pizza.prepare();  //准备
                pizza.bake();//烘烤
                pizza.box();//装箱

                return pizza;
            }
        }

        //var pizza = pizzaStore.orderPizza("cheese");
        var pizza pizzaStore.orderPizza("pork");
        alert(pizza.constructor);
    </script>

     

    版本号2:使用简单工厂:将创建pizza的代码提取到一个简单工厂中去,是这个工厂对象只不过负责pizza的创建这一职责,同一时候新增加品种也无需再改动pizzaStore类。

    1.增加创建pizza的工厂对象

    //创建pizza的简单工厂
    var PizzaFactory = {
        createPizzafunction (type) {
            var pizza;
            if (type == "cheese") {
                pizza new CheesePizza();
            } else if (type == "corn") {
                pizza new CornPizza();
            } else if (type == "pork") {
                pizza new PorkPizza();
            }
            Interface.ensureImplements(pizza, [Pizza]);

            return pizza;
        }
    }

    2.在pizzaStore中使用这个工厂对象来创建

    var pizzaStore = {
        orderPizzafunction (type) {
            var pizza PizzaFactory.createPizza(type);

            pizza.prepare();  //准备
            pizza.bake();//烘烤
            pizza.box();//装箱

            return pizza;
        }
    }

    3.其余部分保持不变

    版本号3:使用真正的工厂模式真正的工厂模式与简单工厂的差别在于,它不是另外使用一个对象或类来创建实例,而是使用一个子类。依照正式定义工厂是一个将其成员对象的实例化延迟到子类中进行的类。

    <script type="text/javascript" src="00_Interface.js"></script>
    <script type="text/javascript">
        /**
         * 定义Pizza接口,每一个披萨都具有“准备”,“烘烤”,“装箱”这几个方法
         * @type {Interface}
         */
        var Pizza new Interface("Pizza", ["prepare""bake""box"]);

        //如果你的pizza店有2个分店,位于三个不同的地区,分别生产当地口味的pizza
        //首先定义一个抽象基类。PizzaStore
        var PizzaStore = function () {
        };
        PizzaStore.prototype = {
            constructor: PizzaStore,
            orderPizzafunction (type) {
                var pizza this.createPizza(type);
                pizza.prepare();
                pizza.bake();
                pizza.box();

                return pizza;
            }, createPizzafunction (type) {
                throw new Error("抽象类中未实现该方法。在详细子类中实现!");
            }
        }


        //湖南分店:口味偏辣
        function HuNanPizzaStore() {
            PizzaStore.call(thisarguments);
        }
        ;
        //继承基类
        HuNanPizzaStore.prototype new PizzaStore();
        HuNanPizzaStore.prototype.constructor = HuNanPizzaStore;
        HuNanPizzaStore.prototype.createPizza function (type) {
            var pizza;
            if (type == "greenPepper") {
                pizza new GreenPepperPizza(); //详细Pizza类的实现省略...
            else if (type == "redPepper") {
                pizza new RedPepperPizza();//详细Pizza类的实现省略...
            }
            Interface.ensureImplements(pizza, [Pizza]);
            return pizza;
        }

        //上海分店,口味偏甜
        function ShangHaiPizzaStore() {
            PizzaStore.call(thisarguments);
        }
        ShangHaiPizzaStore.prototype new PizzaStore();
        ShangHaiPizzaStore.prototype = {
            constructor: ShangHaiPizzaStore,
            createPizzafunction (type) {
                var pizza;
                if (type == "tomato") {
                    pizza new TomatoPizza(); //详细Pizza类的实现省略...
                else if (type == "pineapple") {
                    pizza new PineapplePizza();//详细Pizza类的实现省略...
                }
                Interface.ensureImplements(pizza, [Pizza]);
                return pizza;
            }
        }


        //使用
        var pizzaStore;
        pizzaStore new HuNanPizzaStore();
        pizzaStore.orderPizza("greenPepper");   //从湖南分店订购青椒披萨

        pizzaStore new ShangHaiPizzaStore();
        pizzaStore.orderPizza("pineapple"); //从上海分店订购凤梨披萨 
    </script>

     

    使用真正的工厂模式后,想添加其它的分店非常easy。仅仅须要添加一个PizzaStore的子类,并实现其createPizza方法就可以,不会对其它类造成不论什么影响。也能够对各个子类进行改动,以添加不同食材的pizza。这是工厂模式最重要的特点。对pizza进行的一般性操作能够放在抽象父类PizzaStore中,而其它详细的实现则放在相应的子类中实现!

     

  • 相关阅读:
    多边形切割
    数据库冷备份步骤
    获取对象的矩形范围
    圆柱体切割
    mapgis文件格式
    注册asp_net 4_0 到iis的方法
    文件获取裁剪多边形
    heap做题记录
    手动编译Aseprite源码(1.2.13)
    为什么要使用委托?
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/6828859.html
Copyright © 2020-2023  润新知