[Swift基础] 举例讲解iOS应用开发中对设计模式中的策略模式的使用

[复制链接]

[Swift基础] 举例讲解iOS应用开发中对设计模式中的策略模式的使用[复制链接]

piaodoo 发表于 2018-10-3 09:31:48 [显示全部楼层] 回帖奖励 |倒序浏览 |阅读模式 回复:  72 浏览:  226

这篇文章主要介绍了iOS应用设计中对设计模式中的策略模式的使用,示例代码为传统的Objective-C语言,需要的朋友可以参考下

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

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

复制代码 代码如下:

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

static NSString * const InputValidationErrorDomain = @"InputValidationErrorDomain";
@interface InputValidator : NSObject

//实际验证策略的存根方法
-(BOOL)validateInputUITextField *)input errorNSError **)error;
@end


InputValidator.m
复制代码 代码如下:

#import "InputValidator.h"

@implementation InputValidator


-(BOOL)validateInputUITextField *)input errorNSError **)error
{
    if (error) {
        *error = nil;
    }
    return NO;
}
@end


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

#import "InputValidator.h"

@interface NumericInputValidator : InputValidator

-(BOOL)validateInputUITextField *)input errorNSError **)error;
@end


NumericIputValidator.m
复制代码 代码如下:

#import "NumericInputValidator.h"

@implementation NumericInputValidator

-(BOOL)validateInputUITextField *)input errorNSError **)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 dictionaryWithObjectsbjArray forKeys:keyArray];
           
            *error = [NSError errorWithDomain:InputValidationErrorDomain code:1001 userInfo:userInfo];
        }
        return NO;
    }
    return YES;
}
@end


AlphaInputValidator.h
复制代码 代码如下:

#import "InputValidator.h"

@interface AlphaInputValidator : InputValidator

- (BOOL)validateInputUITextField *)input errorNSError **)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:®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 dictionaryWithObjectsbjArray 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的。其次,多态更多强调的是,不同的对象调用同一个方法会得到不同的结果,而策略模式更多强调的是,同一个对象(事实上这个对象本身并不重要)在不同情况下执行不同的方法,而他们的实现方式又是高度类似的,即共享同一个父类并且各自重写父类的方法。

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

回复

使用道具 举报

uv忘忧水 发表于 2019-4-14 08:29:59 显示全部楼层
强烈支持,楼主万岁!












                               
登录/注册后可看大图


冬虫夏草怎么吃
燕窝市场价格是多少钱一克
大蒜的主要功效有哪些
大太岁网
网站地图
野生小娃娃鱼
酒界名家
白蜡树价格行情
如何种植葛根才能高产
番石榴的功效与作用
桂花树价格
蜂花粉能去黄褐斑吗
蛇的最新价格
丹桂树苗最新价格
长江胭脂鱼养殖技术
莲藕的做法
苹果树种植步骤
qq刷的会员怎么取消
手工折纸玫瑰花教程
脚气病的症状是什么
回复 支持 反对

使用道具 举报

xbp最好的 发表于 2019-4-14 17:54:44 显示全部楼层
看后感悟了点,收下了












                               
登录/注册后可看大图


治脚气最有效的药
燕窝的药用价值有哪些
青蛙的种类有哪些
蒜黄的栽培技术
养鸭子技术
文学与茶
国内种植天麻的基地
百花蜂蜂蜜产地在哪里
养猪行情分析
蛇的最新价格
甘蔗上火吗
新鲜虫草花禁忌
哈密瓜的皮怎么吃
燕窝的药用价值有哪些
蛇的最新价格
沉香木批发
孔雀苗批发
自动回复名片赞软件
养鸭成本
枇杷叶的功效与作用
回复 支持 反对

使用道具 举报

嗱嗱0v 发表于 2019-4-14 19:55:30 显示全部楼层
真的吗?太好了,非常喜欢












                               
登录/注册后可看大图


黑枸杞的功效和吃法
知了猴怎么种植
法桐树的嫁接方法
低价刷访客
鬼故事大全
燕窝亭网
脚气怎么根治
台球国标规则
svip和黄钻联合活动
tplink设置联网
土元养殖实用技术大全
养蝎子的前景怎样
西瓜能种吗
tplink设置联网
红富士苹果批发产地是哪
藏红花种植条件
鹿茸草价格
养殖水律蛇的技术
桂花树播种方法
大蒜的功效与作用
回复 支持 反对

使用道具 举报

中移国动bj3 发表于 2019-4-16 16:15:07 显示全部楼层
我顶啊。接着顶












                               
登录/注册后可看大图


