javaScript设计模式-工厂

它的好处是消除对象间的耦合度,在派生子类时提供了更大的灵活性。但盲目的把普通的构造函数扔在一边,并不值得提倡。如果要采一不可能另外换用一个类,或都不需要在运行期间在一系列可互换的类中进行选择,就不应该使用。这样在后期代码重构时还有机会使用。

简单工厂

这种方式只能处理一个工厂只生产一个品牌的商品,如果生产不同品牌的商品时,此方式就行不通了。

javascript 复制代码
var BicycleFactory = {//把生产Bicycle的工作全部放在工厂类中
    createBicycle: function(model) {
        var bicycle;
        switch(model) {
            case 'The Speedster':
                bicycle = new Speedster();
                break;
            case 'The Lowrider':
                bicycle = new Lowrider();
                break;
            default:
                bicycle = new ComfortCruiser();
        }
//接口在工厂模式中起着很重要的作用,如果不对对象进行某种类型的检查以确保其实现了必要的方法,那  么工厂模式带来的好处就基本没有了,此接口是用第一章的内容创建的
        Interface.ensureImplements(bicycle, Bicycle);
        return bicycle;
    }
};
javascript 复制代码
var BicycleShop = function() {};
BicycleShop.prototype = {
    sellBicycle: function(model) {
        var bicycle = BicycleFactory.createBicycle(model);
        bicycle.assemble();
        bicycle.wash();
        return bicycle;
    }
};
javascript 复制代码
/* The Bicycle interface. */
var Bicycle = new Interface('Bicycle', ['assemble', 'wash', 'ride','repair']);
var Speedster = function() { // implements Bicycle
};
Speedster.prototype = {
    assemble: function() {
    },
    wash: function() {
    },
    ride: function() {
    },
    repair: function() {
    }
};
javascript 复制代码
var t = new BicycleShop();
var a = t.sellBicycle("The Speedster");
console.log(a);

如果需要提供几种不同品牌的自行车时,更恰当的做法是把这个创建方法实现在一个类中,并从此类派生出一些子类。

工厂模式

这个例子需要对上面的简单工厂进行一些修改。工厂是将其成员对象的实例化推迟到子类中进行的类。而简单工厂其成员对象是由工厂类创建的。

javascript 复制代码
/* 抽象的自行车商店(abstract). */
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.');
    }
};

/* AcmeBicycleShop class extends BicycleShop,
由具体的子类决定从哪家进货,卖什么牌子的自行车. */
var AcmeBicycleShop = function() {};
extend(AcmeBicycleShop, BicycleShop);//****
AcmeBicycleShop.prototype.createBicycle = function(model) {
    var bicycle;
    switch(model) {
        case 'The Lowrider':
            bicycle = new Speedster();
            break;
        default:
            bicycle = new AcmeComfortCruiser();
    }
    Interface.ensureImplements(bicycle, Bicycle);
    return bicycle;
};
/* GeneralProductsBicycleShop class.另一个商店 */

/* The Bicycle interface. */
var Bicycle = new Interface('Bicycle', ['assemble', 'wash', 'ride','repair']);
var Speedster = function() { // implements Bicycle
};
Speedster.prototype = {
    assemble: function() {
    },
    wash: function() {
    },
    ride: function() {
    },
    repair: function() {
    }
};
/* Usage. */
var alecsCruisers = new AcmeBicycleShop();
var yourNewBike = alecsCruisers.sellBicycle('The Lowrider');

通常要与一系列实现了同一接口、可以被同等对待的类打交道,或是初始化数据或是动态加载库时用工厂模式比较方便。同样也可以实现组合工厂。其实就是把小件组装在一个大工厂类中,做为对象返回。

javascript 复制代码
var FeedManager = {
  createFeedReader: function(conf) {
    var displayModule = new ListDisplay(conf.id + '-display', conf.parent);
    Interface.ensureImplements(displayModule, DisplayModule);
    var xhrHandler = XhrManager.createXhrHandler();
    Interface.ensureImplements(xhrHandler, AjaxHandler);
    //三个参数代表了三个小工厂。FeedReader是一个组合后的大工厂
    return new FeedReader(displayModule, xhrHandler, conf);
  }
};
相关推荐
牛奔1 小时前
Go 如何打印调试深层或嵌套的结构体
开发语言·后端·golang
geovindu1 小时前
go: Iterative Algorithms
开发语言·后端·算法·golang·迭代算法
学逆向的1 小时前
汇编——JCC指令
开发语言·汇编·网络安全
777VG2 小时前
PostgreSQL +martin将多张表输出成一个 MVT
前端·数据库·postgresql
mayaairi2 小时前
JS循环语句深度解析:嵌套for、while与do...while
开发语言·前端·javascript
To_OC2 小时前
啃完流式输出:从一个卡顿的 LLM 接口开始,我搞懂了数据流到底怎么 “流”
前端·javascript·llm
阳光是sunny3 小时前
LangGraph实战教程:defer延迟节点——让收尾工作自动排到最后
前端·人工智能·后端
kite01213 小时前
Go语言Map深度解析与最佳实践
开发语言·后端·golang
kyriewen3 小时前
我用了三周Claude Code Skills——总结出5条铁律,第3条最反直觉
前端·ai编程·claude
阳光是sunny3 小时前
LangGraph实战教程:控制流详解
前端·人工智能·后端