設計模式之抽象工廠模式(Abstract Factory Pattern)

抽象工廠模式定義

抽象工廠模式(Abstract Factory Pattern)是一種創(chuàng)建型設計模式

  • 提供了一個接口,用于創(chuàng)建一系列相關或相互依賴的對象器罐,而無需指定它們的具體類梢为。
  • 抽象工廠允許客戶端使用抽象的接口來創(chuàng)建一組相關的產(chǎn)品,而具體的創(chuàng)建工作由具體工廠類完成轰坊。

基本概念

  • 抽象工廠(Abstract Factory):聲明了一組用于創(chuàng)建抽象產(chǎn)品的方法铸董,每個方法對應一個產(chǎn)品。
  • 具體工廠(Concrete Factory):實現(xiàn)了抽象工廠接口肴沫,負責創(chuàng)建具體產(chǎn)品對象粟害。
  • 抽象產(chǎn)品(Abstract Product):為一類產(chǎn)品聲明接口。
  • 具體產(chǎn)品(Concrete Product):實現(xiàn)了抽象產(chǎn)品接口樊零,由具體工廠創(chuàng)建,形成產(chǎn)品族孽文。

抽象工廠模式的種類

抽象工廠模式的實現(xiàn)方式主要有兩種:

  1. 普通實現(xiàn):直接使用接口或抽象類定義抽象工廠和抽象產(chǎn)品驻襟,具體工廠和具體產(chǎn)品實現(xiàn)這些接口。
  2. 反射機制實現(xiàn):利用反射和配置文件芋哭,使得客戶端可以動態(tài)地選擇具體工廠沉衣,實現(xiàn)更高的靈活性。

使用場景

  • 需要創(chuàng)建一系列相關或相互依賴的對象减牺,且需要避免指定它們的具體類豌习。
  • 系統(tǒng)的產(chǎn)品具有多種系列,且系統(tǒng)只消費其中某一系列的產(chǎn)品拔疚。
  • 產(chǎn)品族概念:在抽象工廠模式中肥隆,產(chǎn)品族是指位于不同產(chǎn)品等級結構中,功能相關聯(lián)的產(chǎn)品組成的家族稚失。

示例:UI 組件的跨平臺實現(xiàn)

假設我們正在開發(fā)一個跨平臺的 GUI 應用程序栋艳,需要在不同的操作系統(tǒng)(如 Windows、Mac)上顯示不同風格的按鈕和文本框句各。使用抽象工廠模式可以很好地解決這個問題吸占。

1. 定義抽象產(chǎn)品

// 抽象產(chǎn)品:按鈕
public interface Button {
    void click();
}

// 抽象產(chǎn)品:文本框
public interface TextField {
    void setText(String text);
    String getText();
}

2. 定義具體產(chǎn)品

// Windows 風格的按鈕
public class WindowsButton implements Button {
    @Override
    public void click() {
        System.out.println("Windows 風格的按鈕被點擊晴叨。");
    }
}

// Windows 風格的文本框
public class WindowsTextField implements TextField {
    private String text;

    @Override
    public void setText(String text) {
        this.text = text;
        System.out.println("Windows 風格的文本框設置文本:" + text);
    }

    @Override
    public String getText() {
        return text;
    }
}

// Mac 風格的按鈕
public class MacButton implements Button {
    @Override
    public void click() {
        System.out.println("Mac 風格的按鈕被點擊。");
    }
}

// Mac 風格的文本框
public class MacTextField implements TextField {
    private String text;

    @Override
    public void setText(String text) {
        this.text = text;
        System.out.println("Mac 風格的文本框設置文本:" + text);
    }

    @Override
    public String getText() {
        return text;
    }
}

3. 定義抽象工廠

// 抽象工廠
public interface GUIFactory {
    Button createButton();
    TextField createTextField();
}

4. 定義具體工廠

// Windows 工廠
public class WindowsFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new WindowsButton();
    }

    @Override
    public TextField createTextField() {
        return new WindowsTextField();
    }
}

// Mac 工廠
public class MacFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new MacButton();
    }

    @Override
    public TextField createTextField() {
        return new MacTextField();
    }
}

