策略模式
- 概念:定义一系列的算法,并且将每一个算法封装起来,算法间可以互相替换.(策略模式基于固定的输出).
策略模式UML
聚合关系 Context把Stategy类引用过来,引用过来目的为了方便调stategy类的的方法(Context类引用stategy类的话,简单的说就时拥有了Stategy的属性).
stategy是抽象类,(抽象类指的是只有声明,没有实现,所有的继承都是由继承的子类contreteStrategyA,contreteStrategyB,contreteStrategyC来实现).
项目(非策略模式&策略模式对比)
- 非策略模式(写在一个controller里面实现)
@interface ViewController ()
@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 = @"只接受数字";
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){
// 验证输入值,确保它输入的是数字
NSString *outputNumber = [self validateNumberInput:textField];
if (outputNumber) {
NSLog(@"-----%@",outputNumber);
} else {
NSLog(@"--输入是空的---");
}
}
}
- (NSString *)validateLetterInput:(UITextField *)texField
{
if (texField.text.length == 0) {
return nil;
}
//用正则表达式 从开头(表示^)到结尾(表示$)有效字符集(a-zA-Z)或者是更多(*)的字符 azaaaa
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^[a-zA-Z]*$" options:NSRegularExpressionAnchorsMatchLines error:nil];
// NSMatchingAnchored 从开始处进行极限匹配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.用正则验证
// 从开头(表示^)到结尾(表示$)有效数字集(a-zA-Z)或者是更多(*)的字符 azcccc
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^[0-9]*$" options:NSRegularExpressionAnchorsMatchLines error:nil];
// NSMatchingAnchored 从开始处进行极限匹配
NSUInteger numberOfMatches = [regex numberOfMatchesInString:[textField text] options:NSMatchingAnchored range:NSMakeRange(0, [[textField text] length])];
NSString *outLatter = nil;
// 3.判断 匹配不符合表示0的话, 就走里面的漏记
if (numberOfMatches == 0) {
outLatter = @"不全是数字,输入有问题,请重新输入";
} else {
outLatter = @"输入正取,全是数字";
}
return outLatter;
}
@end
- 策略模式
1.声明抽象类InputTextFieldValidate
#import
#import
@interface InputTextFieldValidate : NSObject
- (BOOL)validateInputTextField:(UITextField *)textfeild;
@property (nonatomic, strong)NSString *attributeInputStr;
@end
#import "InputTextFieldValidate.h"
#import
@implementation InputTextFieldValidate
- (BOOL)validateInputTextField:(UITextField *)textfeild
{
return NO;
}
@end
2.定义context类与InputTextFieldValidate类成聚合关系
#import
#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;
}
//用正则表达式 从开头(表示^)到结尾(表示$)有效字符集(a-zA-Z)或者是更多(*)的字符 azaaaa
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^[a-zA-Z]*$" options:NSRegularExpressionAnchorsMatchLines error:nil];
// NSMatchingAnchored 从开始处进行极限匹配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 = @"请输入数字";
return nil;
}
// 2.用正则验证
// 从开头(表示^)到结尾(表示$)有效数字集(a-zA-Z)或者是更多(*)的字符 azcccc
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^[0-9]*$" options:NSRegularExpressionAnchorsMatchLines error:nil];
// NSMatchingAnchored 从开始处进行极限匹配
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;
}
@end
5.策略模式抽象后的viewController
#import "ViewController.h"
#import "CustomTextField.h"
#import "LatterTextFieldValidate.h"
#import "NumberTextFieldValidate.h"
@interface ViewController ()
@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 = @"只接受数字";
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
- 优点:可以精简if-else的代码,解藕性高,可复用性高.
- 缺点:知道固有的输入,在固定的场景下使用,代码量大,分类多.
demo地址:https://github.com/defuliu/StrategyPatterns