淺談設(shè)計(jì)模式4——簡單工廠與工廠模式


書上是三個(gè)模式——簡單工廠模式、工廠模式妈经、抽象工廠模式淮野,一塊說。對(duì)于昨天實(shí)在沒有休息好的狀態(tài)下吹泡,看到如此混亂的景象骤星,確實(shí)有點(diǎn)受不了。好在后面一遍又一遍重復(fù)爆哑,總算是理解了洞难。但是,既然是記筆記揭朝,也是給別人看队贱,那么我覺得拆開來說或許更加明白。

1潭袱、背景
書上用pizza來打比方柱嫌,其實(shí)還是挺愛吃,但是名字太繞口屯换,而且也不熟悉编丘。所以還是用餃子我覺得會(huì)更加親切些——我最愛吃的。
現(xiàn)在我要開一家餃子館,供應(yīng)各種口味的餃子瘪吏,三鮮餡癣防,胡蘿卜羊肉餡,西胡蝦仁餡掌眠,芹菜牛肉餡蕾盯,豬肉大蔥餡,豬肉白菜餡——看來好吃的說起來都沒完沒了蓝丙。
最開始的想法是级遭,按照如下步驟建立餃子:
1)用餃子抽象類建立餃子對(duì)象實(shí)體。
2)包餃子渺尘。
3)煮餃子挫鸽。
4)裝盤,配醬油和醋鸥跟。
5)上桌或打包外賣丢郊。
實(shí)現(xiàn)成的代碼如下——為了不讓很多的名詞困擾,此處直接采用更加形式化的命名方法:

//產(chǎn)品類型
abstract class ProductBase
{
    @Override
    public String toString() {
        return "productbase";
    }
}

class Product1 extends ProductBase
{
    @Override
    public String toString() {
        return "product1";
    }
}

class Product2 extends ProductBase
{
    @Override
    public String toString() {
        return "product2";
    }
}

//商店
class Store
{
    ProductBase product;
    public void  create(String product) {
        if(product.equals("product1"))
            this.product=new Product1();
        else if(product.equals("product2"))
            this.product=new Product2();
        
        //后續(xù)的操作
        //包餃子();
        //煮餃子()医咨;
        //裝盤枫匾,配醬油和醋();
        //上桌或打包()拟淮;
    }
}

上面的代碼將創(chuàng)建餃子對(duì)象和對(duì)餃子的后續(xù)的加工操作干茉,嚴(yán)重耦合,造成以下兩個(gè)比較嚴(yán)重的問題:
1)一個(gè)函數(shù)中的代碼量過大很泊,而且隨著新類型產(chǎn)品研發(fā)角虫,這個(gè)函數(shù)將越來越大,不容易維護(hù)委造。
2)當(dāng)餐館發(fā)明新的餃子時(shí)戳鹅,就需要修改sell()方法。原來類的封裝性就遭到破壞争涌。

2粉楚、簡單工廠模式
根據(jù)上面的問題,我們自然想到的是將創(chuàng)建產(chǎn)品對(duì)象的那部分代碼進(jìn)行封裝亮垫,這樣就實(shí)現(xiàn)了工廠模式。簡單工廠模式如下:

//產(chǎn)品類型
abstract class ProductBase
{
    @Override
    public String toString() {
        return "productbase";
    }
}

class Product1 extends ProductBase
{
    @Override
    public String toString() {
        return "product1";
    }
}

class Product2 extends ProductBase
{
    @Override
    public String toString() {
        return "product2";
    }
}

class ProductFactory
{
    public ProductBase create(String product)
    {
        if(product.equals("product1"))
            return new Product1();
        else if(product.equals("product2"))
            return new Product2();
        else return null;
    }
}

//商店
class Store
{
    ProductBase product;
    ProductFactory productFactory;
    
    public Store(ProductFactory productFactory)
    {
        this.productFactory=productFactory;
    }
    
    public void  create(String product) {
    /*  if(product.equals("product1"))
            this.product=new Product1();
        else if(product.equals("product2"))
            this.product=new Product2();
    */
        this.productFactory.create(product);
        //后續(xù)的操作
        //包餃子();
        //煮餃子()伟骨;
        //裝盤饮潦,配醬油和醋();
        //上桌或打包()携狭;
    }
}

