JS设计模式——7.工厂模式(概念)

工厂模式

本章讨论两种工厂模式:

简单工厂模式

使用一个类(通常是一个单体)来生成实例。

使用场景:假设你想开几个自行车商店(创建自行车实例,组装它,清洗它,出售它),每个店都有几种型号的自行车出售。

/*=====================实现车==========================*/
var Bicycle = new Interface('Bicycle', ['assemble', 'wash', 'ride', 'repair']);//Interface见2.初识接口那一章的用鸭式辨型模仿接口
var Speedster = function(){ //实现Bicycle接口

};
Speedster.prototype = {
    assemble: function(){

    },
    wash: function(){

    },
    ride: function(){

    },
    repair: function(){

    }
};
/*=====================实现商店========================*/
var BicycleFactory={ //单体形式的工厂
    createBicycle: function(model){
        var bicycle;
        switch (model){
            case 'The Speedster':
                bicycle = new Speedster();
                break;
            case 'The Lowrider':
                bicycle = new Lowrider();
                break;
            case 'The Comfort Cruiser':
            default:
                bicycle = new ComfortCruiser();
        }
        Interface.ensureImplements(bicycle, Bicycle); //Interface见2.初识接口那一章的用鸭式辨型模仿接口
        return bicycle;
    }
}
var BicycleShop = function(){};
BicycleShop.prototype ={
    sellBicycle: function(model){
        var bicycle = BicycleFactory.createBicycle(model); //调用工厂
        bicycle.assemble();
        bicycle.wash();
        return bicycle;
    }
};
/*=====================开始卖车========================*/
var shop1 = new BicycleShop();
var soldBicycle = shop1.sellBicycle('The Speedster');

其实,我们完全可以将BicycleFacotry的实现放在BicycleShop.prototype中,那么,为什么会用上工厂模式?

用工厂模式之后就更加方便管理,当我们需要添加一种新的车型时,只需修改工厂就可以了,省得我们去修改BicycleShop。

复杂工厂模式

使用子类来决定一个成员变量应该是哪个具体的类的的实例(按照正式的定义,工厂是一个将其成员对象的实例化推迟到子类中进行的类)

同样的场景,我们打算让各个自行车商店自行决定从哪个生产厂家进货。

我们把BicycleShop设计为抽象类,让子类根据各自的进货渠道实现其createBicycle方法。

/*=============================实现商店=================================*/
/*=============抽象类BicycleShop============*/
var BicycleShop = function() {};
BicycleShop.prototype = {
    sellBicycle: function(model){
        var bicycle = this.createBicycle(model);
        bicycle.assemble();
        bicycle.wash();
        return bicycle;
    },
    createBicycle: function(model){
        throw new Error('Unsupported operation on an abstract class.');
    }
};
/*===========商店从Acme公司进货=============*/
var AcmeBicycleShop = function() {};
extend(AcmeBicycleShop, BicycleShop); //extend见4.继承(概念)
AcmeBicycleShop.prototype.createBicycle = function(model){
    var bicycle;
    switch(model){
        case 'The Speedster':
            bicycle = new AcmeSpeedster();
            break;
        case 'The Lowrider':
            bicycle = new AcmeLowrider();
            break;
        case 'The Comfort Cruiser':
        default:
            bicycle = new AcmeComfortCruiser();
    }
    Interface.ensureImplements(bicycle, Bicycle);
    return bicycle;
}

这里只是实现了商店,至于自行车的实现如上,就不再重复。

工厂模式的适用场合

创建对象的最简单的方法是使用new关键字和具体类.如果不知道工厂模式的适用场合,那么创建和维护工厂所带来的额外复杂性是得不偿失的.

动态实现

如果要像前面自行车的例子一样,创建一些用不同方式实现同一接口的对象,那么可以使用一个工厂方法或简单工厂对象来简化实现的过程.

节省设置开销

如果对象需要进行复杂并且彼此相关的设置,那么使用工厂模式可以减少每种对象所需的代码量.

如果这种设置只需为特定类型的所有实例执行一次即可,这种作用尤其突出.

如果所用的类要求加载外部库的话,这尤其有用.工厂方法可以对这些库进行检查并动态加载那些未找到的库.

这种设置只存在于一个地方,因此以后改起来也方便很多.

用许多小型对象组成一个大对象

工厂方法可以用来创建封装了许多较小对象的对象.

例如自行车包含许多更小的系统:车轮,车架,车闸等.如果你不想让某个子系统与较大的那个对象之间形成强耦合,而是想在运行是从许多子系统中进行挑选的话,那么工厂模式是一个理想的选择.

posted @ 2014-03-26 10:07  JChen___  阅读(766)  评论(0编辑  收藏  举报