rwson

rwson

一个前端开发

javascript工厂模式

工厂模式:

创建一个对象常常需要复杂的过程,所以不适合在一个复杂的对象中。创建对象可能会导致大量的重复代码,也可能提供不了足够级别的抽象。工厂方法模式通过定义一个单独的创建对象的方法来解决这些问题,由子类实现这个方法来创建具体类型的对象。

简单工厂: 类本身实现了所有功能代码,通过实例化调用其方法来完成某些功能。

抽象工厂: 类本身定一些抽象方法,通过给子类继承的方式,来重写父类的抽象方法,该类不能被实例化,只能通过实例化它的子类来完成某些功能。

    /**
     * 注:
     * commonUtil.wrap(xxx.prototype,{})和xxx.prototype = {}功能相同
     * commonUtil.extend()是实现继承那边类式继承的代码功能
     * commonUtil.Interface和commonUtil.Interface.ensureImplement是实现接口那边鸭式辨型的代码功能
     *
     * */

这是简单工厂的一个示例:

/*
	功能描述:
	有三种类型的车(奔驰,宝马,奥迪),现在要买车,定义一个汽车4店类卖车
	逻辑流程:
	
*/

/**
  * 汽车商店构造器
  * @constructor
  */
function CarShop() {}

    commonUtil.wrap(CarShop.prototype, {
        "constructor": CarShop,
        "sellCar": function (type) {
            var car;
            switch (type) {
                case "Benz":
                    car = new Benz();
                    break;
                case "Bmw":
                    car = new Bmw();
                    break;
                case "Audi":
                    car = new Audi();
                    break;
                default:
                    "not to buy!"
            }
	//	通过传入的参数判断到底要实例哪个牌子的车对象(造车)
            return car;
        }
    });
    //  拓展原型对象

    /**
     * SuperClass
     * @constructor
     */
    function BaseCar(){}

    commonUtil.wrap(BaseCar.prototype,{
        "start": function () {
            console.log("我的"+ this.constructor.name +"启动了!");
        },
        "run": function () {
            console.log("我的"+ this.constructor.name +"开走了!");
        }
    });

    //  Class benz bmw audi
    //  子类应该先继承BaseCar类,再拓展或重写自己的方法
 	//	奔驰	
    function Benz() {
    }
    commonUtil.extend(Benz,BaseCar);

	//	宝马
    function Bmw() {
    }
    commonUtil.extend(Bmw,BaseCar);

	//	奥迪
    function Audi() {
    }
    commonUtil.extend(Audi,BaseCar);
    //  三个子类分别继承父类

    var shop = new CarShop();
 	//	实例化汽车商店
    var car = shop.sellCar("Bmw");
	//	从商店里买走辆宝马
    car.start();
    car.run();

    var car2 = shop.sellCar("Audi");
	//	从商店买走一辆奥迪
    car2.start();
    car2.run();

从上面的例子中可以看到,在CarShop这个类中,把所有工作都做了,但是在实际生活中,汽车4S店负责的就只有卖车等工作,不会和现在这个例子一样把生产车的例子也做了,而且在这个例子中,该汽车4S店提供了3种品牌的车(本初、宝马、奥迪),根据需求决定具体出哪一种车。所以,我们有必要把代码优化下,让汽车店只负责卖车。其他的工作和它没太大关系,于是,就有了抽象工厂的概念。

    var CarInterface = new commonUtil.Interface("CarInterface", ["start", "run"]);
    //  接口对象的实例

	/**
     * 卖车的商店(抽象类)
     * 抽象类 -> 用来被之类继承
     * @constructor
     * */
    function CarShop() {
    }

    commonUtil.wrap(CarShop.prototype, {
        "constructor": CarShop,
        "sellCar": function (type) {
            throw new Error("method sellCar is an abstruct method!");
        }//	卖车,给子类继承重写
    });
    //  拓展原型对象

    //  奔驰4S店类
    function BenzCarShop(){}
    commonUtil.extend(BenzCarShop,CarShop);
    commonUtil.wrap(BenzCarShop.prototype,{
        "constructor":BenzCarShop,
        "sellCar":function(type){
            var car;
            var types = ["Benz"];
            for(var t in types){
                if(types[t] === type){
                    //  如果商店里有想要的型号,就走这边
                    car = CarFactory.createCar(type);
                }else{
                    //  没有此类型的车
                    console.log("没有此型号!");
                }
            }
            return car;
            //  数组中存放所有奔驰类型的汽车
        }
    });

    //  宝马4S店类
    function BmwCarShop(){}
    commonUtil.extend(BmwCarShop,CarShop);
    commonUtil.wrap(BmwCarShop.prototype,{
        "constructor":BmwCarShop,
        "sellCar":function(type){
            var car;
            var types = ["Bmw"];
            for(var t in types){
                if(types[t] === type){
                    //  如果商店里有想要的型号,就走这边
                    car = CarFactory.createCar(type);
                }else{
                    //  没有此类型的车
                    console.log("没有此型号!");
                }
            }
            return car;
        }
    });

	//  奥迪4S店类
    function AudiCarShop(){}
    commonUtil.extend(AudiCarShop,CarShop);
    commonUtil.wrap(BmwCarShop.prototype,{
        "constructor":AudiCarShop,
        "sellCar":function(type){
            var car;
            var types = ["Audi"];
            for(var t in types){
                if(types[t] === type){
                    //  如果商店里有想要的型号,就走这边
                    car = CarFactory.createCar(type);
                }else{
                    //  没有此类型的车
                    console.log("没有此型号!");
                }
            }
            return car;
        }
    });
 	//	创建3个汽车4S店类,分别完成对汽车店类的继承

    var CarFactory = {
        "createCar":function(type){
            var car;
            //  动态创建车
            car = eval("new "+ type +"();");
            //  利用eval动态创建传入的车实例
            commonUtil.Interface.ensureImplement(car,CarInterface);
            //  检验接口是否实现
            return car;
        }
    };
    //  创建生产一台车的工厂(单体模式)

    /**
     * SuperClass
     * @constructor
     */
    function BaseCar(){}

    commonUtil.wrap(BaseCar.prototype,{
        "start": function () {
            console.log("老子的"+ this.constructor.name +"启动了!");
        },
        "run": function () {
            console.log("老子的"+ this.constructor.name +"开走了!");
        }
    });

    //  Class benz bmw audi
    //  子类应该先继承父类,再拓展或重写自己的方法

    function Benz() {
    }
    commonUtil.extend(Benz,BaseCar);

    function Bmw() {
    }
    commonUtil.extend(Bmw,BaseCar);
    commonUtil.wrap(Bmw.prototype,{
        "driveBmw":function(){
            console.log("开宝马!");
        },
        "run":function(){
            console.log("宝马开走了!");
        }
    });

    function Audi() {
    }
    commonUtil.extend(Audi,BaseCar);
    //  三个子类分别继承父类,并且拓展自己的方法

    var benz = new BenzCarShop(),
        bmw = new BmwCarShop(),
        benzCar = benz.sellCar("Benz"),
        bmwCar = bmw.sellCar("Bmw");
	//去具体的某个4S店卖车

    benzCar.run();
    bmwCar.run();	

在上面的抽象工厂中,汽车类之提供了一个抽象方法,给各子类继承和重写,而生产的工作交给了具体某种汽车厂商的造车厂,卖车的工作细分到具体某种品牌的4S店,这样,才是我们日常生活中的正常逻辑(买什么车,去什么4S店 -> 卖车 -> 生产车 -> 买车)。