工廠方法模式和簡單工廠模式十分類似,大致結構是基本類似的。不同在於工廠方法模式對工廠類進行了進一步的抽象,將之前的乙個工廠類抽象成了抽象工廠和工廠子類,抽象工廠定義乙個建立抽象子類的介面,抽象工廠的子類實現這些介面並決定例項化哪個抽象子類。工廠子類決定著建立哪個抽象子類,外界決定著建立哪種工廠子類,抽象子類和工廠子類是一一對應的。
在工廠方法模式中,和簡單工廠模式一樣,對外隱藏了抽象子類的建立過程,外界只需要關心工廠類即可,負責例項化的工廠子類決定著最後的結果。
工廠方法模式主要包含四部分:
為什麼要用工廠方法模式?
在簡單工廠模式的**中,如果我們沒有使用反射機制,只是標準的簡單工廠模式**。會有乙個問題,就是如果新增加其他運算功能,需要建立乙個抽象子類,但是還需要修改工廠類中的**邏輯,這種設計是不符合開放封閉原則的。開放封閉原則對於修改是關閉的,對於擴充套件是開放的。而且將所有的操作子類的判斷和例項化都由乙個工廠類完成,如果業務比較複雜會導致工廠類負擔較重。
工廠方法模式將之前負責生成具體抽象子類的工廠類,抽象為工廠抽象類和工廠子類組成的一系列類。每建立乙個抽象子類,就需要建立乙個工廠子類,並且一一對應,由工廠子類去生成對應的抽象子類,由外界使用方來決定生成哪個工廠子類。這樣在增加新的需求時,就不需要對工廠抽象類進行修改,而是對應新增的抽象子類建立對應的工廠子類即可。
這裡的業務場景還用之前簡單工廠模式中提到的運算的例子,根據運算子的不同,計算兩個值的結果。
工廠方法模式
這張類圖中增加了很多任務廠子類,每乙個抽象子類都對應著乙個工廠子類。這樣做的好處就是更佳靈活,每次新新增乙個抽象子類,就生成乙個工廠子類,對其他類沒有任何影響。
簡單工廠模式違背了開放封閉原則,每次新增和刪除抽象子類的時候,都需要對工廠類進行操作,這樣不僅對工廠類的擴充套件開放了,還開放了工廠類的修改,這就是違背開放封閉原則的。因為按照開放封閉原則,新增加乙個需求,應該是在原有類的基礎上進行擴充套件,而不是對原有類進行修改。這樣整個模式在生成新演算法類時,只是進行擴充套件而不對模式中原有的**進行修改,這就是符合開放封閉原則的。
工廠方法模式新建乙個抽象子類時,選擇演算法的操作還是存在的,外界的靈活性依然存在,只是將原來由工廠類對抽象子類的建立,交給工廠子類去完成建立。之前增加和刪除修改的是工廠類,現在是增加工廠子類,這也是開放封閉原則的乙個體現。之前的簡單工廠是在工廠類中建立抽象子類,工廠方法模式在工廠子類中建立抽象子類,依然封裝了物件例項化的過程。
由於**比較多,所以這裡只貼出加法和減法運算的**,其他運算**類似。
建立運算抽象類,宣告參與運算的兩個屬性和運算方法,下面的具體抽象子類繼承自這個類。
@inte***ce
operation : nsobject
@property (nonatomic, assign) cgfloat numberone;
@property (nonatomic, assign) cgfloat numbertwo;
- (cgfloat)getresult;
@end
@implementation
operation
- (cgfloat)getresult
@end
@inte***ce
operationadd : operation
@end
@implementation
operationadd
- (cgfloat)getresult
@end
@inte***ce
operationsub : operation
@end
@implementation
operationsub
- (cgfloat)getresult
@end
抽象工廠類,定義了例項化實際運算類的方法,由子類繼承並例項化不同的運算類。@inte***ce
factory : nsobject
+ (operation *)createoperation;
@end
@implementation
factory
+ (operation *)createoperation
@end
@inte***ce
factoryadd : factory
@end
@implementation
factoryadd
+ (operation *)createoperation
@end
@inte***ce
factorysub : factory
@end
@implementation
factorysub
+ (operation *)createoperation
@end
外界使用時,直接例項化某個工廠子類即可,通過外界例項化某個工廠子類來選擇具體的運算類。- (void)viewdidload
當需求發生改變時,需要進行演算法的切換,外界只需要將工廠子類呼叫類方法的類名換一下即可,其他地方都不用發生變化。這樣做就像乙個「開關」一樣,在外界由這個工廠子類的型別控制著抽象子類的例項化型別,而我們並不知道抽象子類例項化的過程。
優點工廠方法模式的的優點在於更大的靈活性,增加或刪除某種運算都不會對其他地方造成影響,更佳符合開放封閉原則。
而且對抽象的使用更佳深入,將工廠類也抽象為了抽象工廠類和工廠子類,外界呼叫更加靈活,這也是對多型的一種體現。
缺點工廠方法模式的缺點也是非常顯而易見的,工廠方法模式中新增乙個抽象子類,意味著工廠子類要跟著成對增加,這樣會造成生成過多的類,工廠方法模式的複雜度也會隨之增加。
對於這個缺點,反射機制當然可以很好的解決這個問題,工廠設計模式和反射機制的配合,可以使這種設計模式更佳易用和靈活,減少了條件判斷和類的數量。
使用工廠方法模式,看上去會感覺到這不是更麻煩了嗎,直接在外界建立具體的抽象子類不行嗎?還用這麼麻煩的建立工廠子類,然後再用工廠子類去建立抽象子類。
我將從兩方面回答這個問題:
假設現在專案比較大,在外界很多地方都直接使用了抽象子類直接進行運算,這種方式在寫**的時候確實很快也很爽。但是,假設有一天,產品經理過來說要改需求,我現在不要加減乘除這四種運算了,我要換成更高階的其他運算。。。如果這樣改起來改動就大了,需要把所有直接使用抽象子類例項化的地方都做修改。
這只是一種設計模式的思路,在程式的開發中沒有一種設計模式是萬能的,在適合的地方用適合的設計模式,或根據業務需求自己制定一套模式,這才是最好的。只有最適合業務的模式,才是最好的模式。
工廠方法模式 工廠方法模式
工廠方法模式是簡單工廠模式的公升級版,簡單工廠模式不符合設計模式的原則 即 單一職責,開閉原則 優點 職責明確,擴充套件方便 缺點 需要建立多個工廠 實現步驟 1.將工廠通用方法抽取介面 例如 ifactory 2.將產品抽取介面 例如 icar 3.實現各種產品 例如 baomacar,benti...
工廠方法模式 工廠方法模式 二
工廠方法模式是對簡單工廠的進一步抽象和封裝,需要新的類物件時不需要對既有工廠類進行修改,而是增加新的工廠類。工程類可以使用模版進一步封裝,由編譯器來生成 從而減少 編寫工作量。工廠方法的 c 實現01part產品抽象基類class animal virtual void show 0 02part產...
工廠方法模式(一) 簡單工廠方法模式
ps 第二篇學習部落格,堅持就是勝利。繼續設計模式的學習,記錄工廠模式,加深自己的理解。基本結構 abstractproduct 用來定義基本的商品的抽象 public abstract class abstractphoneproduct 用來實現抽象商品,生成各種商品 public class ...