JS設(shè)計(jì)模式之工廠模式

工廠模式類似于現(xiàn)實(shí)生活中的工廠可以產(chǎn)生大量相似的商品,去做同樣的事情胀蛮,實(shí)現(xiàn)同樣的效果;這時(shí)候需要使用工廠模式。

簡(jiǎn)單的工廠模式可以理解為解決多個(gè)相似的問(wèn)題;這也是她的優(yōu)點(diǎn);比如如下代碼:

function CreatePerson(name,age,sex) {
    var obj = new Object();
    obj.name = name;
    obj.age = age;
    obj.sex = sex;
    obj.sayName = function(){
        return this.name;
    }
    return obj;
}
var p1 = new CreatePerson("longen",'28','男');
var p2 = new CreatePerson("tugenhua",'27','女');
console.log(p1.name); // longen
console.log(p1.age);  // 28
console.log(p1.sex);  // 男
console.log(p1.sayName()); // longen

console.log(p2.name);  // tugenhua
console.log(p2.age);   // 27
console.log(p2.sex);   // 女
console.log(p2.sayName()); // tugenhua

// 返回都是object 無(wú)法識(shí)別對(duì)象的類型 不知道他們是哪個(gè)對(duì)象的實(shí)列
console.log(typeof p1);  // object
console.log(typeof p2);  // object
console.log(p1 instanceof Object); // true

如上代碼:函數(shù)CreatePerson能接受三個(gè)參數(shù)name,age,sex等參數(shù)刁憋,可以無(wú)數(shù)次調(diào)用這個(gè)函數(shù)珍昨,每次返回都會(huì)包含三個(gè)屬性和一個(gè)方法的對(duì)象。

工廠模式是為了解決多個(gè)類似對(duì)象聲明的問(wèn)題;也就是為了解決實(shí)列化對(duì)象產(chǎn)生重復(fù)的問(wèn)題动羽。

優(yōu)點(diǎn):能解決多個(gè)相似的問(wèn)題包帚。

缺點(diǎn):不能知道對(duì)象識(shí)別的問(wèn)題(對(duì)象的類型不知道)。

復(fù)雜的工廠模式定義是:將其成員對(duì)象的實(shí)列化推遲到子類中运吓,子類可以重寫(xiě)父類接口方法以便創(chuàng)建的時(shí)候指定自己的對(duì)象類型渴邦。

父類只對(duì)創(chuàng)建過(guò)程中的一般性問(wèn)題進(jìn)行處理,這些處理會(huì)被子類繼承拘哨,子類之間是相互獨(dú)立的谋梭,具體的業(yè)務(wù)邏輯會(huì)放在子類中進(jìn)行編寫(xiě)。

父類就變成了一個(gè)抽象類倦青,但是父類可以執(zhí)行子類中相同類似的方法瓮床,具體的業(yè)務(wù)邏輯需要放在子類中去實(shí)現(xiàn)产镐;比如我現(xiàn)在開(kāi)幾個(gè)自行車店,那么每個(gè)店都有幾種型號(hào)的自行車出售癣亚。我們現(xiàn)在來(lái)使用工廠模式來(lái)編寫(xiě)這些代碼;

父類的構(gòu)造函數(shù)如下:

// 定義自行車的構(gòu)造函數(shù)
var BicycleShop = function(){};
BicycleShop.prototype = {
    constructor: BicycleShop,
    /*
    * 買自行車這個(gè)方法
    * @param {model} 自行車型號(hào)
    */
    sellBicycle: function(model){
        var bicycle = this.createBicycle(model);
        // 執(zhí)行A業(yè)務(wù)邏輯
        bicycle.A();

        // 執(zhí)行B業(yè)務(wù)邏輯
        bicycle.B();

        return bicycle;
    },
    createBicycle: function(model){
        throw new Error("父類是抽象類不能直接調(diào)用,需要子類重寫(xiě)該方法");
    }
};

