設計模式深入學習IOS版(3)工廠方法模式
1 前言
上篇部落格我們學習了簡單工廠模式,今天我們深入一點,學習一下工廠方法模式。工廠方法模式是在簡單工廠模式的基礎上延伸出來的,只不過把原來的工廠類給抽象出來了,這樣是的工廠類可擴充套件性增強。從而進一步的進行了抽象。
2 詳述
2.1 定義
定義一個用於建立物件的介面,讓子類決定例項化哪一個類,工廠方法使一個類的例項化延遲到其子類。
結構圖:
2.2 簡單工廠與工廠方法的區別
簡單工廠模式的最大優點在於工廠類中包含了必要的邏輯判斷,根據客戶端的選擇條件動態的例項化相關的類,對於客戶端來說,去除了與具體產品的依賴。
工廠方法模式的客戶端需要決定例項化哪一個工廠來實現運算類,選擇判斷的問題還是存在的,也就是說,工廠方法把簡單工廠的內部邏輯移到了客戶端程式碼來進行。如果我們想要增加功能,本來是改工廠類的,而現在是修改客戶端。
2.3 工廠方法模式四個要素
- 工廠介面。工廠介面是工廠方法模式的核心,與呼叫者直接互動用來提供產品。在實際程式設計中,有時候也會使用一個抽象類來作為與呼叫者互動的介面,其本質上是一樣的。
- 工廠實現。在程式設計中,工廠實現決定如何例項化產品,是實現擴充套件的途徑,需要有多少種產品,就需要有多少個具體的工廠實現。
- 產品介面。產品介面的主要目的是定義產品的規範,所有的產品實現都必須遵循產品介面定義的規範。產品介面是呼叫者最為關心的,產品介面定義的優劣直接決定了呼叫者程式碼的穩定性。同樣,產品介面也可以用抽象類來代替,但要注意最好不要違反里氏替換原則。
- 產品實現。實現產品介面的具體類,決定了產品在客戶端中的具體行為。
2.4 適用場景
不管是簡單工廠模式,工廠方法模式還是抽象工廠模式,他們具有類似的特性,所以他們的適用場景也是類似的。
首先,作為一種建立類模式,在任何需要生成複雜物件的地方,都可以使用工廠方法模式。有一點需要注意的地方就是複雜物件適合使用工廠模式,而簡單物件,特別是只需要通過new就可以完成建立的物件,無需使用工廠模式。如果使用工廠模式,就需要引入一個工廠類,會增加系統的複雜度。
其次,工廠模式是一種典型的解耦模式,迪米特法則在工廠模式中表現的尤為明顯。假如呼叫者自己組裝產品需要增加依賴關係時,可以考慮使用工廠模式。將會大大降低物件之間的耦合度。
再次,由於工廠模式是依靠抽象架構的,它把例項化產品的任務交由實現類完成,擴充套件性比較好。也就是說,當需要系統有比較好的擴充套件性時,可以考慮工廠模式,不同的產品用不同的實現工廠來組裝。
現在我們就把上次的計算器的簡單工廠模式的程式碼改造一下:
UML圖:
工廠協議介面:
#import <Foundation/Foundation.h>
#import "Operation.h"
/*!
* 工廠協議介面
*
* @since V1.0
*/
@protocol IFactoryProtocol <NSObject>
-(Operation*)createOperate;
@end
生產工廠父類:
#import <Foundation/Foundation.h>
#import "IFactoryProtocol.h"
/*!
* 生產工廠父類
*
* @since V1.0
*/
@interface FactoryBase : NSObject<IFactoryProtocol>
@end
加法工廠類:
#import <Foundation/Foundation.h>
#import "OperationAdd.h"
#import "FactoryBase.h"
/*!
* 加法工廠類
*
* @since V1.0
*/
@interface AddFactoy : FactoryBase
@end
客戶端程式碼:
- (IBAction)clickingOperation:(id)sender {
NSString* strFirstNum = self.firstNumTextField.text;
NSString* strSecondNum = self.secondNumTextField.text;
NSString* strOperation = self.operationTextField.text;
FactoryBase* facBase;
if ([strOperation isEqualToString:@"+"]) {
facBase = [[AddFactoy alloc] init];
}else if([strOperation isEqualToString:@"-"]){
facBase = [[SubFactory alloc] init];
}else if([strOperation isEqualToString:@"*"]){
facBase = [[MulFactory alloc] init];
}else if([strOperation isEqualToString:@"/"]){
facBase = [[DivFactory alloc] init];
}
Operation* oper;
oper = [facBase createOperate];
oper.firstNum = [strFirstNum doubleValue];
oper.secondNum = [strSecondNum doubleValue];
self.resultTextField.text = [NSString stringWithFormat:@"%f",[oper getResult]];
}
通過上面的改造部分可以看出,我們對工廠類進行了抽象,以後如果再增加了新的操作方法,我們只需要在原來的基礎上動態的擴充套件工廠子類即可。這也是工廠方法的優勢所在。
3 結語
以上是所有內容,希望對大家有所幫助,十分感謝!