設(shè)計模式--工廠模式

在最初的學(xué)習(xí)過程中對把簡單的東西搞得復(fù)雜的現(xiàn)象很不理解像鸡,隨著經(jīng)驗的增長逆皮,慢慢發(fā)現(xiàn)我所理解的“簡單”其實是針對設(shè)計的簡單由蘑,這種代碼缺少靈活性,目的僅僅是為了解決現(xiàn)有問題帮碰。而“復(fù)雜”恰恰是針對一類問題的萬能方案相味,他可以讓代碼變得優(yōu)雅,靈活不再是一個臃腫的胖子殉挽。

在對模式的學(xué)習(xí)過程中很容易誤入歧途丰涉,陷入形式主義,對模式細(xì)節(jié)的過多關(guān)注恰恰使我們越陷越深斯碌,子曾經(jīng)曰過:“學(xué)而不思則罔”一死,文檔中的類圖和實現(xiàn)代碼往往并不能代表模式的全部,我們學(xué)習(xí)模式的重點要放在模式的意圖上傻唾。

設(shè)計模式代表了最佳的實踐投慈,是開發(fā)人員在開發(fā)過程中面臨一般問題的解決方案,是眾多前輩們在經(jīng)過相當(dāng)長一段時間的試驗和錯誤中總結(jié)出來的冠骄。

什么是設(shè)計模式

設(shè)計模式:是一套被反復(fù)使用逛裤、多數(shù)人知曉、經(jīng)過分類編目的代碼設(shè)計經(jīng)驗的總結(jié)猴抹。

使用設(shè)計模式的目的

使用設(shè)計模式是為了重用代碼带族、讓代碼更容易被他人理解、保證代碼的可靠性蟀给。

設(shè)計模式的分類
設(shè)計模式的分類
  • 創(chuàng)建型模式:創(chuàng)建型模式涉及對象的實例化蝙砌,用于解耦對象的實例化過程,不讓用戶代碼依賴于對象的創(chuàng)建或排列方式跋理,避免用戶直接使用new創(chuàng)建對象择克。。
  • 結(jié)構(gòu)型模式:把類或?qū)ο蠼Y(jié)合在一起形成一個更大的結(jié)構(gòu)前普,和類有關(guān)的結(jié)構(gòu)型模式涉及如何合理使用繼承機制肚邢;和對象有關(guān)的結(jié)構(gòu)型模式涉及如何合理的使用對象組合機制。。
  • 行為型模式: 行為型模式涉及怎樣合理的設(shè)計對象之間的交互通信骡湖,以及怎樣合理為對象分配職責(zé)贱纠,讓設(shè)計富有彈性,易維護(hù)响蕴,易復(fù)用谆焊。
工廠模式

意圖:定義一個創(chuàng)建對象的接口。讓其子類決定實例化哪一個類浦夷。使其實例化過程延遲到子類進(jìn)行辖试。

工廠模式中,我們在創(chuàng)建對象時不會對客戶端暴露創(chuàng)建邏輯劈狐,并且是通過使用一個共同的接口來指向新創(chuàng)建的對象罐孝。

三個工廠
  • 簡單工廠模式

簡單工廠模式又叫靜態(tài)工廠方法模式,實際不能算作一種設(shè)計模式肥缔。

GOF在《設(shè)計模式》一書中將工廠模式分為兩類:工廠方法模式與抽象工廠模式莲兢。將簡單工廠模式看為工廠方法模式的一種特例,兩者歸為一類辫继。

意圖:定義一個用于創(chuàng)建對象的接口

具體實現(xiàn):
抽象一個產(chǎn)品基類怒见,(接口也可以)

/**
 * @Author: chichapaofan
 * @CreateDate: 2018/10/24
 * @Description:產(chǎn)品的抽象類
 */
public abstract class Coffee {

    /**
     * 展示產(chǎn)品詳情
     */
    public abstract void details();
}

產(chǎn)品的具體實現(xiàn)

