總結(jié)#
創(chuàng)建型設(shè)計模式是一類處理對象創(chuàng)建的設(shè)計模式,通過某種方式控制對象的創(chuàng)建來避免基本對象創(chuàng)建時可能導(dǎo)致設(shè)計上的問題或者增加設(shè)計的復(fù)雜度。
如果需要創(chuàng)建一類對象,可以使用簡單工廠模式。
如果需要創(chuàng)建多類對象,可以使用工廠方法模式。
如果需要制定類的結(jié)構(gòu),可以使用抽象工廠模式。
如果需要精確的控制創(chuàng)造對象時的每一個細節(jié),并且創(chuàng)造的對象結(jié)構(gòu)更加復(fù)雜,是個復(fù)合對象,可以使用建造者模式。
如果需要使用靜態(tài)變量,規(guī)劃命名空間,可以使用單例模式。
簡單工廠模式(Simple Factory)##
- 主要用來創(chuàng)建同一類對象(單一對象)
- 對于同一類對象在不同需求中的重復(fù)性使用,很多時候不需要重復(fù)創(chuàng)建。通過簡單工廠來創(chuàng)建一些對象,可以讓這些對象共用一些資源而又私有一些資源。
- 具體實現(xiàn):
1.通過類實例化對象創(chuàng)建。
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.通過(寄生方式)創(chuàng)建一個新對象然后包裝增強其屬性和功能來實現(xiàn)。
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');
兩種方式的差異性體現(xiàn)在,通過第一種方式創(chuàng)建的對象,因為繼承與同一個父類,所以他們父類的方法是可以共用的;而通過第二種寄生方式創(chuàng)建的對象,每一個都是新的個體,所以他們的方法是不能共用的。
工廠方法模式(Factory Method)##
- 主要用來創(chuàng)建多個對象。
- 通過對產(chǎn)品類的抽象使其創(chuàng)建業(yè)務(wù)主要負責(zé)用于創(chuàng)建多類產(chǎn)品的實例。
工廠方法的本意是將實際創(chuàng)建對象工作推遲到了之類中,把核心類作為抽象類。因為JavaScript沒有傳統(tǒng)意義上的抽象類概念,所以我們只需將工廠方法看成一個實例化對象的工廠類(安全起見,我們采用安全模式類),而我們創(chuàng)建的對象的基類放在工廠方法類的原型即可。 - 具體實現(xiàn):
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)##
- 通過對類的工廠抽象使其業(yè)務(wù)用于對產(chǎn)品類簇的創(chuàng)建,而不負責(zé)創(chuàng)建某一類產(chǎn)品的實例。
- 一般把它作為父類,創(chuàng)建一些子類。抽象工廠模式是設(shè)計模式中最抽象的一種,也是創(chuàng)建模式中唯一一種抽象化創(chuàng)建模式。該模式創(chuàng)建出的結(jié)果不是一個真實的對象實例。而是一個類簇,它制定了類的結(jié)構(gòu),這也是區(qū)別于簡單工廠創(chuàng)建單一對象,工廠模式創(chuàng)建多類對象。
- 抽象類具體實現(xiàn):
var People = function (){};
People.prototype = {
getName:function (){return new Error('抽象方法不能調(diào)用')}
}
- 抽象工廠模式實現(xiàn)
var People = function (subType,superType){
//判斷抽象工廠內(nèi)是否有該抽象類
if(typeof People(superType) === 'function'){
function F(){};
F.prototype = new People[superType]();
subType.constructor = subType;
subType.prototype = new F();
}else{
throw new Error('未創(chuàng)建該抽象類');
}
}
//定義Man抽象類
People.Man = function(){
this.type = 'man';
}
People.Man.prototype = {
getName:function(){return new Error('抽象方法不能調(diào)用')}
}
var Students = function(name){
this.name = name;
}
//抽象工廠實現(xiàn)對Man抽象類的繼承
People(Student,'Man');
Students.prototype.getName = function (){return this.name};
//實例化
var moonburn = new Students('moonburn');
console.log(moonburn.getName()); //moonburn
建造者模式(Builder)##
- 建造者模式更多的是關(guān)注對象建造的整個過程,甚至于說是建造的每一個細節(jié)。
- 建造者模式下創(chuàng)建的對象更多的是復(fù)合對象,是結(jié)構(gòu)更為復(fù)雜的對象。
- 具體實現(xiàn):
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)##
- 用原型實例指向創(chuàng)建對象的類,使用于創(chuàng)建新的對象的類的共享原型對象的屬性已經(jīng)方法。
- 我們平時用的原型繼承就是參照于原型模式。
- 原型模式有一個特點就是在任何時候都可以對基類或者子類進行方法的拓展,而且所有被實例化的對象或者類都能獲取到這些方法,這樣給予我們對功能拓展的自由性(正由于這種方式太過自由,所以不要隨意去做,否則如果修改類的其他屬性或者方法很可能會影響到其他人)。
單例模式(Singleton)##
- 單例模式又稱為單體模式,是只允許實例化一次的對象類。有時我們也用一個對象來規(guī)劃一個命名空間,更加方便的管理對象上的屬性和方法。
- JavaScript中的單例模式除了定義命名空間,還有一個作用,就是通過單例模式來管理代碼庫的各個模塊。比如早起的百度,雅虎,都是通過單例模式來控制自己每一個功能模塊的。
- 單例模式可以模擬靜態(tài)變量,具體如下:
var Conf = (function (){
var conf = { COUNT:100//靜態(tài)變量約定為大寫 }
return { get:function (value){ return conf[name]?conf[name]:'沒有此靜態(tài)變量' } }
})();