举例讲解iOS应用开发中对设计模式中的策略模式的使用_IOS

策略模式是一种常见的软件设计模式,这里简单得介绍一下策略模式并用IOS简单实现一下。
所谓的策略模式,顾名思义是要采用不同的策略的。一般来说,在不同的情况下,处理某一个问题的方法也不一样。比如说对字符串的排序和对数字的排序,虽然用的都是快排,但是显然不可能使用一段通用的代码。有人说java里面的compareTo可以做到,但如果考虑这么一个问题:同样是出门旅行,老年人身体虚弱,需要大量的休息,而孩子则是精力充沛,希望玩到更多的景点。如何在同一模式下表达以上信息、采用合理的设计模式进行封装而不是大量重写类似的代码,就需要学习并采用策略模式。

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

复制代码 代码如下:

#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

复制代码 代码如下:

#import "InputValidator.h"

@implementation InputValidator

-(BOOL)validateInput:(UITextField *)input error:(NSError **)error
{
    if (error) {
        *error = nil;
    }
    return NO;
}
@end

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

复制代码 代码如下:

#import "InputValidator.h"

@interface NumericInputValidator : InputValidator

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

NumericIputValidator.m

复制代码 代码如下:

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

复制代码 代码如下:

#import "InputValidator.h"

@interface AlphaInputValidator : InputValidator

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

AlphaInputValidator.m

复制代码 代码如下:

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

复制代码 代码如下:

#import <UIKit/UIKit.h>
@class InputValidator;
@interface CustomTextField : UITextField

@property(nonatomic,strong)InputValidator *inputValidator;

-(BOOL)validate;
@end

CustomTextField.m

复制代码 代码如下:

#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

复制代码 代码如下:

#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

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

优点

  • 策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。
  • 策略模式的Stategy类层次为Context定义了一些列的可供重用的算法或行为。继承有助于析取出算法中的公共功能。
  • 策略模式的优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。

使用场景

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

总结
再总结一下策略方法的实现,本质上就是需要完成一个事情(出行),但是并不清楚需要使用怎样的策略,所以封装出一个函数,能够把需要的策略(young OR old)作为参数传递进来,并且使用相应的策略完成这个事件的处理。

最后简单谈一谈个人对于策略模式和面向对象中多态的思想的理解,首先多态是高层次,高度抽象的概念,独立于语言之外,是面向对象思想的精髓,而策略模式只是一种软件设计模式,相对而言更加具体,而且具体实现依赖于具体的编程语言,比如OC和java的实现方法并不相同,是language-dependent的。其次,多态更多强调的是,不同的对象调用同一个方法会得到不同的结果,而策略模式更多强调的是,同一个对象(事实上这个对象本身并不重要)在不同情况下执行不同的方法,而他们的实现方式又是高度类似的,即共享同一个父类并且各自重写父类的方法。

以上观点纯属个人愚见,欢迎大牛指正,互相交流。

时间: 2024-10-24 20:19:43

举例讲解iOS应用开发中对设计模式中的策略模式的使用_IOS的相关文章