“簡單工廠模式”是將對(duì)象的生成和使用進(jìn)行分離继蜡,以組合的方式,當(dāng)創(chuàng)建使用某一類對(duì)象的實(shí)體時(shí)(如Store類的對(duì)象),將真正創(chuàng)建對(duì)象的工廠傳入稀并。從而獲得以下兩方面的收益:
1)工廠可以在動(dòng)態(tài)運(yùn)行時(shí)的時(shí)候指定仅颇。比如我現(xiàn)在不打算開餃子店了,想做包子碘举,由于包子和餃子的后續(xù)工作都是一樣的忘瓦,所以只需把制作包子的工廠傳入Store類中就行。
2)產(chǎn)品引颈、制作耕皮、使用三者進(jìn)行了有效分離。產(chǎn)品的分離已經(jīng)在前面的策略模式中說道——用抽象接口來“臨時(shí)”代替具體類蝙场,占位置凌停,將創(chuàng)建對(duì)象實(shí)體推遲到運(yùn)行時(shí)。制作即使用了簡單工廠模式售滤,而使用即為Store類罚拟。這樣就在一定程度上,將類之間的耦合度降到很低完箩。

3赐俗、工廠模式
相對(duì)于簡單工廠模式,工廠模式的耦合度相對(duì)來說比較大嗜憔。之所以比較大秃励,先看下面的例子。
假設(shè)餃子店生意不錯(cuò)吉捶,規(guī)模逐漸增大夺鲜,最后成立一個(gè)實(shí)業(yè)公司——餃子餐飲有限公司,而且設(shè)立了各個(gè)分部——華北子公司呐舔,東北子公司币励,華南子公司,華東子公司珊拼,中西部子公司食呻。為了保證所有公司生產(chǎn)的餃子質(zhì)量過關(guān),公司決定控制生產(chǎn)流程澎现。所有子公司可以根據(jù)當(dāng)?shù)靥禺a(chǎn)仅胞,選擇自己的餡料,但是制作工藝必須嚴(yán)格按照公司的流程剑辫,比如每個(gè)面皮必須為10g干旧,直徑5CM的圓面片。餡料必須20g妹蔽。
這樣椎眯,既增加了靈活性——子公司可以根據(jù)當(dāng)?shù)靥禺a(chǎn)選擇餡料挠将,又保證了質(zhì)量——嚴(yán)格按照母公司的規(guī)程辦事。

說這么多编整,我想“簡單工廠模式”和“工廠模式”應(yīng)用的場景大家也應(yīng)該能看出來了舔稀。
1)簡單工廠模式是針對(duì)只有一個(gè)使用者的情況來說,即程序中只有一個(gè)Store類掌测,這個(gè)Store類可以使用多用“工廠類”來為自己加工產(chǎn)品内贮。
2)工廠模式不同,它是針對(duì)某個(gè)基類的一堆子類赏半,在保證某些流程不改變的情況下贺归, 允許子類有自己的行為特征。也就是說断箫,基類規(guī)定了框架拂酣,而子類只能在框架的基礎(chǔ)上修補(bǔ)、更改仲义。

那么看下面的代碼就比較能說明問題了:

abstract class ProductBase
{
    @Override
    public String toString() {
        return "productbase";
    }
}
class a1 extends ProductBase
{
    @Override
    public String toString() {
        return "a1";
    }
}
class a2 extends ProductBase
{
    @Override
    public String toString() {
        return "a2";
    }
}
class b1 extends ProductBase
{
    @Override
    public String toString() {
        return "b1";
    }
}
class b2 extends ProductBase
{
    @Override
    public String toString() {
        return "b2";
    }
}


//創(chuàng)建工廠基類
abstract class FactoryBase
{
    public abstract ProductBase create(String type);
    final public ProductBase sell(String type)
    {
        ProductBase productBase;
        productBase=create(type);
        //后續(xù)的操作
        //包餃子();
        //煮餃子()婶熬;
        //裝盤,配醬油和醋()埃撵;
        //上桌或打包()赵颅;
        return productBase;
    }
}
//實(shí)現(xiàn)工廠派生類
class Factory1 extends FactoryBase
{
    @Override
    public ProductBase create(String type) {
        ProductBase productBase=null;
        if(type.equals("a1"))
            productBase=new a1();
        else if(type.equals("a2"))
            productBase=new a2();
        return productBase;
    }
}