上面是定義一個(gè)自行車抽象類來(lái)編寫(xiě)工廠模式的實(shí)列述雾,定義了createBicycle這個(gè)方法蓬豁,但是如果直接實(shí)例化父類,調(diào)用父類中的這個(gè)createBicycle方法,會(huì)拋出一個(gè)error地粪,因?yàn)楦割愂且粋€(gè)抽象類,他不能被實(shí)列化琐谤,只能通過(guò)子類來(lái)實(shí)現(xiàn)這個(gè)方法,實(shí)現(xiàn)自己的業(yè)務(wù)邏輯斗忌,下面我們來(lái)定義子類质礼,我們學(xué)會(huì)如何使用工廠模式重新編寫(xiě)這個(gè)方法,首先我們需要繼承父類中的成員织阳,然后編寫(xiě)子類;如下代碼:

// 定義自行車的構(gòu)造函數(shù)
var BicycleShop = function(name){
    this.name = name;
    this.method = function(){
        return this.name;
    }
};
BicycleShop.prototype = {
    constructor: BicycleShop,
    /*
     * 買自行車這個(gè)方法
     * @param {model} 自行車型號(hào)
    */
    sellBicycle: function(model){
            var bicycle = this.createBicycle(model);
            // 執(zhí)行A業(yè)務(wù)邏輯
            bicycle.A();

            // 執(zhí)行B業(yè)務(wù)邏輯
            bicycle.B();

            return bicycle;
        },
        createBicycle: function(model){
            throw new Error("父類是抽象類不能直接調(diào)用眶蕉,需要子類重寫(xiě)該方法");
        }
    };
    // 實(shí)現(xiàn)原型繼承
    function extend(Sub,Sup) {
        //Sub表示子類,Sup表示超類
        // 首先定義一個(gè)空函數(shù)
        var F = function(){};

        // 設(shè)置空函數(shù)的原型為超類的原型
        F.prototype = Sup.prototype; 

        // 實(shí)例化空函數(shù)唧躲,并把超類原型引用傳遞給子類
        Sub.prototype = new F();
                    
        // 重置子類原型的構(gòu)造器為子類自身
        Sub.prototype.constructor = Sub;
                    
        // 在子類中保存超類的原型,避免子類與超類耦合
        Sub.sup = Sup.prototype;

        if(Sup.prototype.constructor === Object.prototype.constructor) {
            // 檢測(cè)超類原型的構(gòu)造器是否為原型自身
            Sup.prototype.constructor = Sup;
        }
    }
    var BicycleChild = function(name){
        this.name = name;
// 繼承構(gòu)造函數(shù)父類中的屬性和方法
        BicycleShop.call(this,name);
    };
    // 子類繼承父類原型方法
    extend(BicycleChild,BicycleShop);
// BicycleChild 子類重寫(xiě)父類的方法
BicycleChild.prototype.createBicycle = function(){
    var A = function(){
        console.log("執(zhí)行A業(yè)務(wù)操作");    
    };
    var B = function(){
        console.log("執(zhí)行B業(yè)務(wù)操作");
    };
    return {
        A: A,
        B: B
    }
}
var childClass = new BicycleChild("龍恩");
console.log(childClass);

實(shí)例化子類造挽,然后打印出該實(shí)例, 如下截圖所示:

console.log(childClass.name);  // 龍恩

// 下面是實(shí)例化后 執(zhí)行父類中的sellBicycle這個(gè)方法后會(huì)依次調(diào)用父類中的A

// 和B方法;A方法和B方法依次在子類中去編寫(xiě)具體的業(yè)務(wù)邏輯弄痹。

childClass.sellBicycle("mode"); // 打印出 

執(zhí)行A業(yè)務(wù)操作和執(zhí)行B業(yè)務(wù)操作

