iOS設計模式(代碼分析系列2:簡單工廠模式)

簡單工廠模式示例代碼下載地址html

一、簡述編程

首先須要說明一下,簡單工廠模式不屬於23種GOF設計模式之一。它也稱做靜態工做方法模式,是工廠方法模式的特殊實現(也就是說工廠模式包含簡單工廠模式)。這裏對簡單工廠模式進行介紹,是爲後面的工廠方法和抽象工廠模式作一個引子。設計模式

二、定義ide

「專門定義一個類來負責建立其餘類的實例,被建立的實例一般具備共同的父類。」
學習

世界上就是由一個工廠類,根據傳入的參數,動態地決定建立出哪個產品類的實例。spa

三、結構圖.net

簡要分析結構圖:設計

ConcreteProduct1和ConcreteProduct2兩個產品具備一個共同的父類IProject,簡單工廠類爲SimpleFactory,負責根據傳入的不一樣參數來決定生產ConcreteProduct1仍是ConcreteProduct2產品。code

四、代碼示例講解orm

模擬一個使用計算器的場景:用戶能夠輸入兩個數和操做符號,而後獲得結果,使用交互以下圖所示,分別進行除運算減運算

(1)除運算示例

(2)減運算示例

一個新手,極有可能按照本身的初步思惟邏輯,判斷用戶輸入的運算符,而後將兩個數字進行運算,固然還會加上必要的除數不爲0的判斷,那麼點擊運算Button,對應的事件能夠以下面這樣編寫,

