iOS设计模式之策略模式
策略模式(Strategy)
基本理解
- 面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类。
- 策略模式:它定义了算法家族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户。
- 简单工厂模式需要让客户端认识两个类,而策略模式和简单工厂结合的用法,客户端只需要认识一个类就可以了。耦合更加降低。
- 当不同的行为堆砌在一个类中时,就很难避免使用条件语句来选择合适的行为。将这些行为封装在一个个独立的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
-(BOOL)validateInput:(UITextField *)input error:(NSError **)error
{
if (error) {
*error = nil;
}
return NO;
}
@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:®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
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:®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
他们两个都是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
-(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
最后在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设计模式之策略模式的更多相关文章
- 设计模式:策略模式(Strategy)
定 义:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化, 不会影响到使用算法的客户. 示例:商场收银系统,实现正常收费.满300返100.打8折.......等不同收费 ...
- iOS 设计模式之工厂模式
iOS 设计模式之工厂模式 分类: 设计模式2014-02-10 18:05 11020人阅读 评论(2) 收藏 举报 ios设计模式 工厂模式我的理解是:他就是为了创建对象的 创建对象的时候,我们一 ...
- PHP设计模式之策略模式
前提: 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能.如查 找.排序等,一种常用的方法是硬编码(Hard Cod ...
- JavaScript设计模式之策略模式(学习笔记)
在网上搜索“为什么MVC不是一种设计模式呢?”其中有解答:MVC其实是三个经典设计模式的演变:观察者模式(Observer).策略模式(Strategy).组合模式(Composite).所以我今天选 ...
- 乐在其中设计模式(C#) - 策略模式(Strategy Pattern)
原文:乐在其中设计模式(C#) - 策略模式(Strategy Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 策略模式(Strategy Pattern) 作者:webabc ...
- JavaScript设计模式之策略模式
所谓"条条道路通罗马",在现实中,为达到某种目的往往不是只有一种方法.比如挣钱养家:可以做点小生意,可以打分工,甚至还可以是偷.抢.赌等等各种手段.在程序语言设计中,也会遇到这种类 ...
- 【设计模式】【应用】使用模板方法设计模式、策略模式 处理DAO中的增删改查
原文:使用模板方法设计模式.策略模式 处理DAO中的增删改查 关于模板模式和策略模式参考前面的文章. 分析 在dao中,我们经常要做增删改查操作,如果每个对每个业务对象的操作都写一遍,代码量非常庞大. ...
- [design-patterns]设计模式之一策略模式
设计模式 从今天开始开启设计模式专栏,我会系统的分析和总结每一个设计模式以及应用场景.那么首先,什么是设计模式呢,作为一个软件开发人员,程序人人都会写,但是写出一款逻辑清晰,扩展性强,可维护的程序就不 ...
- 设计模式入门,策略模式,c++代码实现
// test01.cpp : Defines the entry point for the console application.////第一章,设计模式入门,策略模式#include &quo ...
随机推荐
- 没有找到cxcore100.dll,因此这个应用程序未能启动,重新安装应用程序可能会修复此问题
第一种情况: 出现这个问题多数是因为“环境变量PATH”未设置,虽然你可能在安装的过程中勾选了Add <...>\OpenCV\bin to the system PATH项!安装Open ...
- FLEX自定义事件
有时候我们需要让两个组件之间实现联动,并且在其中传递数据,自定义事件机制可以帮助我们比较优雅的实现这种需要. 下面的例子,是打算实现一个列表和一个编辑框的联动. 编辑框代码 <?xml vers ...
- Weblogic 10.3.6生产模式启动
生产模式启动里需要输入用户名和密码,很麻烦.在域的/security目录下创建文件boot.properties,内容为: username=weblogic password=weblogic123 ...
- WPF中多个RadioButton绑定到一个属性
如图样: 在View中: <RadioButton IsChecked="{Binding Option, Converter={cvt:EnumToBooleanConverter} ...
- Mybatis对MySQL中BLOB字段的读取
1.在sqlMapConfig中,定义一个typeHandlers <typeHandlers> <typeHandler jdbcType="BLOB" jav ...
- LoRaWAN移植笔记(一)__RTC闹钟链表的实现
近日在阅读semtech的Lora-net/LoRaMac-node.此代码是LoRaWAN MAC层的node段的代码. 此代码中构建了一个定时器链表,此链表构建得非常的巧妙,现在和大家分享. 此定 ...
- 前端技术Bootstrap的hello world
----对于用户来说,界面就是程序本身.那么一个漂亮的web一定是你继续使用这个应用的前题. 这一节我们来一起写个Bootstrap的hello wrold. Bootstrap Bootstrap ...
- Vex – 超轻量!可以轻松自定义的现代风格弹窗插件
Vex 的独特之处在于现代风格设计,能够自定义弹出模式.皮肤.Vex 超轻量,压缩后不到 2KB,提供了简洁的 API,可以根据自己的项目需要快速自定义.支持在移动设备上使用,测试通过的浏览器:IE8 ...
- Java魔法堂:注释和注释模板
一.注释 1. 注释类型 [a]. 单行注释 // 单行注释 String type = "单行注释"; [b]. 多行注释 /* * 多行注释 */ String type ...
- Cookie 和 Session 的区别
[[ from 老生常谈session,cookie的区别,安全性 ]] 一,为什么session,cookie经常会有人提到 做web开发的人基本上都会用session和cookie,但是仅仅只是会 ...