总结#
创建型设计模式是一类处理对象创建的设计模式,通过某种方式控制对象的创建来避免基本对象创建时可能导致设计上的问题或者增加设计的复杂度。
如果需要创建一类对象,可以使用简单工厂模式。
如果需要创建多类对象,可以使用工厂方法模式。
如果需要制定类的结构,可以使用抽象工厂模式。
如果需要精确的控制创造对象时的每一个细节,并且创造的对象结构更加复杂,是个复合对象,可以使用建造者模式。
如果需要使用静态变量,规划命名空间,可以使用单例模式。
简单工厂模式(Simple Factory)##
- 主要用来创建同一类对象(单一对象)
- 对于同一类对象在不同需求中的重复性使用,很多时候不需要重复创建。通过简单工厂来创建一些对象,可以让这些对象共用一些资源而又私有一些资源。
- 具体实现:
1.通过类实例化对象创建。
function A(){};
function B(){};
function C(){};
var ABC = function(value){
switch(value){
case'A':return new A();
case'B':return new B();
case'C':return new C();
}
}
var object = ABC('A');
2.通过(寄生方式)创建一个新对象然后包装增强其属性和功能来实现。
function createObject(name,type){
var o = new Object();
o.name = name;
o.type = type;
o.consoleName = function(){
console.log(this.name);
}
return o;
}
var object = createObject('moonburn','coll');
两种方式的差异性体现在,通过第一种方式创建的对象,因为继承与同一个父类,所以他们父类的方法是可以共用的;而通过第二种寄生方式创建的对象,每一个都是新的个体,所以他们的方法是不能共用的。
工厂方法模式(Factory Method)##
- 主要用来创建多个对象。
- 通过对产品类的抽象使其创建业务主要负责用于创建多类产品的实例。
工厂方法的本意是将实际创建对象工作推迟到了之类中,把核心类作为抽象类。因为JavaScript没有传统意义上的抽象类概念,所以我们只需将工厂方法看成一个实例化对象的工厂类(安全起见,我们采用安全模式类),而我们创建的对象的基类放在工厂方法类的原型即可。 - 具体实现:
var Factory = function(name,type){
//安全模式
if(this instanceof Factory){
var a = new this[name](type);
return a;
}else{
return new Factory(name,type);
}
}
Factory.prototype = {
moonburn:function(type){},
moon:function(type){},
burn:function(type){}
}
var moonburn = Factory('moonburn','coll');
抽象工厂模式(Abstract Factory)##
- 通过对类的工厂抽象使其业务用于对产品类簇的创建,而不负责创建某一类产品的实例。
- 一般把它作为父类,创建一些子类。抽象工厂模式是设计模式中最抽象的一种,也是创建模式中唯一一种抽象化创建模式。该模式创建出的结果不是一个真实的对象实例。而是一个类簇,它制定了类的结构,这也是区别于简单工厂创建单一对象,工厂模式创建多类对象。
- 抽象类具体实现:
var People = function (){};
People.prototype = {
getName:function (){return new Error('抽象方法不能调用')}
}
- 抽象工厂模式实现
var People = function (subType,superType){
//判断抽象工厂内是否有该抽象类
if(typeof People(superType) === 'function'){
function F(){};
F.prototype = new People[superType]();
subType.constructor = subType;
subType.prototype = new F();
}else{
throw new Error('未创建该抽象类');
}
}
//定义Man抽象类
People.Man = function(){
this.type = 'man';
}
People.Man.prototype = {
getName:function(){return new Error('抽象方法不能调用')}
}
var Students = function(name){
this.name = name;
}
//抽象工厂实现对Man抽象类的继承
People(Student,'Man');
Students.prototype.getName = function (){return this.name};
//实例化
var moonburn = new Students('moonburn');
console.log(moonburn.getName()); //moonburn
建造者模式(Builder)##
- 建造者模式更多的是关注对象建造的整个过程,甚至于说是建造的每一个细节。
- 建造者模式下创建的对象更多的是复合对象,是结构更为复杂的对象。
- 具体实现:
var People = function (type){
this.type = type||'保密';
}
People.prototype = {consoleType:function (){console.log(this.type)}}
var Name = function (name){
this.name = name;
}
var Work = function (work){
this.work = work;
}
var Person = function(name,work){
var _person = new People();
_person.name = new Name(name);
_person.work = new Work(work);
return _person;
}
var moonburn = new Person('moonburn','student');
console.log(moonburn.name.name); //moonburn
console.log(moonburn.work.work); //student
console.log(moonburn.type); //保密
原型模式(Prototype)##
- 用原型实例指向创建对象的类,使用于创建新的对象的类的共享原型对象的属性已经方法。
- 我们平时用的原型继承就是参照于原型模式。
- 原型模式有一个特点就是在任何时候都可以对基类或者子类进行方法的拓展,而且所有被实例化的对象或者类都能获取到这些方法,这样给予我们对功能拓展的自由性(正由于这种方式太过自由,所以不要随意去做,否则如果修改类的其他属性或者方法很可能会影响到其他人)。
单例模式(Singleton)##
- 单例模式又称为单体模式,是只允许实例化一次的对象类。有时我们也用一个对象来规划一个命名空间,更加方便的管理对象上的属性和方法。
- JavaScript中的单例模式除了定义命名空间,还有一个作用,就是通过单例模式来管理代码库的各个模块。比如早起的百度,雅虎,都是通过单例模式来控制自己每一个功能模块的。
- 单例模式可以模拟静态变量,具体如下:
var Conf = (function (){
var conf = { COUNT:100//静态变量约定为大写 }
return { get:function (value){ return conf[name]?conf[name]:'没有此静态变量' } }
})();