zl程序教程

您现在的位置是:首页 >  移动开发

当前栏目

iOS设计模式之策略模式

2023-09-14 08:58:20 时间
面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类。 策略模式:它定义了算法家族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户。 简单工厂模式需要让客户端认识两个类,而策略模式和简单工厂结合的用法,客户端只需要认识一个类就可以了。耦合更加降低。 当不同的行为堆砌在一个类中时,就很难避免使用条件语句来选择合适的行为。将这些行为封装在一个个独立的Strategy类中,可以再使用这些行为的类中消除条件语句。 策略模式就是用来封装算法的,但在实践中,我们发现用它来封装几乎任何类型的规则,只要在分析过程中听到了需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。 在基本的策略模式中,选择所用具体实现的职责由客户端对象承担,并转给策略模式的Context对象。 面向对象软件设计中,我们可以把相关算法分离为不同的类,成为策略。 策略模式中的一个关键角色是策略类,它为所有支持的或者相关的算法声明了一个共同接口。 控制器和试图之间是一种基于策略模式的关系。 策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。
策略模式的Stategy类层次为Context定义了一些列的可供重用的算法或行为。继承有助于析取出算法中的公共功能。 策略模式的优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。 一个类在其操作中使用多个条件语句来定义许多行为。我们可以把相关的条件分支移到他们自己的策略类中 需要算法的各种变体 需要避免把复杂的、与算法相关的数据结构暴露给客户端

该例子主要利用策略模式来判断UITextField是否满足输入要求,比如输入的只能是数字,如果只是数字就没有提示,如果有其他字符则提示出错。验证字母也是一样。
首先,我们先定义一个抽象的策略类IputValidator。代码如下:
InputValidator.h

 // // InputValidator.h // StrategyDemo // // Created by zhanggui on 15/8/7. // Copyright (c) 2015年 zhanggui. All rights reserved. // #import Foundation/Foundation.h #import UIKit/UIKit.h static NSString * const InputValidationErrorDomain = @"InputValidationErrorDomain";

@interface InputValidator : NSObject //实际验证策略的存根方法

-(BOOL)validateInput:(UITextField *)input error:(NSError **)error;

@end

InputValidator.m

// // InputValidator.m // StrategyDemo // // Created by zhanggui on 15/8/7. // Copyright (c) 2015年 zhanggui. All rights reserved. // #import "InputValidator.h" @implementation InputValidator


@end

这个就是一个策略基类,然后我们去创建两个子类NumericInputValidator和AlphaInputValidator。具体代码如下:
NumericIputValidator.h

// // NumericInputValidator.h // StrategyDemo // // Created by zhanggui on 15/8/7. // Copyright (c) 2015年 zhanggui. All rights reserved. // #import "InputValidator.h" @interface NumericInputValidator : InputValidator

-(BOOL)validateInput:(UITextField *)input error:(NSError **)error;

@end

NumericIputValidator.m

// // NumericInputValidator.m // StrategyDemo // // Created by zhanggui on 15/8/7. // Copyright (c) 2015年 zhanggui. All rights reserved. // #import "NumericInputValidator.h" @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: regError];


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 *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.h

// // AlphaInputValidator.h // StrategyDemo // // Created by zhanggui on 15/8/7. // Copyright (c) 2015年 zhanggui. All rights reserved. // #import "InputValidator.h" @interface AlphaInputValidator : InputValidator

- (BOOL)validateInput:(UITextField *)input error:(NSError **)error;

@end

AlphaInputValidator.m

// // AlphaInputValidator.m // StrategyDemo // // Created by zhanggui on 15/8/7. // Copyright (c) 2015年 zhanggui. All rights reserved. // #import "AlphaInputValidator.h" @implementation AlphaInputValidator

-(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: regError];


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 *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

他们两个都是InputValidator的子类。然后再定义一个CustomTextField:
CustomTextField.h

// // CustomTextField.h // StrategyDemo // // Created by zhanggui on 15/8/7. // Copyright (c) 2015年 zhanggui. All rights reserved. // #import UIKit/UIKit.h @class InputValidator; @interface CustomTextField : UITextField @property(nonatomic,strong)InputValidator *inputValidator;

-(BOOL)validate;

@end

CustomTextField.m

// // CustomTextField.m // StrategyDemo // // Created by zhanggui on 15/8/7. // Copyright (c) 2015年 zhanggui. All rights reserved. // #import "CustomTextField.h" #import "InputValidator.h" @implementation CustomTextField


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

最后在ViewController中测试是否完成验证
ViewController.m

// // ViewController.m // StrategyDemo // // Created by zhanggui on 15/8/7. // Copyright (c) 2015年 zhanggui. All rights reserved. // #import "ViewController.h" #import "CustomTextField.h" #import "NumericInputValidator.h" #import "AlphaInputValidator.h" @interface ViewController () @end @implementation ViewController

- (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

结果:当我们输入的不满足条件的时候就会显示提示信息,而满足条件就不会有任何提示。


淘宝iOS扫一扫架构升级 - 设计模式的应用 本文在“扫一扫功能的不断迭代,基于设计模式的基本原则,逐步采用设计模式思想进行代码和架构优化”的背景下,对设计模式在扫一扫中新的应用进行了总结。
1.外观模式简介 外观模式(Facade)在开发过程中的运用频率非常高,尤其是在现阶段各种第三方SDK充斥在我们的周边,而这些SDK很大概率会使用外观模式。
模型-视图-控制器(Model-View-Controller,MVC)是Xerox PARC在20世纪80年代为编程语言Smalltalk-80发明的一种软件设计模式,至今已广泛应用于用户交互应用程序中。
建议45:设计模式是特定环境下的特定问题的解决方案 设计模式是某种特定设计的模板或指导原则。 建议46:MVC模式是一种复合或聚合模式 MVC 是一种高级别的模式,关注的是应用程序的全局架构,并根据各种对象在程序中发挥的作用对其进行分类。