易发19119存10送20,木乃伊魔咒,小姐待字闺中gl
策略模式是一种常见的软件设计模式,这里简单得介绍一下策略模式并用ios简单实现一下。
所谓的策略模式,顾名思义是要采用不同的策略的。一般来说,在不同的情况下,处理某一个问题的方法也不一样。比如说对字符串的排序和对数字的排序,虽然用的都是快排,但是显然不可能使用一段通用的代码。有人说java里面的compareto可以做到,但如果考虑这么一个问题:同样是出门旅行,老年人身体虚弱,需要大量的休息,而孩子则是精力充沛,希望玩到更多的景点。如何在同一模式下表达以上信息、采用合理的设计模式进行封装而不是大量重写类似的代码,就需要学习并采用策略模式。
例子
该例子主要利用策略模式来判断uitextfield是否满足输入要求,比如输入的只能是数字,如果只是数字就没有提示,如果有其他字符则提示出错。验证字母也是一样。
首先,我们先定义一个抽象的策略类iputvalidator。代码如下:
inputvalidator.h
static nsstring * const inputvalidationerrordomain = @"inputvalidationerrordomain";
@interface inputvalidator : nsobject
//实际验证策略的存根方法
-(bool)validateinput:(uitextfield *)input error:(nserror **)error;
@end
#import "inputvalidator.h"
@implementation inputvalidator
-(bool)validateinput:(uitextfield *)input error:(nserror **)error
{
if (error) {
*error = nil;
}
return no;
}
@end
#import "inputvalidator.h"
@interface numericinputvalidator : inputvalidator
-(bool)validateinput:(uitextfield *)input error:(nserror **)error;
@end
@implementation numericinputvalidator
-(bool)validateinput:(uitextfield *)input error:(nserror **)error
{
nserror *regerror = nil;
//使用配置的nsregularexpression对象,检查文本框中数值型的匹配次数。
//^[0-9]*$:意思是从行的开头(表示为^)到结尾(表示为$)应该有数字集(标示为[0-9])中的0或者更多个字符(表示为*)
nsregularexpression *regex = [nsregularexpression regularexpressionwithpattern:@"^[0-9]*$" options:nsregularexpressionanchorsmatchlines error:®error];
nsuinteger numberofmatches = [regex numberofmatchesinstring:[input text] options:nsmatchinganchored range:nsmakerange(0, [[input text] length])];
//如果没有匹配,就返回错误和no
if (numberofmatches==0) {
if (error != nil) {
nsstring *description = nslocalizedstring(@"input validation faild", @"");
nsstring *reason = nslocalizedstring(@"the input can contain only 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
@interface alphainputvalidator : inputvalidator
- (bool)validateinput:(uitextfield *)input error:(nserror **)error;
@end
-(bool)validateinput:(uitextfield *)input error:(nserror **)error
{
nserror *regerror = nil;
//使用配置的nsregularexpression对象,检查文本框中数值型的匹配次数。
//^[0-9]*$:意思是从行的开头(表示为^)到结尾(表示为$)应该有数字集(标示为[0-9])中的0或者更多个字符(表示为*)
nsregularexpression *regex = [nsregularexpression regularexpressionwithpattern:@"^[a-za-z]*$" options:nsregularexpressionanchorsmatchlines error:®error];
nsuinteger numberofmatches = [regex numberofmatchesinstring:[input text] options:nsmatchinganchored range:nsmakerange(0, [[input text] length])];
//如果没有匹配,就返回错误和no
if (numberofmatches==0) {
if (error != nil) {
nsstring *description = nslocalizedstring(@"input validation faild", @"");
nsstring *reason = nslocalizedstring(@"the input can contain only 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
@property(nonatomic,strong)inputvalidator *inputvalidator;
-(bool)validate;
@end
#import "customtextfield.h"
#import "inputvalidator.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
@end
- (void)viewdidload {
[super viewdidload];
_numbertextfield.inputvalidator = [numericinputvalidator new];
_lettertextfield.inputvalidator = [alphainputvalidator new];
// do any additional setup after loading the view, typically from a nib.
}
- (void)didreceivememorywarning {
[super didreceivememorywarning];
// dispose of any resources that can be recreated.
}
#pragma mark - validbuttonmehtod
- (ibaction)validnumaction:(id)sender {
[_numbertextfield validate];
}
- (ibaction)validletteraction:(id)sender {
[_lettertextfield validate];
}
@end
优点
使用场景
总结
再总结一下策略方法的实现,本质上就是需要完成一个事情(出行),但是并不清楚需要使用怎样的策略,所以封装出一个函数,能够把需要的策略(young or old)作为参数传递进来,并且使用相应的策略完成这个事件的处理。
最后简单谈一谈个人对于策略模式和面向对象中多态的思想的理解,首先多态是高层次,高度抽象的概念,独立于语言之外,是面向对象思想的精髓,而策略模式只是一种软件设计模式,相对而言更加具体,而且具体实现依赖于具体的编程语言,比如oc和java的实现方法并不相同,是language-dependent的。其次,多态更多强调的是,不同的对象调用同一个方法会得到不同的结果,而策略模式更多强调的是,同一个对象(事实上这个对象本身并不重要)在不同情况下执行不同的方法,而他们的实现方式又是高度类似的,即共享同一个父类并且各自重写父类的方法。
以上观点纯属个人愚见,欢迎大牛指正,互相交流。
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
iOS 使用UITextField自定义搜索框 实现用户输入完之后“实时搜索”功能
网友评论