5. 客戶端代碼

public class Client {
    public static void main(String[] args) {
        GUIFactory factory;
        Button button;
        TextField textField;

        // 根據(jù)操作系統(tǒng)選擇具體工廠
        String osType = "Windows"; // 這可以從配置文件或系統(tǒng)參數(shù)獲取

        if (osType.equalsIgnoreCase("Windows")) {
            factory = new WindowsFactory();
        } else if (osType.equalsIgnoreCase("Mac")) {
            factory = new MacFactory();
        } else {
            throw new IllegalArgumentException("未知的操作系統(tǒng)類型");
        }

        // 通過工廠創(chuàng)建產(chǎn)品
        button = factory.createButton();
        textField = factory.createTextField();

        // 使用產(chǎn)品
        button.click();
        textField.setText("Hello, World!");
    }
}

輸出結果(在 Windows 平臺)

Windows 風格的按鈕被點擊矾屯。
Windows 風格的文本框設置文本:Hello, World!

6. 新增產(chǎn)品族或產(chǎn)品等級結構

如果需要支持新的操作系統(tǒng)(如 Linux)兼蕊,只需添加對應的具體工廠和具體產(chǎn)品類,而不需要修改現(xiàn)有代碼件蚕。

抽象工廠模式的優(yōu)勢

  1. 分離接口和實現(xiàn):客戶端使用抽象工廠來創(chuàng)建產(chǎn)品孙技,避免了對具體產(chǎn)品類的依賴。
  2. 產(chǎn)品族一致性:確保同一工廠創(chuàng)建的產(chǎn)品屬于同一產(chǎn)品族骤坐,避免了產(chǎn)品間的不兼容問題绪杏。
  3. 符合開閉原則:增加新的產(chǎn)品族時,只需添加新的具體工廠和產(chǎn)品類纽绍,無需修改現(xiàn)有代碼蕾久。

抽象工廠模式的意義

  • 提高系統(tǒng)的可擴展性:通過引入新的工廠和產(chǎn)品,系統(tǒng)可以支持新的產(chǎn)品族拌夏,滿足不斷變化的需求僧著。
  • 降低系統(tǒng)的耦合度:客戶端通過抽象接口與工廠和產(chǎn)品交互,具體實現(xiàn)細節(jié)對客戶端透明障簿。
  • 便于產(chǎn)品族的切換:只需更改具體工廠盹愚,客戶端即可使用不同的產(chǎn)品族,實現(xiàn)靈活的系統(tǒng)配置站故。

抽象工廠模式與工廠方法模式的區(qū)別

雖然抽象工廠模式工廠方法模式都屬于創(chuàng)建型設計模式皆怕,都涉及到工廠和產(chǎn)品的概念,但它們在目的西篓、結構和使用場景上有明顯的區(qū)別愈腾。

1. 目的不同

  • 工廠方法模式:關注創(chuàng)建單一產(chǎn)品,定義一個創(chuàng)建對象的接口岂津,讓子類決定實例化哪一個類虱黄。其目的是將對象的創(chuàng)建與使用解耦。

  • 抽象工廠模式:關注創(chuàng)建一系列相關的產(chǎn)品吮成,提供一個接口橱乱,用于創(chuàng)建相關或依賴的對象的家族,而無需明確指定具體類粱甫。其目的是為一組相關或相互依賴的對象提供一個一致的創(chuàng)建方式泳叠。

2. 結構不同

  • 工廠方法模式

    • 角色:抽象產(chǎn)品、具體產(chǎn)品茶宵、抽象工廠析二、具體工廠。
    • 特點:每個具體工廠只生產(chǎn)一種具體產(chǎn)品。
  • 抽象工廠模式

    • 角色:抽象工廠叶摄、具體工廠属韧、抽象產(chǎn)品族、具體產(chǎn)品族蛤吓。
    • 特點:每個具體工廠生產(chǎn)多個具體產(chǎn)品宵喂,產(chǎn)品組成一個產(chǎn)品族。

