JavaScript設(shè)計(jì)模式第一彈-創(chuàng)建型設(shè)計(jì)模式

前言

接下來將會為大家介紹設(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ì)模式折剃,寫得很不錯像屋。

成功不在一朝一夕,我們都需要努力

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末因苹,一起剝皮案震驚了整個(gè)濱河市篇恒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌款筑,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奈梳,死亡現(xiàn)場離奇詭異攘须,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)于宙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來至会,“玉大人,你說我怎么就攤上這事奉件±ブ” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵煤痕,是天一觀的道長征候。 經(jīng)常有香客問我,道長兆解,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任锅睛,我火速辦了婚禮现拒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘印蔬。我一直安慰自己脱衙,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布退唠。 她就那樣靜靜地躺著荤胁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上盆驹,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天召娜,我揣著相機(jī)與錄音运褪,去河邊找鬼。 笑死檀咙,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的弧可。 我是一名探鬼主播劣欢,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼校套!你這毒婦竟也來了牧抵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤妹孙,失蹤者是張志新(化名)和其女友劉穎获枝,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體省店,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年有鹿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了葱跋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡稍味,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出模庐,到底是詐尸還是另有隱情油宜,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布疼燥,位于F島的核電站,受9級特大地震影響醉者,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜撬即,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一剥槐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧才沧,春花似錦、人聲如沸温圆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽膝蜈。三九已至,卻和暖如春饱搏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背备绽。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留肺素,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓猴伶,卻偏偏與公主長得像,于是被迫代替她去往敵國和親他挎。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 設(shè)計(jì)模式概述 在學(xué)習(xí)面向?qū)ο笃叽笤O(shè)計(jì)原則時(shí)需要注意以下幾點(diǎn):a) 高內(nèi)聚雇盖、低耦合和單一職能的“沖突”實(shí)際上栖忠,這兩者...
    彥幀閱讀 3,736評論 0 14
  • 參考資料:菜鳥教程之設(shè)計(jì)模式 設(shè)計(jì)模式概述 設(shè)計(jì)模式(Design pattern)代表了最佳的實(shí)踐贸街,通常被有經(jīng)驗(yàn)...
    Steven1997閱讀 1,169評論 1 12
  • 設(shè)計(jì)模式匯總 一薛匪、基礎(chǔ)知識 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 3,922評論 1 15
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,092評論 1 32
  • 1.神秘的城堡 小龍古沥、樂樂娇跟、涵涵三個(gè)人都用手捂著眼睛,不敢把手從眼睛上拿下來苞俘,過了好半天才從手指縫中偷偷望去。 三...
    蔡海山閱讀 1,262評論 0 51