上面只是"龍恩"自行車這么一個(gè)型號(hào)的饭入,如果需要生成其他型號(hào)的自行車的話,可以編寫(xiě)其他子類肛真,工廠模式最重要的優(yōu)點(diǎn)是:可以實(shí)現(xiàn)一些相同的方法谐丢,這些相同的方法我們可以放在父類中編寫(xiě)代碼,那么需要實(shí)現(xiàn)具體的業(yè)務(wù)邏輯蚓让,那么可以放在子類中重寫(xiě)該父類的方法乾忱,去實(shí)現(xiàn)自己的業(yè)務(wù)邏輯;使用專業(yè)術(shù)語(yǔ)來(lái)講的話有2點(diǎn):第一:弱化對(duì)象間的耦合历极,防止代碼的重復(fù)窄瘟。在一個(gè)方法中進(jìn)行類的實(shí)例化,可以消除重復(fù)性的代碼执解。第二:重復(fù)性的代碼可以放在父類去編寫(xiě)寞肖,子類繼承于父類的所有成員屬性和方法纲酗,子類只專注于實(shí)現(xiàn)自己的業(yè)務(wù)邏輯衰腌。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市觅赊,隨后出現(xiàn)的幾起案子右蕊,更是在濱河造成了極大的恐慌,老刑警劉巖吮螺,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件饶囚,死亡現(xiàn)場(chǎng)離奇詭異帕翻,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)萝风,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén)嘀掸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人规惰,你說(shuō)我怎么就攤上這事睬塌。” “怎么了歇万?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵揩晴,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我贪磺,道長(zhǎng),這世上最難降的妖魔是什么劫映? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任苏研,我火速辦了婚禮摹蘑,結(jié)果婚禮上轧飞,老公的妹妹穿的比我還像新娘。我一直安慰自己大渤,他們只是感情好掸绞,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布衔掸。 她就那樣靜靜地躺著,像睡著了一般较曼。 火紅的嫁衣襯著肌膚如雪捷犹。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,185評(píng)論 1 284
  • 那天侣颂,我揣著相機(jī)與錄音枪孩,去河邊找鬼。 笑死丛晌,一個(gè)胖子當(dāng)著我的面吹牛斗幼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播谋逻,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼毁兆,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼气堕!你這毒婦竟也來(lái)了畔咧?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤梅桩,失蹤者是張志新(化名)和其女友劉穎宿百,沒(méi)想到半個(gè)月后洪添,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡外臂,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年宋光,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了罪佳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片黑低。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡克握,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出掰曾,到底是詐尸還是另有隱情停团,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布秒梅,位于F島的核電站捆蜀,受9級(jí)特大地震影響幔嫂,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜婉烟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一洞辣、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧扬霜,春花似錦、人聲如沸著瓶。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)余蟹。三九已至,卻和暖如春威酒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背担钮。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工裳朋, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鲤嫡。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓暖眼,卻偏偏與公主長(zhǎng)得像纺裁,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子栋豫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

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

  • 工廠模式類似于現(xiàn)實(shí)生活中的工廠可以產(chǎn)生大量相似的商品丧鸯,去做同樣的事情嫩絮,實(shí)現(xiàn)同樣的效果;這時(shí)候需要使用工廠模式。簡(jiǎn)單...
    舟漁行舟閱讀 7,721評(píng)論 2 17
  • 設(shè)計(jì)模式匯總 一蜂怎、基礎(chǔ)知識(shí) 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用置尔、多...
    MinoyJet閱讀 3,906評(píng)論 1 15
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法朵锣,內(nèi)部類的語(yǔ)法试躏,繼承相關(guān)的語(yǔ)法设褐,異常的語(yǔ)法颠蕴,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,587評(píng)論 18 399
  • 設(shè)計(jì)模式基本原則 開(kāi)放-封閉原則(OCP)犀被,是說(shuō)軟件實(shí)體(類寡键、模塊雪隧、函數(shù)等等)應(yīng)該可以拓展,但是不可修改脑沿。開(kāi)-閉原...
    西山薄涼閱讀 3,753評(píng)論 3 13
  • 熱烈祝賀云聯(lián)惠與廉江大方租車對(duì)接成功 廉江大方租車派員到云聊惠總部商學(xué)院經(jīng)過(guò)多天的學(xué)習(xí)庄拇,已撐握了云聯(lián)惠大系統(tǒng)...
    雷公山閱讀 1,382評(píng)論 0 0