3. 使用場景不同

  • 工廠方法模式:適用于創(chuàng)建單個產(chǎn)品会傲,客戶端不需要知道具體產(chǎn)品的類名锅棕,只需要知道工廠接口。

  • 抽象工廠模式:適用于創(chuàng)建一組相關的產(chǎn)品淌山,客戶端需要使用這些產(chǎn)品裸燎,但是不需要知道具體的產(chǎn)品類名,只需要知道產(chǎn)品的接口和工廠泼疑。

4. 擴展性不同

  • 工廠方法模式:增加新的產(chǎn)品德绿,需要新增具體產(chǎn)品類和對應的具體工廠類。

  • 抽象工廠模式

    • 增加產(chǎn)品等級結構(新產(chǎn)品類型):需要修改抽象工廠退渗,增加新的產(chǎn)品創(chuàng)建方法移稳,以及所有的具體工廠類,違背了開閉原則会油。
    • 增加產(chǎn)品族(新產(chǎn)品系列):只需新增具體工廠類和具體產(chǎn)品類个粱,符合開閉原則。

5. 示例區(qū)別

  • 工廠方法模式:比如翻翩,在日志系統(tǒng)中都许,通過工廠方法模式創(chuàng)建不同類型的日志記錄器(文件日志、數(shù)據(jù)庫日志)嫂冻,每個工廠只創(chuàng)建一種日志記錄器胶征。

  • 抽象工廠模式:在跨平臺的 GUI 應用中,通過抽象工廠模式創(chuàng)建一組相關的 UI 組件(按鈕絮吵、文本框)弧烤,每個工廠創(chuàng)建一組風格一致的組件(如 Windows 風格忱屑、Mac 風格)蹬敲。

結語

抽象工廠模式提供了一種解決方案,使得客戶端可以使用抽象的接口來創(chuàng)建一系列相關或相互依賴的對象莺戒,而無需指定它們的具體類伴嗡。這在需要創(chuàng)建產(chǎn)品族的場景中非常有用,可以確保產(chǎn)品族的一致性从铲。

通過區(qū)分抽象工廠模式和工廠方法模式瘪校,我們可以更好地理解設計模式的應用場景和適用條件,選擇最適合的模式來解決實際問題。

啟發(fā)

抽象工廠模式通過對產(chǎn)品族的封裝阱扬,實現(xiàn)了對變化的隔離泣懊,體現(xiàn)了面向?qū)ο笤O計的開閉原則依賴倒置原則。這啟示我們麻惶,在軟件設計中馍刮,應當盡可能地面向抽象編程,減少對具體實現(xiàn)的依賴窃蹋。

抽象 是一個架構師最重要的能力亦或者是最基礎的

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載卡啰,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。
  • 序言:七十年代末警没,一起剝皮案震驚了整個濱河市匈辱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌杀迹,老刑警劉巖亡脸,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異佛南,居然都是意外死亡梗掰,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門嗅回,熙熙樓的掌柜王于貴愁眉苦臉地迎上來及穗,“玉大人,你說我怎么就攤上這事绵载」÷剑” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵娃豹,是天一觀的道長焚虱。 經(jīng)常有香客問我,道長懂版,這世上最難降的妖魔是什么鹃栽? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮躯畴,結果婚禮上民鼓,老公的妹妹穿的比我還像新娘。我一直安慰自己蓬抄,他們只是感情好丰嘉,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嚷缭,像睡著了一般饮亏。 火紅的嫁衣襯著肌膚如雪耍贾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天路幸,我揣著相機與錄音荐开,去河邊找鬼。 笑死简肴,一個胖子當著我的面吹牛誓焦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播着帽,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼杂伟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了仍翰?” 一聲冷哼從身側響起赫粥,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎予借,沒想到半個月后越平,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡灵迫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年秦叛,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瀑粥。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡挣跋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出狞换,到底是詐尸還是另有隱情避咆,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布修噪,位于F島的核電站查库,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏黄琼。R本人自食惡果不足惜樊销,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望脏款。 院中可真熱鬧围苫,春花似錦、人聲如沸弛矛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽丈氓。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間万俗,已是汗流浹背湾笛。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留闰歪,地道東北人嚎研。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像库倘,于是被迫代替她去往敵國和親临扮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348

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