JavaScript设计模式(二):工厂模式

1. 简单工厂

工厂模式主要用来创建同一类对象,解决相似问题。它将成员对象的实例化操作(new 操作)封装在一个外部函数中,我们需要什么对象,就要调用工厂方法来创建对应对象。其内部通常使用 if-elseswitch-case 条件语句来分别创建不同类型对象。

function Man(){}
Man.prototype = {...}

function Woman(){}
Woman.prototype = {...}

function PersonFactory(s){
	if(s == 'man'){
	    return new Man();
	}else if(s == 'woman'){
	    return new Woman();
	}else{
	    return null;
	}
}

PersonFactory('man');
// 异步对象工厂
function CreateXHR(){
    var xhr = null;
    if(window.XMLHttpRequest){
        xhr = new XMLHttpRequest();
    }else if(window.ActiveXObject){
        xhr = new ActiveXObject('Msxml2.XMLHTTP');
    }
    return xhr;
}

缺陷:违反了开闭原则

什么是开闭原则?

软件中的对象(类、模块、函数等)应该对于扩展开放,而对于修改是封闭的。

也就是说,当需要改变一个程序的功能或者给程序增加新功能时,可以增加代码但不允许改变程序的源代码。因为修改源代码常常是危险的,尤其是在代码十分复杂的情况下,我们永远不知道改动源码会出现什么副作用。

// 当我们想增加child类时 不得不改变PersonFactory函数
function PersonFactory(s, name){
	if(s == 'man'){
	    return new Man(name);
	}else if(s == 'woman'){
	    return new Woman(name);
	}else if(s == 'child'){
	    return new Child(name);
	}else{
	    return null;
	}
}

PersonFactory('man', 'Tim');

2. 工厂方法

工厂方法使一个类的实例化延迟到其子类。也就是遵从开闭原则,引进新类时不改变原有的东西,仅需要添加新的具体工厂类即可。
如以下代码,我们想添加其它 Person 类,只需要写在 PersonFactory 的原型中就可以,而不必改变PersonFactory

var PersonFactory = function(s, name){
    return new this[s](name);
}

PersonFactory.prototype = {
    man: function(name){
        this.name = name;
    },
    women: function(name){
        this.name = name;
    },
    child: function(name){
        this.name = name;
    }
}

new PersonFactory('child', 'Bob');

3. 总结

  1. 简单工厂适用于创建单一对象,而工厂方法则适合创建多类对象。
  2. 简单工厂将对象实例化的选择判断放在工厂内部,而工厂方法将简单工厂的内部逻辑判断移到了外部,本来修改工厂类,现在修改原型即可。
原文地址:https://www.cnblogs.com/qimeng/p/7639806.html