複製鏈接
請複製以下鏈接發送給好友

抽象工廠模式

鎖定
抽象工廠模式(Abstract Factory Pattern)隸屬於設計模式中的創建型模式,用於產品族的構建。抽象工廠是所有形態的工廠模式中最為抽象和最具一般性的一種形態。抽象工廠是指當有多個抽象角色時使用的一種工廠模式。抽象工廠模式可以向客户端提供一個接口,使客户端在不必指定產品的具體情況下,創建多個產品族中的產品對象。 [1] 
工廠模式中的每一個形態都是針對一定問題的解決方案,工廠方法針對的是多個產品系列結構;而抽象工廠模式針對的是多個產品族結構,一個產品族內有多個產品系列。 [1] 
中文名
抽象工廠模式
外文名
Abstract Factory
是    指
當有多個抽象角色
根    據
LSP原則
創    建
多個產品族中的產品對象

抽象工廠模式實現原理

抽象工廠模式相對於工廠方法模式來説,就是工廠方法模式是針對一個產品系列的,而抽象工廠模式是針對多個產品系列的,即工廠方法模式是一個產品系列一個工廠類,而抽象工廠模式是多個產品系列一個工廠類。在抽象工廠模式中,客户端不再負責對象的創建,而是把這個責任丟給了具體的工廠類,客户端只負責對對象的調用,從而明確了各個類的職責。並且當一系列相互關聯的產品被設計到一個工廠類裏後,客户端的調用將會變得非常簡單,而且,如果要更換這一系列的產品,則只需要更換一個工廠類即可。 [2] 
如果客户端需要創建一些產品結構,而這些產品結構又分別屬於不同的產品類別,則可以使用抽象工廠模式,抽象工廠模式中抽象工廠類負責定義創建對象的接口,具體這一系列對象的創建工作由實現抽象工廠的具體工廠類來完成。 [2] 

抽象工廠模式角色

抽象工廠模式中存在四種角色,分別是抽象工廠角色,具體工廠角色,抽象產品角色,具體產品角色。 [3] 
抽象工廠角色:擔任這個角色的是工廠方法模式的核心,它是與應用系統商業邏輯無關的。 [3] 
具體工廠角色:這個角色直接在客户端的調用下創建產品的實例。這個角色含有選擇合適的產品對象的邏輯,而這個邏輯是與應用系統的商業邏輯緊密相關的。 [3] 
抽象產品角色:擔任這個角色的類是工廠方法模式所創建的對象的父類,或它們共同擁有的接口。 [3] 
具體產品角色:抽象工廠模式所創建的任何產品對象都是某一個具體產品類的實例。這是客户端最終需要的東西,其內部一定充滿了應用系統的商業邏輯。 [3] 

抽象工廠模式功能

抽象工廠模式的一個主要功能是它能夠隔離要生成的具體產品類, 由於這些類的實際類名部被隱藏在工廠內部,因此客户端根本不需要關心如何對它們進行實例化的細節。每種設計模式都是針對特定問題的解決方案,而抽象工廠模式面臨的問題則是當涉及到有多個產品等級結構寸,如何更好地進行軟件體系結構的設計。 [4] 

抽象工廠模式代碼舉例

假設我們有兩種產品接口 Button 和 Border ,每一種產品都支持多種系列,比如 Mac 系列和 Windows 系列。這樣每個系列的產品分別是 MacButton, WinButton, MacBorder, WinBorder 。為了可以在運行時刻創建一個系列的產品族,我們可以為每個系列的產品族創建一個工廠 MacFactory 和 WinFactory 。每個工廠都有兩個方法 CreateButton 和 CreateBorder 並返回對應的產品,可以將這兩個方法抽象成一個接口 AbstractFactory 。這樣在運行時刻我們可以選擇創建需要的產品系列。 [5] 

抽象工廠模式C++

我們的產品結構是這樣的
class Button; // Abstract 
Classclass MacButton: public Button {};
class WinButton: public Button {};
class Border; // Abstract 
Classclass MacBorder: public Border {};
class WinBorder: public Border {};
對應的工廠是這樣的
class AbstractFactory {public:    virtual Button* CreateButton() =0;    virtual Border* CreateBorder() =0;};class MacFactory: public AbstractFactory {public:    MacButton* CreateButton() { return new MacButton; }    MacBorder* CreateBorder() { return new MacBorder; }};class WinFactory: public AbstractFactory {public:    WinButton* CreateButton() { return new WinButton; }    WinBorder* CreateBorder() { return new WinBorder; }};
那麼客户可以根據需要選擇 Mac 風格或者 Win 風格來創建 Button 或 Border
AbstractFactory* fac;switch (style) {case MAC:    fac = new MacFactory;    break;case WIN:    fac = new WinFactory;    break;}Button* button = fac->CreateButton();
Border* border = fac->CreateBorder();