/**
 * @Author: chichapaofan
 * @CreateDate: 2018/10/24
 * @Description: 美式咖啡
 */
public class Americano extends Coffee {

    @Override
    public void details() {
        System.out.print("美式咖啡,不便宜");
    }
}
/**
 * @Author: chichapaofan
 * @CreateDate: 2018/10/24
 * @Description:拿鐵咖啡
 */
public class Latte extends Coffee {

    @Override
    public void details() {
        System.out.print("拿鐵咖啡,不便宜");
    }
}
/**
 * @Author: chichapaofan
 * @CreateDate: 2018/10/24
 * @Description:雀巢咖啡
 */
public class Nescafe extends Coffee {

    @Override
    public void details() {
        System.out.print("雀巢咖啡,喝得起");
    }
}

簡單工廠來創(chuàng)建不同類型的咖啡實例

/**
 * @Author: chichapaofan
 * @CreateDate: 2018/10/24
 * @Description: 簡單工廠
 */
public class SimpleFactory {

    /**
     * 通過傳遞過來的類型創(chuàng)建不同實例
     * @param type
     * @return
     */
    public static Coffee createInstance(String type) {
        if (type.equals("Americano")) {
            return new Americano();
        } else if (type.equals("Latte")) {
            return new Latte();
        } else if (type.equals("Nescafe")) {
            return new Nescafe();
        } else {
            throw new RuntimeException("沒有匹配到可實例化[" + type + "]對象");
        }
    }
    
}

使用

/**
 * @Author: chichapaofan
 * @CreateDate: 2018/10/24
 * @Description:
 */
public class Test {

    public static void main(String[] args) {
        Coffee latte = SimpleFactory.createInstance("Latte");
        latte.details();
        Coffee americano = SimpleFactory.createInstance("Americano");
        americano.details();
        Coffee nescafe = SimpleFactory.createInstance("Nescafe");
        nescafe.details();
    }

}

簡單工廠模式在實際使用過程中,對產(chǎn)品部分來說是符合開閉原則的姑宽,但是對于工廠部分遣耍,每增加一個新產(chǎn)品,都要在工廠類中增加相應(yīng)的創(chuàng)建邏輯炮车,這顯然違背了開閉原則舵变。

不知道設(shè)計模式六大原則的同學(xué)請自行補課
http://www.runoob.com/design-pattern/design-pattern-intro.html

  • 工廠方法模式

意圖:提供一個用于創(chuàng)建對象的接口(工廠接口),讓其實現(xiàn)類(工廠實現(xiàn)類)決定實例化哪一個類(產(chǎn)品類)瘦穆,并且由該實現(xiàn)類創(chuàng)建對應(yīng)類的實例纪隙。

可以理解為不同地區(qū)只生產(chǎn)自己類型的咖啡,美國America只生產(chǎn)Americano扛或,德國Germany只生產(chǎn)Latte和Nescafe绵咱。
具體實現(xiàn):
產(chǎn)品基類及實現(xiàn)同上
定義一個工廠基類,(使用接口的方式會更好)

/**
 * @Author: chichapaofan
 * @CreateDate: 2018/10/24
 * @Description:定義一個抽象咖啡工廠
 */
public abstract class CoffeeFactory {

    /**
     * 用于生產(chǎn)咖啡
     * @return
     */
    public abstract Coffee createCoffee(String type);
}

咖啡工廠的具體實現(xiàn)

/**
 * @Author: chichapaofan
 * @CreateDate: 2018/10/24
 * @Description:美國咖啡工廠
 */
public class AmericaCoffeeFactory extends CoffeeFactory{

    @Override
    public Coffee createCoffee(String type) {
        return new Americano();
    }
}
/**
 * @Author: chichapaofan
 * @CreateDate: 2018/10/24
 * @Description:德國咖啡工廠
 */
public class GermanyCoffeeFactory extends CoffeeFactory {

