前言
接下來將會為大家介紹設(shè)計(jì)模式中的創(chuàng)建型設(shè)計(jì)模式奔垦,在此之前需要掌握一定的JavaScript對象繼承基礎(chǔ)尸疆。
簡單工廠模式
先說說
- 什么是簡單工廠模式:又叫靜態(tài)工廠方法,由一個(gè)工廠對象決定創(chuàng)建某一種產(chǎn)品對象類的實(shí)例
看著定義有點(diǎn)懵犯眠,沒關(guān)系症革。繼續(xù)往下走
工廠函數(shù)
- 說明:簡單來說,就是為了把多個(gè)相同類型的類集成到一個(gè)函數(shù)內(nèi)量蕊,我們把這個(gè)函數(shù)叫做工廠函數(shù)
- 用途:使得其他人不用關(guān)注創(chuàng)建對象是基于哪個(gè)基類艇挨,直接用該工廠函數(shù)即可
- 代碼:
//定義小貓類
var Cat = function(){
this.voice = '喵';
}
Cat.prototype.getVoice = function(){
console.log(this.voice);
}
//定義小狗類
var Dog = function(){
this.voice = '汪';
}
Dog.prototype.getVoice = function(){
console.log(this.voice);
}
//動物工廠
var AnimalFactory = function(name) {
switch(name){
case 'cat':
return new Cat();
case 'dog':
return new Dog();
}
}
//創(chuàng)建實(shí)例
var hellokity = AnimalFactory('cat');
hellokity.getVoice(); //'喵'
當(dāng)然,上面兩種方法十分相似吉殃,于是還可以有下面的定義方式:
var createAnimal = function(name,voice) {
var o = new Object();
o.name = name;
o.voice = voice;
o.getVoice = function() {
console.log(this.voice);
}
return o;
}
var hellokity = createAnimal('hellokity','喵');
hellokity.getVoice(); //'喵'
看似最后一種方法好像簡便不少楷怒,但是實(shí)際上這兩種定義方法是有區(qū)別的瓦灶。
- 第一種方式所定義的實(shí)例對象是擁有父類的方法,也就是可以訪問到原型鏈上面的屬性和方法的刃泡。
- 第二種方式定義則是因?yàn)樵趦?nèi)部新建了一個(gè)對象,那么父級對象什么的自然也就不存在了(當(dāng)然這里不是指object)烘贴。
最后回顧
最后再次加深對簡單工廠模式的印象吧
簡單工廠模式:又叫靜態(tài)工廠方法,由一個(gè)工廠對象決定創(chuàng)建某一種產(chǎn)品對象類的實(shí)例
工廠方法模式
先說說
- 什么是工廠方法模式:通過對產(chǎn)品類的抽象使其創(chuàng)建業(yè)務(wù)主要負(fù)責(zé)用于創(chuàng)建多類產(chǎn)品的實(shí)例
懵老翘?沒關(guān)系铺峭。繼續(xù)往下走
安全模式類
- 用途:可以屏蔽使用該類的所造成的錯誤
- 例子:
var Demo = function() {};
Demo.prototype.getName = function(){
console.log('get success!')
}
var d = Demo();
d.getName(); //報(bào)錯
//安全模式類
var Demo = function() {
if(!(this instanceof Demo)){
return new Demo
}
};
Demo.prototype.getName = function(){
console.log('get success!')
}
var d = Demo();
d.getName(); //'get success!'
工廠方法
實(shí)際上工廠方法和簡單工廠模式區(qū)別在于:簡單工廠模式如果需要增加類的話,那么它則需要改變兩處地方卫键,一處是工廠函數(shù)虱朵,一處是改變類。但是如果是工廠方法模式的話呢袱,則只需要往工廠方法中添加基類則可以翅敌。代碼實(shí)現(xiàn)如下:
//安全模式創(chuàng)建的工廠類
var superHeroFatory = function(type,skill){
if(this instanceof superHeroFatory){
var s = new this[type](skill);
return s
}else{
return new superHeroFatory(type,skill)
}
}
superHeroFatory.prototype = {
IronMan: function(skill){
this.name = 'Iron Man';
this.skill = skill;
this.getName = function(){
console.log(this.name);
}
this.getSkill = function(){
console.log(this.skill);
}
},
CaptainAmerica: function(skill){
this.name = 'Captain America';
this.skill = skill;
this.getName = function(){
console.log(this.name);
}
this.getSkill = function(){
console.log(this.skill);
}
}
}
var captainAmerica = superHeroFatory('CaptainAmerica','shield');
captainAmerica.getName(); //'Captain America'
captainAmerica.getSkill(); //'shield'
最后回顧
這個(gè)工廠方法模式解決了創(chuàng)建多類對象所帶來的麻煩蚯涮,這樣的工廠方法對象的方式也避免了使用者與對象類之間的耦合,用戶不關(guān)心創(chuàng)建該對象的具體類张峰,只需調(diào)用工廠方法即可棒旗。
抽象工廠模式
先說說
- 什么是抽象工廠模式:通過對類的工廠抽象使其業(yè)務(wù)用于對產(chǎn)品類簇的創(chuàng)建,而不負(fù)責(zé)創(chuàng)建其某一類產(chǎn)品的實(shí)例
看著定義有點(diǎn)懵饶深,沒關(guān)系逛拱。繼續(xù)往下走
抽象類
- 概念:抽象類是一種聲明但不能使用的類,使用就會報(bào)錯俱两。
- 用途:定義一個(gè)產(chǎn)品簇,并聲明一些必備的方法宪彩,如果子類沒有重寫就會報(bào)錯
- 例子:在java中可以簡單定義,但是在js中的話暫時(shí)還沒有這種抽象類的定義衍腥,于是我們可以用這種方式模仿抽象類:
var Car = function() {};
Car.prototype = {
getPrice(){
return new Error('抽象方法不可用')
},
getName(){
return new Error('抽象方法不可用')
}
}
于是乎纳猫,在對象實(shí)例化后調(diào)用這些函數(shù)就會報(bào)錯。因?yàn)槌橄箢愂菦]有具體實(shí)現(xiàn)的尚骄,它只用作繼承的方式
抽象工廠模式
- 說明:為了更好的創(chuàng)建抽象類侵续,于是將抽象類整合為一個(gè)抽象工廠
- 用途:用于創(chuàng)建抽象對象的一種方法
- 定義:
var VehicleFactory = function(subType,superType){
if(typeof VehicleFactory[superType] === 'function'){
// 緩存類
function F() { };
//繼承父類屬性和方法
F.prototype = new VehicleFactory[superType]();
//子類constructor指向子類
subType.constructor = subType;
//子類原型繼承“父類”
subType.prototype = new F();
}else{
throw new Error('未創(chuàng)建該抽象類')
}
}
//小汽車抽象類
VehicleFactory.Car = function(){
this.type = 'car';
}
VehicleFactory.Car.prototype = {
getPrice(){
return new Error('抽象方法不可用')
},
getName(){
return new Error('抽象方法不可用')
}
}
//大巴抽象類
VehicleFactory.Bus = function(){
this.type = 'bus';
}
VehicleFactory.Bus.prototype = {
getPrice(){
return new Error('抽象方法不可用')
},
getName(){
return new Error('抽象方法不可用')
}
}
抽象類的實(shí)現(xiàn)
啥也別說了状蜗,直接上碼
var BMW = function(price,name){
this.price = price;
this.name = name;
}
VehicleFactory(BMW,'Car');
BMW.prototype.getName = function(){
console.log(this.name);
}
var X2 = new BMW(200,'X2');
X2.getName(); //'X2'
X2.getPrice(); //報(bào)錯,因?yàn)橥浂x這個(gè)方法了
最后回顧
最后再次感受一下定義吧
抽象工廠模式:通過對類的工廠抽象使其業(yè)務(wù)用于對產(chǎn)品類簇的創(chuàng)建宏邮,而不負(fù)責(zé)創(chuàng)建其某一類產(chǎn)品的實(shí)例
建造者模式
先說說
- 什么是建造者模式:將一個(gè)復(fù)雜對象的構(gòu)建層與其表示層相互分離缸血,同樣的構(gòu)建過程可采用不同的表示
與工廠模式差別
- 工廠模式主要是為了創(chuàng)建對象實(shí)例或者類簇(抽象工廠),關(guān)心的是最終創(chuàng)建的是什么飒炎,而對創(chuàng)建的過程并不關(guān)心
- 建造者模式在創(chuàng)建對象時(shí)要更復(fù)雜笆豁,它更多的關(guān)心創(chuàng)建對象的過程甚至于每個(gè)細(xì)節(jié)〈秤或者說這種模式創(chuàng)建了一個(gè)復(fù)合對象
建造者模式
- 說明:關(guān)心創(chuàng)建對象的過程,對于創(chuàng)建的具體實(shí)現(xiàn)的細(xì)節(jié)也參與了干涉
- 用途:當(dāng)需要我們創(chuàng)建對象不僅需要得到對象實(shí)例耕驰,還需對對象細(xì)化時(shí)录豺,則可以使用建造者模式
- 代碼:
//創(chuàng)建類
var Human = function(props){
this.name = props && props.name || '保密';
}
Human.prototype.getName = function(){
console.log(this.name);
}
//名字類
var Name = function(name){
var that = this;
(function(name,that){
that.wholeName = name;
if(name.indexOf(' ') > -1){
that.FirstName = name.slice(0,name.indexOf(' '));
that.SecondName = name.slice(name.indexOf(' '));
}
})(name,that)
}
var Person = function(name){
var _name = new Name(name);
var _person = new Human({name:_name});
return _person
}
var Miles = new Person('Miles Jiang');
Milse.getName(); //{wholeName: "Miles Jiang", FirstName: "Miles", SecondName: " Jiang"}
最后回顧
這種模式下双饥,我們就可以關(guān)心到對象的創(chuàng)建過程。因此我們通常將創(chuàng)建對象模塊化趴生,這樣使得被創(chuàng)建的類的每個(gè)模塊都可以獲得靈活的運(yùn)用和高質(zhì)量的復(fù)用
單例模式
先說說
- 什么是單例模式:又被稱為單體模式,是只允許實(shí)例化一次的對象類昏翰。有時(shí)我們也用一個(gè)對象來規(guī)劃一個(gè)命名空間,井井有條地管理對象上的屬性與方法
命名空間
- 說明:用來約束每個(gè)人定義的變量
- 用途:防止共同開發(fā)時(shí)帶來的變量名沖突
- 例子:
var Miles = {
getDom: function(id){
return document.getElementById(id)
}
}
最后回顧
為了梳理代碼浸踩,使得代碼有序整潔
后話
本文章是通過學(xué)習(xí)張榮銘所著的《JavaScript設(shè)計(jì)模式》所總結(jié)统求。希望大家看完文章可以學(xué)到東西,同時(shí)也推薦大家去看看這本設(shè)計(jì)模式折剃,寫得很不錯像屋。
成功不在一朝一夕,我們都需要努力