绿萝叶子发黄怎么办
柴鸡蛋批发价格
磊科无线路由器设置
免费qq会员
养羊场的环保要求
辟谷减肥注意事项
养殖扇贝利润
网站地图
幼孔雀怎么养
速生法桐价格
沉香树产地在什么地方
灵芝草的功效与作用
为什么圣诞老人用驯鹿拉礼物
黄精的作用与功效
知了猴的壳营养价值
桂花树的品种及价格
8公分大叶女贞树的移植
孔雀苗怎么养
名片赞花花社区
小金鱼怎么养才不会死
回复 支持 反对

使用道具 举报

xbp最好的 发表于 2019-4-17 01:51:38 显示全部楼层
的确好帖子,推荐加精华












                               
登录/注册后可看大图


中国鸡蛋吧
火鸡火鸡
蓝莓的营养价值
桂花树盆栽怎么养
马铃薯是土豆吗
翡翠和玉的区别
玉雕摆件大全
银杏树的特点是什么
为什么风电场要建到海上去
艾灸的副作用
花生米怎么做好吃
在哪买阿胶
qq小号出售网站
脚气怎么治
有机肥网
治疗狐臭的费用是多少
怎么做四川泡菜
蜂蜜减肥的正确吃法
冬枣的功效与作用
中国最好的板栗品种
回复 支持 反对

使用道具 举报

uv忘忧水 发表于 2019-4-17 02:06:19 显示全部楼层
祝楼主快乐,大家一齐讨论!












                               
登录/注册后可看大图


宫寒可以吃藏红花吗
共创卡盟官方网站
土元养殖
青蛙人工养殖有难度吗
茶叶的功效
养殖大棚低价供应养鸽子大棚
花生网
人工葛根种植方法
猕猴桃怎么去皮
辟谷采气方法有几种
霍山石斛价格
龙鱼吃什么肉
qq会员体验卡领取2019
苹果什么时候吃最好
沉香木苗批发价格是多少
鸽子肉的营养价值
养鹅家
雪松苗圃批发基地
蜂蜜水的正确喝法
金银花盆景如何管理
回复 支持 反对

使用道具 举报

黄石好又多9 发表于 2019-4-17 17:14:49 显示全部楼层
顶你!辛苦了~












                               
登录/注册后可看大图


仿真树生产厂家
藏红花的副作用有哪些
银杏树的外形特征和作用
孔雀种苗价格
小苗雪松种植技术
一元10万QQ赞
酒糟养羊方法
水蛭吧
娃娃鱼的价格
网站地图
玉雕图案大全
牡丹栽培论文参考文献
鹿茸人
农村养鹅销路
白蜡树苗移植栽种培植技术
天麻子的功效与作用
肉牛怎么养殖更专业
兔子繁殖问题
虫草的功效与作用及食用方法
鸭子的常见病及预防
回复 支持 反对

使用道具 举报

嗱嗱0v 发表于 2019-4-17 19:59:37 显示全部楼层
呵呵,非常感谢,很好很强大












                               
登录/注册后可看大图


鸭子的常见病及特征
沉香手串鉴别
长吻鮠养殖技术
百花蜂蜂蜜产地在哪里
孔雀鱼要怎么养
藏红花藏药足浴有效吗
鹿茸人
哪里收鹿茸
到家辟谷养生方法
水蛭小苗的孵化
农村养鸽子赚钱吗
野生金银花种植技术
白蜡木种植技术
葛根的种植栽培技术
什么东西解酒
琥珀收藏网
菠萝蜜的核能吃吗
娃娃鱼网
灵芝孢子粉的功效与作用
桂花树的价格
回复 支持 反对

使用道具 举报

嗱嗱0v 发表于 2019-4-18 17:34:53 显示全部楼层
创意哦!楼主高人啊 谢












                               
登录/注册后可看大图


乌龟吃什么
铁皮石斛多少钱一斤
沉香是树吗
UFO之家
形成狐臭的主要原因
蒜苔市场批发价格
八月十五的月亮最圆吗
法桐秋冬能不能移栽
反季小龙虾如何养殖
甘蔗上火吗
养青蛙吃什么
名片互赞挂机
新鲜的铁皮石斛怎么吃
自动养兔设备
快手粉丝一元
大闸蟹怎么做好吃
微创去除狐臭手术
哈密瓜上火吗
孕妇吃什么水果对胎儿好
笋壳鱼的养殖方法
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1
QQ