代码改变世界

js设计模式--工厂模式

2013-09-16 19:10  明朝  阅读(274)  评论(0编辑  收藏  举报
工厂模式:

工厂模式的目的是为了创建对象,它经常是在类和类的方法中实现。简单的工厂模式是由一个方法来决定到底要创建哪类的实例,这些实例经常拥有相同的接口,这种模式在所实例化的类型在编译期并不确定,而是在执行期决定的情况。

 比如说,你有一家加工厂,生产各类牛奶:三氯氰胺奶粉,酸奶,变质奶,。。等等。当有客户跟你签约生产某种奶粉的时候,你便让工厂生产对应的奶。但如果要求生产牛肉,那肯定没有这个功能。。。

 具体上代码:

var Car = (function () {
    var Car = function (model, year, miles) {
        this.model = model;
        this.year = year;
        this.miles = miles;
    };
    return function (model, year, miles) {
        return new Car(model, year, miles);
    };
})();

var tom = new Car("Tom", 2009, 20000);
var dudu = new Car("Dudu", 2010, 5000);

初始化Car已经自执行,返回值是一个匿名函数,当用new创建实例时,返回的是内部Car的实例。所以当传进去不同数值是返回来的就是不同的实例。

让我们看下面一个工厂模式,在页面中插入不同的一些元素,这些元素类型是不固定的,它具备一个工行类和子类型,具体上代码:

//建立一个总的工厂类
var copyFactory = copyFactory || {};
copyFactory.dom = copyFactory.dom || {};

//处理文本函数
copyFactory.dom.text = function(){
    this.insert = function(where){
        var txt = document.createTextNode(this.url);
        where.appendChild(txt);
    };
};
//处理链接函数
copyFactory.dom.link = function(){
    this.insert = function(where){
        var link = document.createElement('a');
        link.href = this.url;
        link.appendChild(document.createTextNode(this.url));
        where.appendChild(link);
    };
};

创建了一个copyFactory.dom这个对象,在其上面添加静态的方法text,link。

创建工厂处理函数:

//定义工厂处理函数
copyFactory.dom.factory = function(type){
    var con = type,newFac;
    //如果copyFactory.dom这个类不存在con这个静态函数就报错,存在返回它的实例
    if(typeof copyFactory.dom[con] != 'function'){
        throw{
            name:"error",
            message:con+"不存在!"
        }
    }else{
        return new copyFactory.dom[con];
    }
}; 

使用方法如下:

//实例化一个处理链接的函数
var link = copyFactory.dom.factory("link");
    //可以使用方法了;
    link.url ="http://www.baidu.com";
    link.insert("body");

//实例化一个处理文本的函数
var text = copyFactory.dom.factory("text");
    //可以使用方法了;
    link.text ="创建文本"; 

搞定。

其实全局的Object()函数也表现出来工厂的行为,输入不同类型的而创建不同的对象。

比如你输入的是一个number = 1,那么后台就会以Number()构造函数创建对象:

//无论是否用new,都会调用Object();
var num = Object(1); 
var num2 =  new Object(1); 

num.constructor === Number; //true
num2.constructor === Number; //true

字符串,布尔值也成立:

var str = Object("1");
str.constructor === String; //true

var bl = Object(true);
bl.constructor === Boolean; //true

汤姆大叔语: 

      什么时候使用工厂模式

        以下几种情景下工厂模式特别有用:

      1. 对象的构建十分复杂
      2. 需要依赖具体环境创建不同实例
      3. 处理大量具有相同属性的小对象

      什么时候不该用工厂模式

        不滥用运用工厂模式,有时候仅仅只是给代码增加了不必要的复杂度,同时使得测试难以运行下去。

 

 虽然现在还没用到这样的模式写程序,但明白其中的原理,在套用已有的代码看很清晰。

参考《javascript模式》

汤姆大叔博客:http://www.cnblogs.com/TomXu/archive/2012/02/23/2353389.html

推荐阅读:

http://www.hulufei.com/post/201008141553

http://www.alloyteam.com/2012/10/commonly-javascript-design-patterns-simple-factory-pattern/