抽象工廠模式最初的定義出現於《設計模式》(addison-wesley,1994)抽象工廠模式的類圖如下:
抽象工廠類圖
在軟體設計中,如果客戶端想手工建立乙個類的物件,那麼客戶端需要首先知道這個類的細節。更糟的情況是,一組相關的物件可以在執行時按照不同的標準建立得不一樣,此時客戶端就需要知道全部細節才能建立他們。這種情況就可以用抽象工廠模式來解決這個問題。
抽象工廠提供乙個固定的介面,用於建立一系列有關聯或相互依存的物件,而不必指定其具體類或建立細節。客戶端與從工廠得到的具體物件之間沒有耦合。
client只知道abstractfactory和abstractproduct。每個工廠類中,結構與實際操作的細節按黑箱對待。甚至產品也不知道誰將負責建立他們。只有具體工廠知道為客戶端建立什麼、如何建立。這個模式有趣的一點是,很多時候他都是用哪個工廠方法模式來實現。工廠方法吧實際的建立過程推遲到過載它的子類中。在類圖中,方法createproducta
和createproductb
是工廠方法。最初的抽象方法什麼也不建立。這種抽象非常通用,廣泛用於任何需要抽象建立過程的場合。
抽象模式常與原型模式、單例模式、享元模式等其他設計模式一起使用。
抽象工廠模式與工廠方法模式
抽象工廠模式
工廠方法模式
通過物件組合建立抽象產品
通過類繼承建立抽象產品
建立多系列產品
建立一種產品
必須修改父類才能支援新的產品
子類化建立者並過載工廠方法以建立新產品
軟體設計**法則:變動需要抽象在cocoa touch框架中使用抽象工廠
抽象工廠模式常見於cocoa touch框架。有很多基礎類採用了這一模式。特別常見的乙個就是nsnumber
。建立nsnumber
例項的方式完全符合抽象工廠模式。
建立cocoa touch物件有兩種方式:使用先alloc
再init
的方法(兩步建立過程),或者使用類中的+classname...
方法。在cocoa touch的基礎框架中,nsnumber
類有很多類方法用於建立各種型別的nsnumber
物件,像下面這樣的:
nsnumber * boolnumber = [nsnumber numberwithbool:yes];
nsnumber * charnumber = [nsnumber numbberwithchar:'a'];
nsnumber * intnumber = [nsnumber numberwithint:1];
nsnumber * floatnumber = [nsnumber numberwithfloat:1.0];
nsnumber * doublenumber = [nsnumber numberwithdouble:1.0];
每個返回的物件屬於代表最初輸入值的不同私有子類。可以像這樣列出他們的描述:
nslog(@"%@",[[boolnumber class] description]);
nslog(@"%@",[[charnumber class] description]);
nslog(@"%@",[[intnumber class] description]);
nslog(@"%@",[[floatnumber class] description]);
nslog(@"%@",[[doublenumber class] description]);
將看到控制台輸出:
nscfbollean
nscfnumber
nscfnumber
nscfnumber
nscfnumber
除了boolnumber
的實際型別是nscfboolean
以外,大多數實際類為nscfnumber
型別。儘管這些+classname...
類工廠方法返回nsnumber
具體子類的例項,但是返回的例項確實支援nsnumber
的公有介面。
雖然它們屬於nsnumber
的不同具體子類,但是其行為由抽象超類nsnumber
定義,而且是公有的。若執行以下**段,就會明白我的意思。
nslog(@"%@",[boolnumber intvalue]);
nslog(@"%@",[charnumber boolvalue] ? @"yes" : @"no");
將看到控制台輸出:
1
yes
boolnumber
內部保持布林值yes
,但是仍然實現了公有intvalue
方法,返回反映其內部布林值的適當整數值。charnumber
也是如此,它過載了boolvalue
方法,返回反映其內部布林值的適當布林值。
接受不同型別的引數並返回nsnumber
例項的類方法是類工廠方法(工廠方法模式)。nsnumber
的類工廠方法生產各種「數工廠」。numberwithbool:
建立nscfboolean
工廠的例項,而numberwithint:
建立nscfnumber
的例項。nsnumber
中的類工廠方法定義了決定例項化何種私有具體子類(比如,nscfboolean
或nscfnumber
)的預設行為。這一版本的工廠方法是傳統工廠方法的乙個變體,雖然它達成了返回抽象產品的目的,此處的抽象產品為作為工廠的具體nsnumber
子類。nsnumber
是抽象工廠實現的乙個例子。基礎框架中抽象工廠的此種特點被稱為「類簇」(class cluster)。
類簇是基礎框架中一種常見的設計模式,基於抽象工廠模式的思想,它將若干相關的私有具體工廠子類集合到乙個公有的抽象超類之下。類簇是抽象工廠的一種形式。
建立抽象產品的工廠方法與建立抽象工廠的工廠方法之前有個不同點。顯然,像intvalue
和boolvalue
這樣的工廠方法,應該在具體工廠(nscfnumber
和nscfboolean
)中過載以返回實際值(產品)。其它像numberwithbool:
和numberwithint:
這樣的工廠方法並不是為了返回產品,而是為了返回能返回產品的工廠,因此它們不應在具體工廠子類中過載。
其它實現為類簇的基礎類有nsdata
,nsarray
,nsdictionary
和nsstring
。
附上抽象工廠模式的demo:designpattern_abstractfactory
抽象工廠模式 常用設計模式 抽象工廠模式
提供乙個建立一系列相關或相互依賴物件的介面,而無需指定它們具體的類。在工廠方法模式中,我們的具體建立者每次使用都只能建立乙個同型別的物件,假如我們現在需要的是多個不同型別的物件,工廠方法就滿足不了需求了。這時我們可以把多個工廠方法組合到乙個類,這就是抽象工廠模式,它就是專門用來建立多個產品,也可以說...
抽象工廠模式 設計模式(九) 抽象工廠模式
提供乙個為建立一組相關或相互依賴物件的介面,且無須指定它們的具體類。它屬於建立型模式。在抽象工廠模式中,每個具體工廠都提供了多個用於建立多種不同型別具體物件的方法,這些不同型別的物件都存在乙個共同的屬性,構成乙個族。上篇文章設計模式 八 工廠方法模式說到工廠方法模式中只考慮某一類產品的生產,例如可樂...
設計模式 工廠模式 抽象工廠模式
建立物件時不會對客戶暴露建立邏輯,並且通過使用乙個共同的介面來指向建立的物件。sept1 建立乙個公共介面,將要對外開放的方法在這裡定義。sept2 建立實現介面的類,用即實現對外開放的類的方法 sept3 建立工廠,提供乙個get方法,這個方法提供返回實現類的物件 建立選擇 sept4 使用,建立...