- (IBAction)getResult:(id)sender {
    //獲得三個文本輸入框的內容
    NSString* strFirstNum = self.FirstNumTextField.text;
    NSString* strSecondNum = self.SecondNumTextField.text;
    NSString* strOperation = self.OperationTextField.text;
    //進行運算操做
    if ([strOperation isEqualToString:@"+"]) {
        NSLog(@"+");
        double result = [strFirstNum doubleValue]+[strSecondNum doubleValue];
        self.ResultTextField.text = [NSString stringWithFormat:@"%f",result];
    }else if([strOperation isEqualToString:@"-"]){
        NSLog(@"-");
        double result = [strFirstNum doubleValue]-[strSecondNum doubleValue];
        self.ResultTextField.text = [NSString stringWithFormat:@"%f",result];
    }else if([strOperation isEqualToString:@"*"]){
        NSLog(@"*");
        double result = [strFirstNum doubleValue]*[strSecondNum doubleValue];
        self.ResultTextField.text = [NSString stringWithFormat:@"%f",result];
    }
    else if([strOperation isEqualToString:@"/"]){
        NSLog(@"/");
        //判斷除數不能爲0
        if ([strSecondNum isEqualToString:@"0"]) {
            NSLog(@"除數不能爲0");
            UIAlertView* tempAlert = [[UIAlertView alloc] initWithTitle:@"警告" message:@"除數不能爲0" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
            [tempAlert show];
        }else{
            double result = [strFirstNum doubleValue]/[strSecondNum doubleValue];
            self.ResultTextField.text = [NSString stringWithFormat:@"%f",result];
        }
    }
}

恩,這樣寫確定可以實現功能。可是若是進行更多的運算,例如增長開平方、乘方運算,增長100種運算,那麼是否是要增長100個else if判斷語句呢?若是這樣去作每次都要去修改這部分代碼,這樣有悖於可擴展性原則。因此咱們須要引入簡單工廠模式,把運算給抽象出來,而且加入運算工廠用於接收用戶的操做。

註釋:這裏咱們把運算這個動做給抽象出來,當作一個對象,可能不少人以爲有點迷糊。咱們知道,面向對象編程是不一樣於面向過程編程的,一般將一個事物給抽象成一個類,類具備屬性和方法;那麼咱們也能夠把一個動做進行抽象,例如此處的運算Operation,它具備兩個屬性(前一個操做數和後一個操做數),它具備的方法就是獲取運算的結果。因此深刻理解面向對象編程,還有不少的路要走。

那麼此處咱們能夠抽象出一個UML圖,以下所示,

與上面的UML結構圖相似,這裏再簡單解釋一下,加、減、乘、除四個運算符都繼承自父類Operation,有兩個屬性和一個操做方法,這些加減乘除的對象並非直接在ViewController中建立,而是根據輸入操做符,由簡單工廠OperationFactory來建立。

(1)建立一個協議OprationProtocol,由父類Operation來聽從該協議

/*
 *  操做方法協議接口
 */
@protocol OperationProtocol <NSObject>
-(double)getResult;
@end

(2)定義加減乘除操做的父類Operation

#import OperationProtocol.h
/*
 *  操做方法父類
 */
@interface Operation : NSObject<operationprotocol>
@property double firstNum;//第一個操做數
@property double secondNum;//第二個操做數 
@end

(3)加減乘除實現類,此處以"加"舉例說明,

//OperationAdd.h文件
#import Operation.h
/*
 *  加法實現類
 */
@interface OperationAdd : Operation
@end

//OperationAdd.m文件
#import "OperationAdd.h"
@implementation OperationAdd
-(double)getResult
{
    double result = 0;
    result = self.firstNum+self.secondNum;//"+"是OperationAdd時候使用,"+-*/"分別對應"加減乘除"
    return result;
}
@end

(4)簡單工廠類的代碼,

//OpeartionFactory.h file
#import Operation.h
#import OperationAdd.h
#import OperationSub.h
#import OperationMultiply.h
#import OperationDivide.h
/*
 *  操做工廠類
 */
@interface OperationFactory : NSObject
 
//得到操做對象
+(Operation*)createOperate:(NSString*)operateStr;
 
@end

//OpeartionFactory.m file
#import "OperationFactory.h"
@implementation OperationFactory

+(Operation*)createOperate:(NSString*)operateStr
{
    Operation* oper = nil;
    //根據不一樣的操做符,建立不一樣的操做對象,"+-*/"分別對應"加減乘除"
    if ([operateStr isEqualToString:@"+"]) {
        oper = [[OperationAdd alloc] init];
    }else if ([operateStr isEqualToString:@"-"]){
        oper = [[OperationSub alloc] init];
    }else if ([operateStr isEqualToString:@"*"]){
        oper = [[OperationMultiply alloc] init];
    }else if ([operateStr isEqualToString:@"/"]){
        oper = [[OperationDivide alloc] init];
    }
    return oper;
}
@end

(5)客戶端代碼,在ViewController中使用OperationFactory

- (IBAction)clickingOperation:(id)sender {
    NSString* strFirstNum = self.firstNumTextField.text;
    NSString* strSecondNum = self.secondNumTextField.text;
    Operation* oper;
    oper = [OperationFactory createOperate:self.operationTextField.text];
    oper.firstNum = [strFirstNum doubleValue];
    oper.secondNum = [strSecondNum doubleValue];
    self.resultTextField.text = [NSString stringWithFormat:@%f,[oper getResult]];
}

這樣的話ViewController中的代碼看起來就簡潔明瞭,並且易於擴展。

那麼咱們根據ViewController中的代碼,分析一下使用思路,把操做類類比成一個容器,它有輸入端(操做符號、第一個操做數、第二個操做數)和輸出端(運算結果),以下圖所示,

因此上面的代碼將ViewController的TextField中的輸入內容拿過來建立操做對象,而且把操做運算的邏輯放在了Operation及其子類中實現,而後將結果返回給ViewController,這樣減小了ViewController的邏輯代碼。

經過簡單工廠模式的重構,咱們就是閒了低耦合度的代碼結構,作到了對外擴展開放,對修改關閉。若是再增長任何的操做方法,只須要繼承操做方法父類,新建一個操做子類,而且在簡單工廠類裏面多添加一個else if的判斷便可。

5、優缺點

優勢:簡單工廠模式的優勢是客戶端能夠直接消費產品,而沒必要關心具體產品的實現,消除了客戶端直接建立產品對象的責任,實現了對責任的分割。

缺點是工廠類幾種了全部產品的建立邏輯,一旦不能正常工做,整個系統都會受到影響,並且當產品類多結構複雜的時候,把全部建立工做放進一個工廠中來,回過後期程序的擴展較爲困難。

經過優缺點的分析,咱們能夠再以下場景中使用簡單工廠模式:

(1)工廠類負責建立的對象較少時;

(2)客戶端只知道傳入工廠類的參數,對於如何建立對象的邏輯沒必要關心時。

6、參考博客

(1)iOS設計模式淺析值簡單工廠模式(SimpleFactory)

(2)設計模式深刻學習iOS版(2)簡單工廠模式

(3)計算機簡單工廠模式示例代碼

相關文章
相關標籤/搜索