策略模式
- 概念:定義一系列的算法姑丑,并且將每一個算法封裝起來,算法間可以互相替換.(策略模式基于固定的輸出).
策略模式UML
F3BE4105-4849-4ABD-B7D5-B9758A9B9585.png
F3BE4105-4849-4ABD-B7D5-B9758A9B9585.png
聚合關(guān)系 Context把Stategy類引用過來辞友,引用過來目的為了方便調(diào)stategy類的的方法(Context類引用stategy類的話栅哀,簡單的說就時擁有了Stategy的屬性).
stategy是抽象類,(抽象類指的是只有聲明称龙,沒有實(shí)現(xiàn)留拾,所有的繼承都是由繼承的子類contreteStrategyA,contreteStrategyB鲫尊,contreteStrategyC來實(shí)現(xiàn)).
項目(非策略模式&策略模式對比)
- 非策略模式(寫在一個controller里面實(shí)現(xiàn))
@interface ViewController ()<UITextFieldDelegate>
@property(nonatomic, strong)UITextField *letterInput;
@property(nonatomic, strong)UITextField *numberInput;
@property(nonatomic, strong)UIButton *printBtn;
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.letterInput = [[UITextField alloc] initWithFrame:CGRectMake(10,100,self.view.frame.size.width - 2*10 , 40)];
self.letterInput.placeholder = @"只接受字母";
self.letterInput.delegate = self;
self.letterInput.layer.borderWidth = 1;
[self.view addSubview: self.letterInput];
self.numberInput = [[UITextField alloc] initWithFrame:CGRectMake(10,170,self.view.frame.size.width - 2*10 , 40)];
self.numberInput.placeholder = @"只接受數(shù)字";
self.numberInput.layer.borderWidth = 1;
self.numberInput.delegate = self;
[self.view addSubview: self.numberInput];
self.printBtn = [[UIButton alloc] initWithFrame:CGRectMake(10, 240, self.view.frame.size.width - 2*10, 40)];
self.printBtn.backgroundColor = [UIColor redColor];
[self.printBtn setTitle:@"測試" forState:UIControlStateNormal];
[self.printBtn addTarget:self action:@selector(action:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.printBtn];
}
- (void)action:(UIButton *)sender
{
[self.view endEditing:YES];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
if (textField == self.letterInput) {
// 驗證輸入值,確保它輸入的是字母
NSString *outputLatter = [self validateLetterInput:textField];
if (outputLatter) {
NSLog(@"-----%@",outputLatter);
} else {
NSLog(@"--輸入是空的---");
}
}
else if (textField == self.numberInput){
// 驗證輸入值,確保它輸入的是數(shù)字
NSString *outputNumber = [self validateNumberInput:textField];
if (outputNumber) {
NSLog(@"-----%@",outputNumber);
} else {
NSLog(@"--輸入是空的---");
}
}
}
- (NSString *)validateLetterInput:(UITextField *)texField
{
if (texField.text.length == 0) {
return nil;
}
//用正則表達(dá)式 從開頭(表示^)到結(jié)尾(表示$)有效字符集(a-zA-Z)或者是更多(*)的字符 azaaaa
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^[a-zA-Z]*$" options:NSRegularExpressionAnchorsMatchLines error:nil];
// NSMatchingAnchored 從開始處進(jìn)行極限匹配r
NSUInteger numberOfMatches = [regex numberOfMatchesInString:[texField text] options:NSMatchingAnchored range:NSMakeRange(0, [texField.text length])];
NSString *outLatter = nil;
// 3.判斷 匹配不符合表示0的話, 就走里面的漏記
if (numberOfMatches == 0) {
outLatter = @"不全是字母,輸入有問題,請重新輸入";
} else {
outLatter = @"輸入正取,全是字母";
}
return outLatter;
}
- (NSString *)validateNumberInput:(UITextField *)textField
{
// 1.判斷沒有輸入就返回
if(textField.text.length == 0) {
return nil;
}
// 2.用正則驗證
// 從開頭(表示^)到結(jié)尾(表示$)有效數(shù)字集(a-zA-Z)或者是更多(*)的字符 azcccc
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^[0-9]*$" options:NSRegularExpressionAnchorsMatchLines error:nil];
// NSMatchingAnchored 從開始處進(jìn)行極限匹配
NSUInteger numberOfMatches = [regex numberOfMatchesInString:[textField text] options:NSMatchingAnchored range:NSMakeRange(0, [[textField text] length])];
NSString *outLatter = nil;
// 3.判斷 匹配不符合表示0的話, 就走里面的漏記
if (numberOfMatches == 0) {
outLatter = @"不全是數(shù)字,輸入有問題,請重新輸入";
} else {
outLatter = @"輸入正取,全是數(shù)字";
}
return outLatter;
}
@end
- 策略模式
1.聲明抽象類InputTextFieldValidate
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface InputTextFieldValidate : NSObject
- (BOOL)validateInputTextField:(UITextField *)textfeild;
@property (nonatomic, strong)NSString *attributeInputStr;
@end
#import "InputTextFieldValidate.h"
#import <UIKit/UIKit.h>
@implementation InputTextFieldValidate
- (BOOL)validateInputTextField:(UITextField *)textfeild
{
return NO;
}
@end
2.定義context類與InputTextFieldValidate類成聚合關(guān)系
#import <UIKit/UIKit.h>
#import "InputTextFieldValidate.h"
@interface CustomTextField : UITextField
@property(nonatomic, strong)InputTextFieldValidate *inputValidate;
//驗證方法
- (BOOL)validate;
@end
#import "CustomTextField.h"
@implementation CustomTextField
- (BOOL)validate
{
BOOL result = [self.inputValidate validateInputTextField:self];
return result;
}
@end
3.繼承InputTextFieldValidate的子類:LatterTextFieldValidate
#import "InputTextFieldValidate.h"
@interface LatterTextFieldValidate : InputTextFieldValidate
@end
#import "LatterTextFieldValidate.h"
@implementation LatterTextFieldValidate
- (BOOL)validateInputTextField:(UITextField *)textField
{
if (textField.text.length == 0) {
self.attributeInputStr = @"請輸入字符";
return self.attributeInputStr;
}
//用正則表達(dá)式 從開頭(表示^)到結(jié)尾(表示$)有效字符集(a-zA-Z)或者是更多(*)的字符 azaaaa
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^[a-zA-Z]*$" options:NSRegularExpressionAnchorsMatchLines error:nil];
// NSMatchingAnchored 從開始處進(jìn)行極限匹配r
NSUInteger numberOfMatches = [regex numberOfMatchesInString:[textField text] options:NSMatchingAnchored range:NSMakeRange(0, [textField.text length])];
// 3.判斷 匹配不符合表示0的話, 就走里面的漏記
if (numberOfMatches == 0) {
self.attributeInputStr = @"不全是字母,輸入有問題,請重新輸入";
} else {
self.attributeInputStr = @"輸入正取,全是字母";
}
return self.attributeInputStr==nil?YES:NO;
}
4.繼承NumberTextFieldValidate的子類:NumberTextFieldValidate
#import "InputTextFieldValidate.h"
@interface NumberTextFieldValidate : InputTextFieldValidate
@end
#import "NumberTextFieldValidate.h"
@implementation NumberTextFieldValidate
- (BOOL)validateInputTextField:(UITextField *)textField
{
// 1.判斷沒有輸入就返回
if(textField.text.length == 0) {
self.attributeInputStr = @"請輸入數(shù)字";
return nil;
}
// 2.用正則驗證
// 從開頭(表示^)到結(jié)尾(表示$)有效數(shù)字集(a-zA-Z)或者是更多(*)的字符 azcccc
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^[0-9]*$" options:NSRegularExpressionAnchorsMatchLines error:nil];
// NSMatchingAnchored 從開始處進(jìn)行極限匹配
NSUInteger numberOfMatches = [regex numberOfMatchesInString:[textField text] options:NSMatchingAnchored range:NSMakeRange(0, [[textField text] length])];
// 3.判斷 匹配不符合表示0的話, 就走里面的漏記
if (numberOfMatches == 0) {
self.attributeInputStr = @"不全是數(shù)字,輸入有問題,請重新輸入";
} else {
self.attributeInputStr = @"輸入正取,全是數(shù)字";
}
return self.attributeInputStr==nil?YES:NO;
}
@end
5.策略模式抽象后的viewController
#import "ViewController.h"
#import "CustomTextField.h"
#import "LatterTextFieldValidate.h"
#import "NumberTextFieldValidate.h"
@interface ViewController ()<UITextFieldDelegate>
@property(nonatomic, strong)CustomTextField *letterInput;
@property(nonatomic, strong)CustomTextField *numberInput;
@property(nonatomic, strong)UIButton *printBtn;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.letterInput = [[CustomTextField alloc] initWithFrame:CGRectMake(10,100,self.view.frame.size.width - 2*10 , 40)];
self.letterInput.placeholder = @"只接受字母";
self.letterInput.delegate = self;
self.letterInput.layer.borderWidth = 1;
[self.view addSubview: self.letterInput];
self.numberInput = [[CustomTextField alloc] initWithFrame:CGRectMake(10,170,self.view.frame.size.width - 2*10 , 40)];
self.numberInput.placeholder = @"只接受數(shù)字";
self.numberInput.layer.borderWidth = 1;
self.numberInput.delegate = self;
[self.view addSubview: self.numberInput];
self.printBtn = [[UIButton alloc] initWithFrame:CGRectMake(10, 240, self.view.frame.size.width - 2*10, 40)];
self.printBtn.backgroundColor = [UIColor redColor];
[self.printBtn setTitle:@"測試" forState:UIControlStateNormal];
[self.printBtn addTarget:self action:@selector(action:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.printBtn];
self.letterInput.inputValidate = [LatterTextFieldValidate new];
self.numberInput.inputValidate = [NumberTextFieldValidate new];
}
- (void)action:(UIButton *)sender
{
[self.view endEditing:YES];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
if ([textField isKindOfClass:[CustomTextField class]]) {
[(CustomTextField *)textField validate];
}
}
@end
- 優(yōu)點(diǎn):可以精簡if-else的代碼痴柔,解藕性高,可復(fù)用性高.
- 缺點(diǎn):知道固有的輸入,在固定的場景下使用疫向,代碼量大咳蔚,分類多.
demo地址:https://github.com/defuliu/StrategyPatterns