1. 程式人生 > >設計模式深入學習IOS版(3)工廠方法模式

設計模式深入學習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 結語

  以上是所有內容,希望對大家有所幫助,十分感謝!