在開發中我們經常會遇到這樣一種情況,同一種功能,因為使用的場景不同而需要使用不同演算法來實現。比如textfield輸入的文字格式要求可能是**號碼、郵箱等,我們在驗證textfield輸入是否符合格式時,我們需要根據textfield的型別來選擇不同的驗證演算法。
我們要實現這個功能並不難,只需要在驗證輸入的方法中使用if-else
來對不同的型別的文字框做相應的處理,就有下面這種處理方法:
if (textfield == _emailtextfield) else if (textfield == _phonetextfield) else if (textfield == _securitycodetextfield) else
但是使用if-else
有幾個弊端:
1. 需要判斷的條件太多的時候,**的可讀性比較差。
2. 需要增加或刪除某個條件時都需要在源**的基礎上修改,不便於擴充套件。
3. 當驗證演算法需要修改的時候,改動的地方會比較多,同時由於改動檔案又有可能引起其它問題。
面對演算法的時常變動,使用if-else
的處理方式就顯得比較糟糕了,接下來我們來看看策略設計模式的威力。
還是以驗證textfield輸入文字格式為例,來看看策略設計模式的基本使用方法。
定義乙個策略類,即所有演算法類的父類
@inte***ce inputvalidator : nsobject
/** * 子類重寫這個方法,在這個方法中實現各自的驗證演算法
*/- (bool)validateinput:(nsstring *)inputstring;
@property(nonatomic,copy) nsstring *errormessage;/**< 輸入不合法時的錯誤提示 */
@end
建立演算法類
驗證郵箱的演算法類。
//.h檔案
#import "inputvalidator.h"
@inte***ce emailvalidator : inputvalidator
@end
//.m檔案
#import "emailvalidator.h"
#import "nsstring+validate.h"
@implementation emailvalidator
/** * 重寫父類輸入合法性檢測方法
* * @return
*/- (bool)validateinput:(nsstring *)inputstring
else if ([inputstring emailvalidate]) else
}@end
驗證手機號的演算法類。
//注:其他部分和驗證郵箱演算法類一樣
- (bool)validateinput:(nsstring *)inputstring
else if ([inputstring phonenumbervalidate]) else
}
定義好策略類及其算法子類之後,我們需要告訴textfield驗證輸入的時候選擇哪種演算法,所以需要自定義乙個textfield,並讓其擁有乙個策略類屬性。
#import #import "inputvalidator.h"
@inte***ce customfield : uitextfield
@property(nonatomic,strong) inputvalidator *inputvalidator;/**< 抽象策略 */
//驗證輸入
- (bool)validateinput;
@end
//.m檔案中- (bool)validateinput;方法的實現**
- (bool)validateinput
準備工作都做好了,接下來可以開始使用了。
建立textfield的時候,需要告訴textfield驗證輸入的時候選擇的演算法。
//郵箱
customfield *emailtextfield = [[customfield alloc]initwithframe:cgrectmake(10, 10, self.view.frame.size.width-20, 44)];
emailtextfield.delegate =self;
emailtextfield.placeholder = @"請輸入郵箱";
emailtextfield.inputvalidator = [emailvalidator new];
[self.view addsubview:emailtextfield];
//**號碼
customfield *phonetextfield = [[customfield alloc]initwithframe:cgrectmake(10, 10+44+10, self.view.frame.size.width-20, 44)];
phonetextfield.delegate =self;
phonetextfield.placeholder = @"請輸入**號碼";
phonetextfield.inputvalidator = [phonenumbervalidator new];
[self.view addsubview:phonetextfield];
在驗證輸入格式的時候我們也會變得比使用if-else
更加簡單。
- (void)textfielddidendediting:(uitextfield *)textfield
else
}
假設之後需要再增加其他型別的textfield,比如驗證碼輸入框,我們只需要再建立乙個算法子類來處理驗證碼的輸入問題,而不會影響其他地方的**,對於擴充套件性和**可讀性來說都優於if-else
方法。
總結:策略模式是定義了一系列的演算法,它可以以相同的方式呼叫所有的演算法,這些演算法完成的都是同一種功能,只不過因不同的使用場景需要選擇不同的演算法。雖然策略設計模式好處多多,但也有一些不足之處:
策略模式文字輸入框demo
推薦閱讀:設計模式之策略模式(ios開發,**用objective-c展示)
設計模式 策略設計模式
策略設計模式其實就是多型的使用,父類引用指向子類物件。策略模式的最大特點是使得演算法可以在不影響客戶端的情況下發生變化,從而改變不同的功能。策略模式的缺點其實也很明顯,在於策略模式把每一種具體的策略都封裝成乙個實現類,如果策略有很多的話,很顯然是實現類就會導致過多,顯得臃腫。案列 author de...
策略設計模式 Go語言設計模式 策略
策略設計模式 策略模式是一種行為設計模式。此模式允許在執行時不需要更改物件的型別定義時就能改變該物件的行為。用乙個例子來理解策略模式。假設構建乙個快取inmemorycache,它擁有固定的容量大小,當達到其最大容量時,快取中的某些舊項需要被逐出,這種驅逐可以通過幾種演算法來實現 現在的問題是如何將...
設計模式 策略模式
策略模式是一種定義一系列演算法的方法,從概念上來看,所有這些方法完成的都是相同的工作,只是實現不同,他們可以用相同的方式呼叫所有的演算法,減少了演算法類和使用演算法類之間的耦合.優點 策略模式的strategy類層次為context定義了一系列可供重用的演算法和行為,繼承有助於吸取這些演算法中的公共...