策略模式实现起来很其实简单,主要在于策略抽象采用抽象类还是协议的决策。
在这里我个人比较倾向采用抽象类,严格来说OC没有抽象类,所以可以采用“默认实现类”,只要让策略子类来覆盖它就可以了。
也就是说这个策略抽象当中的方法相当于java/C#里的virtual方法。
由于这种不严格性,就没有必要考虑协议改变时的接口版本问题。
当然,也可以通过修改默认实现,达到模板方法模式以及某种程度的AOP效果。
以一个正则校验逻辑为例子:
抽象策略:
1 #import <Foundation/Foundation.h> 2 3 @interface ValidateStrategy : NSObject 4 -(BOOL)validate:(NSString *)str; 5 @end
1 #import "ValidateStrategy.h" 2 3 @implementation ValidateStrategy 4 -(BOOL)validate:(NSString *)str { 5 return NO; 6 } 7 @end
具体策略之一:
1 #import <UIKit/UIKit.h> 2 #import "ValidateStrategy.h" 3 @interface NumberValidateStrategy : ValidateStrategy 4 -(BOOL)validate:(NSString *)str; 5 @end
1 @implementation NumberValidateStrategy 2 -(BOOL)validate:(NSString *)str{ 3 NSError *regError = nil; 4 NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^\\d+$" options:NSRegularExpressionAnchorsMatchLines error:®Error]; 5 NSUInteger numberOfMatches = [regex numberOfMatchesInString:str options:NSMatchingAnchored range:NSMakeRange(0, [str length])]; 6 return (regError == nil && numberOfMatches != 0); 7 } 8 @end
调用端:
1 - (IBAction)checkNumberBtn:(UIButton *)sender { 2 ValidateStrategy *strategy = [[NumberValidateStrategy alloc]init]; 3 4 BOOL validateResult = [strategy validate:[self.inputText text]]; 5 NSLog(@"%d", validateResult); 6 }
整体思路和在java/C#当中是一样的,具体的策略类的获取也通过依赖注入的方式获得,这里不再赘述。