抽象工廠模式PHP

<?php/*************************************************************************** *              AbstractFactory.php *              ------------------- *   Time  :    2006-11-11 *   Coder :    rollenc(http://www.rollenc.com) *              syre(http://syre.blogbus.com) ***************************************************************************/abstract class AbstractFactory {    abstract public function CreateButton();    abstract public function CreateBorder();}class MacFactory extends AbstractFactory{    public function CreateButton()    {        return new MacButton();    }    public function CreateBorder()    {        return new MacBorder();    }}class WinFactory extends AbstractFactory{    public function CreateButton()    {        return new WinButton();    }    public function CreateBorder()    {        return new WinBorder();    }}class Button{}class Border{}class MacButton extends Button{    function __construct()    {        echo 'MacButton is created' . "\n";    }}class MacBorder extends Border{    function __construct()    {        echo 'MacBorder is created' . "\n";    }}class WinButton extends Button{    function __construct()    {        echo 'WinButton is created' . "\n";    }}class WinBorder extends Border{    function __construct()    {        echo 'WinBorder is created' . "\n";    }}?>
那麼客户可以根據需要選擇 Mac 風格或者 Win 風格的 Button 或 Border 來創建
<?$type = 'Mac'; //value by user.
    if(!in_array($type, array('Win','Mac')))      die('Type Error');
    $factoryClass = $type.'Factory';
    $factory=new $factoryClass;
    $factory->CreateButton();
    $factory->CreateBorder();

抽象工廠模式Java

  • 使用上面的例子
public interface Button {}
public interface Border {}
  • 實現抽象類
public class MacButton implements Button {}
public class MacBorder implements Border {}
public class WinButton implements Button {}
public class WinBorder implements Border {}
  • 接着實現工廠
public class MacFactory {    public static Button createButton() {        return new MacButton();    }    public static Border createBorder() {        return new MacBorder();    }}public class WinFactory {    public static Button createButton() {        return new WinButton();    }    public static Border createBorder() {        return new WinBorder();    }}

抽象工廠模式適用情況

在以下情況可以考慮使用抽象工廠模式: [6] 
  • 一個系統要獨立於它的產品的創建、組合和表示時。 [6] 
  • 一個系統要由多個產品系列中的一個來配置時。 [6] 
  • 需要強調一系列相關的產品對象的設計以便進行聯合使用時。 [6] 
  • 提供一個產品類庫,而只想顯示它們的接口而不是實現時。 [6] 

抽象工廠模式優缺點

抽象工廠模式優點

(1)分離了具體的類。客户通過抽象接口操縱實例,產品的類名也在具體工廠的實現中被分離,它們不出現在客户代碼中。 [3] 
(2)易於交換產品系列。一個具體工廠類只在初始化時出現一次,這使得改變一個應用的具體工廠變得很容易,只需改變具體的工廠即可使用不同的產品配置。 [3] 
(3)有利於產品的一致性。當一個系列的產品對象被設計成一起工作時,一個應用一次只能使用同一個系列中的對象,這一點很重要,而抽象工廠很容易實現這一點。 [3] 

抽象工廠模式缺點

難以支持新種類的產品。因為抽象工廠接口確定了可以被創建的產品集合,所以難以擴展抽象工廠以生產新種類的產品。 [3] 
參考資料
  • 1.    温立輝主編.Java EE編程技術:北京理工大學出版社,2016.01:第206頁
  • 2.    郭峯著.深入淺出設計模式:中國鐵道出版社,2013.01:第79頁
  • 3.    沙基昌主編.軟件開發中級編程指南:國防科技大學出版社,2008.09:第243頁
  • 4.    黃永忠 陳新 陳海勇 劉蓬暉 王磊 周蓓編著.面向對象方法與技術基礎:國防工業出版社,2006年05月第1版:第318頁
  • 5.    陳華恩. JAVA設計模式研究之抽象工廠模式[J]. 電腦知識與技術, 2010, 6(9):2245-2246.
  • 6.    徐瀟,李遠編著.MATLAB面向對象編程 從入門到設計模式:北京航空航天大學出版社,2015.01:第247頁