Objective-C编程之道 iOS设计模式解析
iOS设计模式解析-工厂模式
iOS设计模式解析-抽象工厂模式
iOS设计模式解析-外观模式
iOS设计模式解析-中介者模式
iOS设计模式解析-观察者模式
iOS设计模式解析-装饰模式
iOS设计模式解析-责任链模式
iOS设计模式解析-模板方法
iOS设计模式解析-策略模式
iOS设计模式解析-享元模式
iOS设计模式解析-代码地址
何为策略模式
策略模式中的一个关键角色是策略类,它为所有支持的或相关的算法声明了一个共同接口。另外,还有使用策略接口来实现相关算法的具体策略类,场景类的对象配置有一个具体策略对象的实例,场景对象使用策略接口调用由具体策略类定义的算法。
何时使用策略模式
在以下情形,自然会考虑使用这一模式。
- 一个类在其操作中使用多个条件语句来定义许多行为,我们可以把相关的条件分支移到它们自己的策略类中。
- 需要算法的各种变体。
- 需要避免把复杂的,与算法相关的数据结构暴露给客户端。
在UITextField中应用验证策略
创建InputValidator类
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
static NSString * const InputValidationErrorDomain = @"InputValidationErrorDomain";
@interface InputValidator : NSObject
// A stub for any actual validation strategy
- (BOOL) validateInput:(UITextField *)input error:(NSError **) error;
@end
#import "InputValidator.h"
@implementation InputValidator
// A stub for any actual validation strategy
- (BOOL) validateInput:(UITextField *)input error:(NSError **) error
{
if (error)
{
*error = nil;
}
return NO;
}
@end
创建CustomTextField类继承UITextField
#import <Foundation/Foundation.h>
#import "InputValidator.h"
@interface CustomTextField : UITextField
@property (nonatomic, strong) InputValidator *inputValidator;
- (BOOL) validate;
@end
#import "CustomTextField.h"
@implementation CustomTextField
- (BOOL) validate
{
NSError *error = nil;
BOOL validationResult = [_inputValidator validateInput:self error:&error];
if (!validationResult)
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[error localizedDescription]
message:[error localizedFailureReason]
delegate:nil
cancelButtonTitle:NSLocalizedString(@"OK", @"")
otherButtonTitles:nil];
[alertView show];
}
return validationResult;
}
@end
创建NumericInputValidator继承InputValidator(只能输入数字算法)
#import <Foundation/Foundation.h>
#import "InputValidator.h"
@interface NumericInputValidator : InputValidator
// A validation method that makes sure the input only contains
// numbers i.e. 0-9
- (BOOL) validateInput:(UITextField *)input error:(NSError **) error;
@end
#import "NumericInputValidator.h"
@implementation NumericInputValidator
- (BOOL) validateInput:(UITextField *)input error:(NSError**) error
{
NSError *regError = nil;
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:@"^[0-9]*$"
options:NSRegularExpressionAnchorsMatchLines
error:®Error];
NSUInteger numberOfMatches = [regex
numberOfMatchesInString:[input text]
options:NSMatchingAnchored
range:NSMakeRange(0, [[input text] length])];
// if there is not a single match
// then return an error and NO
if (numberOfMatches == 0)
{
if (error != nil)
{
NSString *description = NSLocalizedString(@"Input Validation Failed", @"");
NSString *reason = NSLocalizedString(@"The input can only contain numerical values", @"");
NSArray *objArray = [NSArray arrayWithObjects:description, reason, nil];
NSArray *keyArray = [NSArray arrayWithObjects:NSLocalizedDescriptionKey,
NSLocalizedFailureReasonErrorKey, nil];
NSDictionary *userInfo = [NSDictionary dictionaryWithObjects:objArray
forKeys:keyArray];
*error = [NSError errorWithDomain:InputValidationErrorDomain
code:1001
userInfo:userInfo];
}
return NO;
}
return YES;
}
@end
创建AlphaInputValidator继承InputValidator(只能输入字母算法)
#import <Foundation/Foundation.h>
#import "InputValidator.h"
@interface AlphaInputValidator : InputValidator
// A validation method that makes sure the input only
// contains letters only i.e. a-z A-Z
- (BOOL) validateInput:(UITextField *)input error:(NSError **) error;
@end
#import "AlphaInputValidator.h"
@implementation AlphaInputValidator
- (BOOL) validateInput:(UITextField *)input error:(NSError **) error
{
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:@"^[a-zA-Z]*$"
options:NSRegularExpressionAnchorsMatchLines
error:nil];
NSUInteger numberOfMatches = [regex
numberOfMatchesInString:[input text]
options:NSMatchingAnchored
range:NSMakeRange(0, [[input text] length])];
// If there is not a single match
// then return an error and NO
if (numberOfMatches == 0)
{
if (error != nil)
{
NSString *description = NSLocalizedString(@"Input Validation Failed", @"");
NSString *reason = NSLocalizedString(@"The input can only contain letters", @"");
NSArray *objArray = [NSArray arrayWithObjects:description, reason, nil];
NSArray *keyArray = [NSArray arrayWithObjects:NSLocalizedDescriptionKey,
NSLocalizedFailureReasonErrorKey, nil];
NSDictionary *userInfo = [NSDictionary dictionaryWithObjects:objArray
forKeys:keyArray];
*error = [NSError errorWithDomain:InputValidationErrorDomain
code:1002
userInfo:userInfo];
}
return NO;
}
return YES;
}
@end
主类调用
#import "ViewController.h"
#import "CustomTextField.h"
#import "AlphaInputValidator.h"
#import "NumericInputValidator.h"
@interface ViewController ()<UITextFieldDelegate>
@property (nonatomic, strong) CustomTextField *numericTextField;
@property (nonatomic, strong) CustomTextField *alphaTextField;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor redColor];
_numericTextField = [[CustomTextField alloc] initWithFrame:CGRectMake(100, 100, 100, 30)];
_numericTextField.backgroundColor = [UIColor blueColor];
_numericTextField.delegate = self;
_numericTextField.inputValidator = [[NumericInputValidator alloc]init];
_numericTextField.placeholder = @"_numericTextField";
_numericTextField.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
_numericTextField.font = [UIFont systemFontOfSize:16.f];
_numericTextField.textColor = [UIColor whiteColor];
[self.view addSubview:_numericTextField];
_alphaTextField = [[CustomTextField alloc] initWithFrame:CGRectMake(100, 200, 100, 30)];
_alphaTextField.inputValidator = [[AlphaInputValidator alloc]init];
_alphaTextField.backgroundColor = [UIColor blueColor];
_alphaTextField.placeholder = @"_alphaTextField";
_alphaTextField.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
_alphaTextField.font = [UIFont systemFontOfSize:16.f];
_alphaTextField.delegate = self;
_alphaTextField.textColor = [UIColor whiteColor];
[self.view addSubview:_alphaTextField];
}
#pragma mark -
#pragma mark UITextFieldDelegate methods
- (void)textFieldDidEndEditing:(UITextField *)textField
{
if ([textField isKindOfClass:[CustomTextField class]])
{
[(CustomTextField*)textField validate];
}
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[self.view endEditing:YES];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
注意(这俩句代码很重要)
_numericTextField.inputValidator = [[NumericInputValidator alloc]init];
_alphaTextField.inputValidator = [[AlphaInputValidator alloc]init];
策略模式的优缺点
优点:
- 提供了管理相关的算法族的办法。可以封装一些算法,不想让算法直接暴露出来。
- 可以避免使用多重条件转移语句,消除根据类型决定使用什么算法的一些if-else的语句。
缺点:
- 使用之前必须知道所有的策略,使用中不能动态改变,在实例话的时候就设定好需要使用的策略类了。
网友评论