class Factory2 extends FactoryBase
{
    @Override
    public ProductBase create(String type) {
        ProductBase productBase=null;
        if(type.equals("b1"))
            productBase=new b1();
        else if(type.equals("b2"))
            productBase=new b2();
        return productBase;
    }
}

如上代碼所示:
1)分別建立產(chǎn)品基類、工廠基類暂刘。由產(chǎn)品基類饺谬,根據(jù)不同地區(qū)(地區(qū)a和地區(qū)b),構(gòu)建了子類產(chǎn)品谣拣。相應(yīng)的募寨,也構(gòu)建了不同的子類工廠。
2)基類工廠中森缠,sell()方法作為對(duì)外統(tǒng)一方法拔鹰,控制生產(chǎn)總流程,因此生命為final方法贵涵。而create()方法則因地制宜列肢,按照不同地區(qū)特點(diǎn),生產(chǎn)特定的產(chǎn)品宾茂。

這樣瓷马,工廠方法既保證了修改的靈活性,也保證了某些必要操作不會(huì)被修改跨晴。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末决采,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子坟奥,更是在濱河造成了極大的恐慌树瞭,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件爱谁,死亡現(xiàn)場離奇詭異晒喷,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)访敌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門凉敲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人寺旺,你說我怎么就攤上這事爷抓。” “怎么了阻塑?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵蓝撇,是天一觀的道長。 經(jīng)常有香客問我陈莽,道長渤昌,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任走搁,我火速辦了婚禮独柑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘私植。我一直安慰自己忌栅,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布曲稼。 她就那樣靜靜地躺著索绪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪躯肌。 梳的紋絲不亂的頭發(fā)上者春,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音清女,去河邊找鬼钱烟。 笑死,一個(gè)胖子當(dāng)著我的面吹牛嫡丙,可吹牛的內(nèi)容都是我干的拴袭。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼曙博,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼拥刻!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起父泳,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤般哼,失蹤者是張志新(化名)和其女友劉穎吴汪,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蒸眠,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡漾橙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了楞卡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片霜运。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蒋腮,靈堂內(nèi)的尸體忽然破棺而出淘捡,到底是詐尸還是另有隱情,我是刑警寧澤池摧,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布焦除,位于F島的核電站,受9級(jí)特大地震影響险绘,放射性物質(zhì)發(fā)生泄漏踢京。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一宦棺、第九天 我趴在偏房一處隱蔽的房頂上張望瓣距。 院中可真熱鬧,春花似錦代咸、人聲如沸蹈丸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽逻杖。三九已至,卻和暖如春思瘟,著一層夾襖步出監(jiān)牢的瞬間荸百,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工滨攻, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留够话,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓光绕,卻偏偏與公主長得像女嘲,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子诞帐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

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

  • 設(shè)計(jì)模式匯總 一欣尼、基礎(chǔ)知識(shí) 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 3,903評(píng)論 1 15
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法停蕉,類相關(guān)的語法愕鼓,內(nèi)部類的語法钙态,繼承相關(guān)的語法,異常的語法拒啰,線程的語...
    子非魚_t_閱讀 31,581評(píng)論 18 399
  • 一個(gè)UML類圖 類之間的關(guān)系 類的繼承結(jié)構(gòu)表現(xiàn)在UML中為:泛化(generalize)與實(shí)現(xiàn)(realize) ...
    僚機(jī)KK閱讀 638評(píng)論 0 0
  • 設(shè)計(jì)模式基本原則 開放-封閉原則(OCP)驯绎,是說軟件實(shí)體(類、模塊谋旦、函數(shù)等等)應(yīng)該可以拓展,但是不可修改屈尼。開-閉原...
    西山薄涼閱讀 3,753評(píng)論 3 13
  • 簡單工廠模式雖然簡單册着,但存在一個(gè)很嚴(yán)重的問題。當(dāng)系統(tǒng)中需要引入新產(chǎn)品時(shí)脾歧,由于靜態(tài)工廠方法通過所傳入?yún)?shù)的不同來創(chuàng)建...
    justCode_閱讀 1,177評(píng)論 1 9