    @Override
    public Coffee createCoffee(String type) {
        if (type.equals("Latte")) {
            return new Latte();
        } else if (type.equals("Nescafe")) {
            return new Nescafe();
        } else {
            throw new RuntimeException("沒有匹配到可實例化[" + type + "]對象");
        }
    }
}

使用

public class Test {

    public static void main(String[] args) {
        /**
         * 工廠方法模式的使用方法
         */
        CoffeeFactory americaCoffeeFactory = new AmericaCoffeeFactory();
        Coffee americaCoffees = americaCoffeeFactory.createCoffee("");
        americaCoffees.details();

        CoffeeFactory germanyCoffeeFactory = new GermanyCoffeeFactory();
        Coffee latteCoffees = germanyCoffeeFactory.createCoffee("Latte");
        latteCoffees.details();
        Coffee nescafeCoffees = germanyCoffeeFactory.createCoffee("Nescafe");
        nescafeCoffees.details();
    }
}

工廠方法模式非常符合“開閉原則”熙兔,當(dāng)需要增加一個新的產(chǎn)品時悲伶,我們只需要增加一個具體的產(chǎn)品類和與之對應(yīng)的具體工廠即可,無須修改原有系統(tǒng)住涉。但是由于每新增一個新產(chǎn)品時就需要增加兩個類麸锉,這樣勢必會導(dǎo)致系統(tǒng)的復(fù)雜度增加。

  • 抽象工廠模式

場景:當(dāng)需要創(chuàng)建的對象是一系列相互關(guān)聯(lián)或相互依賴的產(chǎn)品族時舆声,便可以使用抽象工廠模式花沉。

意圖:為創(chuàng)建一組相關(guān)或相互依賴的對象提供一個接口,而且無需指定他們的具體類。抽象工廠為不同產(chǎn)品族的對象創(chuàng)建提供接口碱屁。
關(guān)鍵點在于如何在一個工廠里聚合多個同類產(chǎn)品磷脯。
具體實現(xiàn):
抽象出飲料制造工廠

/**
 * @Author: chichapaofan
 * @CreateDate: 2018/10/24
 * @Description:
 */
public interface AbstractDrinksFactory {

    /**
     * 制造咖啡
     * @return
     */
    Coffee createCoffee();

    /**
     * 制造碳酸飲料
     * @return
     */
    Sodas createSodas();

    /**
     * 制造茶
     * @return
     */
    Tea createTea();
}

飲料工廠的具體實現(xiàn)

/**
 * @Author: chichapaofan
 * @CreateDate: 2018/10/24
 * @Description:美國飲料工廠
 */
public class AmericaDrinksFactory implements AbstractDrinksFactory{

    @Override
    public Coffee createCoffee() {
        return new Latte();
    }

    @Override
    public Sodas createSodas() {
        return new CocaCola();
    }

    @Override
    public Tea createTea() {
        return null;
    }
}
/**
 * @Author: chichapaofan
 * @CreateDate: 2018/10/24
 * @Description:中國飲料工廠
 */
public class ChinaDrinksFactory implements AbstractDrinksFactory{

    @Override
    public Coffee createCoffee() {
        return new Latte();
    }

    @Override
    public Sodas createSodas() {
        return new CocaCola();
    }

    @Override
    public Tea createTea() {
        return new Dragon_Well();
    }
}

使用

/**
 * @Author: chichapaofan
 * @CreateDate: 2018/10/24
 * @Description:
 */
public class Test {

    public static void main(String[] args) {
        /**
         * 抽象工廠測試
         */
        AbstractDrinksFactory chinaDrinksFactory = new ChinaDrinksFactory();
        Coffee coffee = chinaDrinksFactory.createCoffee();
        Sodas sodas = chinaDrinksFactory.createSodas();
        Tea tea = chinaDrinksFactory.createTea();
       if (coffee != null) {
            coffee.details();
        }
        if (sodas != null) {
            sodas.details();
        }
        if (tea != null) {
            tea.details();
        }
    }
}