举例讲解iOS应用开发中hitTest触摸事件的编写方法_IOS

 hitTest:withEvet  调用过程 比如如果是当前的View A, 还有一个viewB 如果不重写 hitTest 方法,那么 系统默认是先调用viewA的hitest 方法,然后再调用viewB的htest方法. 系统的调用过程,跟下面的重写hitest的方法是一模一样的. 复制代码 代码如下: -(UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event  {      if ([self pointInside:poin

设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述         在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能.如查找.排序等,一种常用的方法是硬编码(Hard Coding)在一个类中,如需要提供多种查找算法,可以将这些算法写到一个类中,在该类中提供多个方法,每一个方法对应一个具体的查找算法:当然也可以将这些查找算法封装在一个统一的方法中,通过if-else-或者case等条件判断语

【设计模式系列】--策略模式

什么是策略模式 在前面的博文中,小编主要向小伙伴介绍了组合模式,今天这篇博文,我们继续来学习设计模式的相关知识,今天和小伙伴们见面的是策略模式,策略模式英文名字叫Strategy,策略模式属于行为模式的一种,她对一系列的算法加以封装,为所有算法定义一个抽象的算法接口,并通过继承该抽象算法接口对所有的算法加以封装和实现,具体的算法选择交由客户端决定,策略模式主要用来平滑的处理算法的切换. 策略模式结构图 我们来看一下策略的结构图,如下所示:   对上述结构图进行简单的解释说明:         a

C++编程中使用设计模式中的policy策略模式的实例讲解_C 语言

   在看<C++设计新思维>的时候,发现在一开始就大篇幅的介绍策略模式(policy),策略模式不属于经典设计模式中的一种,但是其实在我们日常的开发中是必不可少的.policy,策略,方针,这里的意思是指把复杂功能的类尽量的拆分为功能单一的简单类的组合,简单的类只负责单纯行为或结构的某一方面.增加程序库的弹性,可复用性,可扩展性.policy是一个虚拟的概念,他定义了某一类class的一些接口规范,并不与C++语法的关键字对应,只是一个抽象的概念. 实例1: //policy模式的常见使用实

深入解析C++编程中对设计模式中的策略模式的运用_C 语言

策略模式也是一种非常常用的设计模式,而且也不复杂.下面我们就来看看这种模式. 定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化. 角色:     抽象策略角色(Strategy): 抽象策略类.     具体策略角色(ConcreteStrategy):封装了继续相关的算法和行为.     环境角色(Context):持有一个策略类的引用,最终给客户端调用. UML图: 例子: #include <iostream>

php设计模式介绍之策略模式

在编写面向对象的代码的时,有些时候你需要一个能够自己根据不同的条件来引入不同的操作对象实 例.例如,一个菜单功能能够根据用户的"皮肤"首选项来决定是否采用水平的还是垂直的 排列形式,或者一个计费系统可以自行根据用户的收货地址来决定税率. 一般来讲,一个控制菜 单的对象实例包括了add(), delete(), 和 replace()等菜单元素:并通过set()进行配置,用render() 来管理显示模式.无论你想生成什么样子的菜单,你都可以用同一个对象类来处理.不同菜单的对象实 例只是

Java设计模式之Strategy(策略)模式

Strategy是属于设计模式中 对象行为型模式,主要是定义一系列的算法,把这些算法一个个封装成单独的类. Stratrgy应用比较广泛,比如,公司经营业务变化图,可能有两种实现方式,一个是线条曲线,一个是框图(bar),这是两种算法,可以使用Strategy实现. 这里以字符串替代为例, 有一个文件,我们需要读取后,希望替代其中相应的变量,然后输出.关于替代其中变量的方法可能有多种方法,这取决于用户的要求,所以我们要准备几套变量字符替代方案. 首先,我们建立一个抽象类RepTempRule 定

C# 设计模式系列教程-策略模式_C#教程

在讲策略模式之前,我先给大家举个日常生活中的例子,从首都国际机场到XXX酒店,怎么过去?1)酒店接机服务,直接开车来接.2)打车过去.3)机场快轨+地铁 4)机场巴士 5)公交车 6)走路过去(不跑累死的话) 等等.使用方法,我们都可以达到从机场到XXX酒店的目的,对吧.那么我所列出的从机场到XXX酒店的的方法,就是我们可以选择的策略. 再举个例子,就是我们使用WCF时,往往避免不了对它进行扩展,例如授权,我们可以通过自定义授权来扩展WCF.这里我们可以通过自定义AuthorizationPol

学习php设计模式 php实现策略模式(strategy)_php技巧

一.意图定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换.策略模式可以使算法可独立于使用它的客户而变化 策略模式变化的是算法二.策略模式结构图   三.策略模式中主要角色 抽象策略(Strategy)角色:定义所有支持的算法的公共接口.通常是以一个接口或抽象来实现.Context使用这个接口来调用其ConcreteStrategy定义的算法 具体策略(ConcreteStrategy)角色:以Strategy接口实现某具体算法 环境(Context)角色:持有一个Strategy类的