- 用處:讓算法和對(duì)象分開來翻擒,使得算法可以獨(dú)立于使用它的客戶而變化。
- 例子:出行旅游怯疤,我們 可以有幾個(gè)策略可以考慮掠抬,可以騎(對(duì)象)自行車,汽車顽悼,做火車,飛機(jī)。每個(gè)策略都可以得到相同的結(jié)果吐句,但是它們使用了不同的資源。選擇策略的依據(jù)(算法)是費(fèi)用店读,時(shí)間嗦枢,使用工具還有每種方式的方便程度 。
-
結(jié)構(gòu)
- 當(dāng)存在以下情況時(shí)使用策略模式(優(yōu)點(diǎn))
許多相關(guān)的類僅僅是行為有異屯断。 “策略”提供了一種用多個(gè)行為中的一個(gè)行為來配置一個(gè)類的方法文虏。即一個(gè)系統(tǒng)需要?jiǎng)討B(tài)地在幾種算法中選擇一種。
需要使用一個(gè)算法的不同變體殖演。例如氧秘,你可能會(huì)定義一些反映不同的空間 /時(shí)間權(quán)衡的算法。當(dāng)這些變體實(shí)現(xiàn)為一個(gè)算法的類層次時(shí) 趴久,可以使用策略模式丸相。
算法使用客戶不應(yīng)該知道的數(shù)據(jù)”斯鳎可使用策略模式以避免暴露復(fù)雜的灭忠、與算法相關(guān)的數(shù)據(jù)結(jié)構(gòu)。
一個(gè)類定義了多種行為 , 并且這些行為在這個(gè)類的操作中以多個(gè)條件語句的形式出現(xiàn)座硕。將相關(guān)的條件分支移入它們各自的策略類中以代替這些條件語句弛作。
- 缺點(diǎn)
1.客戶端必須知道所有的策略類,并自行決定使用哪一個(gè)策略類华匾,就是一個(gè)客戶要選擇一個(gè)合適的策略就必須知道這些策略到底有何不同缆蝉。此時(shí)可能不得不向客戶暴露具體的實(shí)現(xiàn)問題。因此僅當(dāng)這些不同行為變體與客戶相關(guān)的行為時(shí) , 才需要使用策略模式。
2.Strategy和Context之間的通信開銷:無論各個(gè)ConcreteStrategy實(shí)現(xiàn)的算法是簡(jiǎn)單還是復(fù)雜, 它們都共享Strategy定義的接口刊头。因此很可能某些 ConcreteStrategy不會(huì)都用到所有通過這個(gè)接口傳遞給它們的信息黍瞧;簡(jiǎn)單的 ConcreteStrategy可能不使用其中的任何信息!這就意味著有時(shí)Context會(huì)創(chuàng)建和初始化一些永遠(yuǎn)不會(huì)用到的參數(shù)原杂。如果存在這樣問題 , 那么將需要在Strategy和Context之間更進(jìn)行緊密的耦合印颤。
3.策略模式將造成產(chǎn)生很多策略類。
- iOS 應(yīng)用:做一個(gè)只接收字母, 只接收數(shù)字的輸入框, 驗(yàn)證登錄
當(dāng)xib或者sb中有兩個(gè)或多個(gè)以上輸入框穿肄,假如叫l(wèi)etterInput年局,numberInput;那么勢(shì)必在view咸产,或者控制器會(huì)有如下代碼:
- (void)textFieldDidEndEditing:(UITextField *)textField{
if(textField == self.letterInput){
//驗(yàn)證是字母的邏輯等
}else if(textField == self.numberInput){
//驗(yàn)證是數(shù)字的邏輯等
}
}
那么矢否,出現(xiàn)的問題是,如果輸入框較多時(shí)候邏輯太長(zhǎng)脑溢,還會(huì)有多個(gè)條件語句的形式出現(xiàn)僵朗,不利于擴(kuò)展。
如果使用策略模式:
- 那么制定一個(gè)策略類InputTextField
// .h文件
@interface InputTextField : NSObject
//策略輸入 驗(yàn)證身份合法
- (BOOL)inputTextField:(UITextField *)textField;
@end
// .m文件
@implementation InputTextField
- (BOOL)inputTextField:(UITextField *)textField{
return NO;
}
@end
- Context類:CustomTextField屑彻,繼承UITextField验庙,以后在控制器,在view中通過CustomTextField進(jìn)行交互
// .h文件
#import "InputTextField.h"http://聚合關(guān)系
@interface CustomTextField : UITextField
@property (nonatomic,strong)InputTextField *inputTextField;//抽象策略類
//驗(yàn)證方法
- (BOOL)isOK;
@end
// .m文件
@implementation CustomTextField
- (BOOL)isOK{
BOOL result = [self.inputTextField inputTextField:self];
if(!result){
NSLog(@"輸入不合法");
}
return result;
}
@end
- ConcreteStrategy類:集成策略類
LetterInput:
@implementation LetterInput
- (BOOL)inputTextField:(UITextField *)textField{
// 驗(yàn)證LetterInput是否合法
}
@end
NumberInput:
@implementation NumberInput
- (BOOL)inputTextField:(UITextField *)textField{
// 驗(yàn)證NumberInput是否合法
}
@end
- 調(diào)用:
輸入框變成CustomTextField
@property (weak, nonatomic) IBOutlet CustomTextField *letterInput;//字母輸入
@property (weak, nonatomic) IBOutlet CustomTextField *numberInput;//數(shù)字輸入
初始化實(shí)際策略類
//初始化
self.letterInput.inputTextField = [LetterInput new];
self.numberInput.inputTextField = [NumberInput new];
驗(yàn)證輸入框是否合法
- (void)textFieldDidEndEditing:(UITextField *)textField{
if ([textField isKindOfClass:[CustomTextField class]]) {
[(CustomTextField *)textField isOK];
}
}
由此可看出:
1.省略了條件判斷社牲,各自的邏輯分布到各自的策略中粪薛。
2.擴(kuò)展性,假如以后需要?jiǎng)e的驗(yàn)證搏恤,那么增加策略方法- (BOOL)inputAnotherTextField:(UITextField *)textField;
违寿,Context類增加新的判斷- (BOOL)isAnotherOK;
,然后在對(duì)應(yīng)的ConcreteStrategy類添加邏輯熟空。