iOS策略设计模式实践

栏目: 后端 · 发布时间: 6年前

内容简介:情景:把一堆算法塞到同一段代码中,然后使用策略模式的使用可以粗暴的分为3个角色。它们的静态关系如下图所示:

情景:把一堆算法塞到同一段代码中,然后使用 if-else 或者 switch-case 条件语句来决定要使用哪个算法?这些算法可能是一堆相似的类函数或方法,用以解决相关的问题。例如验证数据输入的情形,数据本身可以是任何数据类型(如CGFloat,NSString,NSInteger等),每种数据类型需要不同的算法。如果把每一种算法封装成一个对象,那么就能消除根据数据类型决定使用什么算法的一堆 if-elseswitch-case 语句。 面向对象软件设计中,我们可以把相关算法分离为不同的类,成为策略,对应的 设计模式 称为策略模式。

何为策略模式

策略模式的使用可以粗暴的分为3个角色。

  1. 策略类,或者定义为策略接口、策略协议,它为所有支持的或相关的算法声明了一个共同接口。
  2. 策略对象:它会实现策略协议,策略对象通常存在多个,分别封装实现具体的算法。
  3. 场景(context)类对象:配置有一个具体策略对象的示例,场景对象使用策略接口调用由具体策略类定义的算法。

它们的静态关系如下图所示:

iOS策略设计模式实践

一组算法,或者说算法的一个层次结构,以ConcreteStrategy(A、B和C)类的形式,共享相同的AlgorithmInterface接口,这样Context就能使用相同的接口访问算法的各种变体。

Context的实例可以在运行时用不同的ConcreteStrategy对象进行配置,这可以理解成更换context对象的『内容』,因为变更是发生在对象的内部。

何时使用策略模式

在以下情形,考虑使用策略模式。

  • 一个类在其操作中使用多个条件语句来定义许多行为,我们可以把相关的条件分支移动到它们自己的策略类中。
  • 需要算法的各种变体。
  • 需要避免把复杂的、与算法相关的数据结构暴露给客户端。

在UITextField中应用策略模式

类图设计如下图所示:

iOS策略设计模式实践

策略接口

这里策略类抽象了两个接口:

@protocol ACITextFieldInputValidator <NSObject>

- (BOOL)validateInput:(UITextField *)textField
    charactersInRange:(NSRange)range
    replacementString:(NSString *)string
                error:(NSError **)error;

- (BOOL)validateEndEditingInput:(UITextField *)textField error:(NSError **)error;

@end

其中

- (BOOL)validateInput:(UITextField *)textField
    charactersInRange:(NSRange)range
    replacementString:(NSString *)string
                error:(NSError **)error;

在UITextFieldDelegate的 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 方法中进行验证。

- (BOOL)validateEndEditingInput:(UITextField *)textField error:(NSError **)error; 在UITextFieldDelegate的 - (void)textFieldDidEndEditing:(UITextField *)textField 方法中进行验证。

这里特殊说明一下:

接口中使用UITextField作为入参而不是使用NSString作为入参,是因为如果只用NSString值,那么策略对象中的动作就是单向的。就是说,验证器只能检查,然后返回结果,而不能修改原始值。而使用UITextField型的输入参数,就可以两全其美。验证器可以选择修改文本框的原始值(比如删除无效的值),或者只检查而不修改。

另一个问题是,如果输入值错误,为什么不引发一个NSException异常呢?这是因为在Cocoa Touch框架中,引发自己的异常然后再用 try-catch 语句块来捕捉,这非常耗资源,所以不推荐,返回NSError对象的开销相对较小。

场景

这里使用策略的场景是UITextField,在UITextField的子类InputValidateTextField中,声明一个遵循策略协议的对象属性。

@interface ACIInputValidateTextField : UITextField

@property (nonatomic, strong) id<ACITextFieldInputValidator> inputValidator;

- (BOOL)validateCharactersInRange:(NSRange)range
                replacementString:(NSString *)string
                            error:(NSError **)error;

- (BOOL)validateEndEditingWithError:(NSError **)error;

@end

同时,场景对象中会声明方法来处理调用策略对象的接口方法。具体示例如下:

@implementation ACIInputValidateTextField

- (BOOL)validateCharactersInRange:(NSRange)range
                replacementString:(NSString *)string
                            error:(NSError **)error {
    
    BOOL shouldChange = [self.inputValidator validateInput:self charactersInRange:range replacementString:string error:error];
    return shouldChange;
}

- (BOOL)validateEndEditingWithError:(NSError **)error {
    BOOL isValid = [self.inputValidator validateEndEditingInput:self error:error];
    return isValid;
}

@end

策略对象

策略对象,这里是遵循了策略协议的 TextFieldInputValidator 的对象。每个对象会实现TextFieldInputValidator的方法,其中封装了具体的策略实现。

具体代码示例详见 github InputValidator

如果觉得本文对你有帮助,就请用微信随意打赏我吧^_^

iOS策略设计模式实践


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

安全测试指南(第4版)

安全测试指南(第4版)

OWASP基金会 / 电子工业出版社 / 2016-7-1 / CNY 89.00

软件安全问题也许是这个时代面临的*为重要的技术挑战。Web应用程序让业务、社交等网络活动飞速发展,这同时也加剧了它们对软件安全的要求。我们急需建立一个强大的方法来编写和保护我们的互联网、Web应用程序和数据,并基于工程和科学的原则,用一致的、可重复的和定义的方法来测试软件安全问题。本书正是实现这个目标的重要一步,作为一本安全测试指南,详细讲解了Web应用测试的“4W1H”,即“什么是测试”、“为什......一起来看看 《安全测试指南(第4版)》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

URL 编码/解码
URL 编码/解码

URL 编码/解码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具