抽象工廠模式最主要的優(yōu)點就是可以在類的內(nèi)部對產(chǎn)品族進(jìn)行約束,而不必專門引入一個新的類來進(jìn)行管理忽媒。
當(dāng)然抽象工廠模式的缺點也非常明顯争拐,那就是產(chǎn)品族的不易擴展腋粥,使產(chǎn)品族中每需要增加一個新的產(chǎn)品晦雨,則幾乎所有的工廠類都需要進(jìn)行修改。所以使用抽象工廠模式時隘冲,對產(chǎn)品等級結(jié)構(gòu)的劃分是非常重要的闹瞧。

參考文章:
http://www.runoob.com/design-pattern/abstract-factory-pattern.html
https://www.cnblogs.com/zailushang1996/p/8601808.html
https://www.cnblogs.com/carryjack/p/7709861.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市展辞,隨后出現(xiàn)的幾起案子奥邮,更是在濱河造成了極大的恐慌,老刑警劉巖罗珍,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件洽腺,死亡現(xiàn)場離奇詭異,居然都是意外死亡覆旱,警方通過查閱死者的電腦和手機蘸朋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扣唱,“玉大人藕坯,你說我怎么就攤上這事≡肷常” “怎么了炼彪?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長正歼。 經(jīng)常有香客問我辐马,道長,這世上最難降的妖魔是什么局义? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任喜爷,我火速辦了婚禮,結(jié)果婚禮上旭咽,老公的妹妹穿的比我還像新娘贞奋。我一直安慰自己,他們只是感情好穷绵,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布轿塔。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪勾缭。 梳的紋絲不亂的頭發(fā)上揍障,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天,我揣著相機與錄音俩由,去河邊找鬼毒嫡。 笑死,一個胖子當(dāng)著我的面吹牛幻梯,可吹牛的內(nèi)容都是我干的兜畸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼碘梢,長吁一口氣:“原來是場噩夢啊……” “哼咬摇!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起煞躬,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤肛鹏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后恩沛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體在扰,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年雷客,在試婚紗的時候發(fā)現(xiàn)自己被綠了芒珠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡佛纫,死狀恐怖妓局,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情呈宇,我是刑警寧澤好爬,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站甥啄,受9級特大地震影響存炮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蜈漓,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一穆桂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧融虽,春花似錦享完、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽彼绷。三九已至,卻和暖如春茴迁,著一層夾襖步出監(jiān)牢的瞬間寄悯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工堕义, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留猜旬,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓倦卖,卻偏偏與公主長得像洒擦,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子糖耸,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354

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

  • 設(shè)計模式概述 在學(xué)習(xí)面向?qū)ο笃叽笤O(shè)計原則時需要注意以下幾點:a) 高內(nèi)聚秘遏、低耦合和單一職能的“沖突”實際上丘薛,這兩者...
    彥幀閱讀 3,743評論 0 14
  • 設(shè)計模式——工廠模式 工廠模式核心是封裝對象的創(chuàng)建接口嘉竟,將new對象的操作封裝起來,方便創(chuàng)建使用洋侨、管理對象舍扰。 工廠...
    Ant_way閱讀 550評論 0 0
  • 設(shè)計模式匯總 一、基礎(chǔ)知識 1. 設(shè)計模式概述 定義:設(shè)計模式(Design Pattern)是一套被反復(fù)使用希坚、多...
    MinoyJet閱讀 3,944評論 1 15
  • 今天裁僧,因為一位博友小勤的留言个束,我登陸了他的文學(xué)領(lǐng)地,大略看看文章目錄聊疲,發(fā)現(xiàn)他來自湘西的鳳凰茬底。 終于,有人勾起我對于...
    文飛姐姐閱讀 661評論 2 4
  • 認(rèn)識豆先生之前获洲,我是一只在愛情里順風(fēng)順?biāo)难颉?不幸的是豆先生認(rèn)識我的時候阱表,我卻剛好像薅了羊毛一樣的丑。 短發(fā)贡珊,粗...
    楊梓梧閱讀 292評論 0 0