策略模式

继上次的适配器模式后,这次说的是策略模式。

还是同样的套路,先来说说为什么要使用策略模式吧***

在实际的开发中,肯定会有多选一的情况,这时首先想到的肯定是 if-else 语句啦~如果有很多很多情况,我想就if-else都得写吐了吧 - _ -!!而且会显得代码特别繁琐,可读性差。

举一个栗子吧,登录界面中,验证邮箱、姓名、手机号、、、等等杂七杂八的条件时,就需要有选择性的验证,这就是所谓的多选一的情况,实际上邮箱、手机号、姓名等等在验证的时候都是验证文本框中的文字,这时就可以用策略模式来解决这个问题。

下图展示了策略模式的基本原理:

如图中所看到的+-+

context : 应用场景

(1)需要使用具体策略类(如ConcreteStrategyA类)中的算法

(2)需要持有一个Strategy实例变量

(3)需要与Strategy类之间交互并且进行数据传递

Strategy :抽象策略类

(1)定义一个公共接口,并且空实现。

(2)Context使用这个接口调用不同的算法

ConcreteStrategyA :具体策略类

以继承的方式实现具体的算法。


接下来就是以文本输入框的验证为例上代码啦~~~

(1)if-else方式

CustomedField类

.h

#import <UIKit/UIKit.h>

@interface CustomedField : UITextField

//初始化并返回实例对象
- (instancetype)initWithFrame:(CGRect)frame;


@end

.m

#import "CustomedField.h"

@implementation CustomedField

- (instancetype)initWithFrame:(CGRect)frame{
    
    self = [super initWithFrame:frame];
    if (self) {
        //实现***
    }
    return self;
}

@end

ViewController.m

#import "ViewController.h"
#import "CustomedField.h"

#define W [UIScreen mainScreen].bounds.size.width

@interface ViewController ()
<UITextFieldDelegate>

//邮箱文本输入框
@property CustomedField *emailField;
//电话号文本输入框
@property CustomedField *phoneNumberField;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self initTextField];
    [self initButton];
}
//初始化文本输入框
- (void)initTextField{
    
    //***
}
//初始化确认按钮级点击事件
- (void)initButton{
    //***
}
- (void)touchButton:(UIButton *)button{
    
    [self.view endEditing:YES];
}
//文本框代理
- (void)textFieldDidEndEditing:(UITextField *)textField{
    
    NSString *str = nil;
    if (textField == self.emailField) {
        str = [self validateEmailField:textField];
        if (str) {
            NSLog(@"%@",str);
        }
        else{
            NSLog(@"textfield不为空");
        }
    }
    else if(textField == self.phoneNumberField)
    {
        str = [self validateEmailField:textField];
        if (str) {
            NSLog(@"%@",str);
        }
        else{
            NSLog(@"textfield不为空");
        }
    }
    //else if...
}

//验证算法(简单起见,只验证textfield是否为空)
- (NSString *)validateEmailField:(UITextField *)field {
    
    NSString *str = nil;
    if (field.text.length <= 0) {
        str = @"没有输入";
    }
    return str;
}

- (NSString *)validatePhoneNumberField:(UITextField *)field {
    
    NSString *str = nil;
    if (field.text.length <= 0) {
        str = @"没有输入";
    }
    return str;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
这里我只写了两个文本输入框,假如有成十成百个需要验证的,如果使用if-else就太麻烦啦~

(2)策略模式

①抽象策略类:TextFieldValidateStrategy类

.h

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

@interface TextFieldValidateStrategy : NSObject

//当验证不通过时,读取错误信息
@property (nonatomic ,strong) NSString *errorMessageStr;
//验证策略,通过返回YES,不通过返回NO
- (BOOL)validateTextField:(UITextField *)field;

@end


.m

#import "TextFieldValidateStrategy.h"

@implementation TextFieldValidateStrategy
//空实现验证策略
- (BOOL)validateTextField:(UITextField *)field{
    
    return NO;
}
@end
②具体策略类

i > EmailTextFieldValidateStrategy类

.h

#import "TextFieldValidateStrategy.h"

@interface EmailTextFieldValidateStrategy : TextFieldValidateStrategy

//重载父类的验证方法
- (BOOL)validateTextField:(UITextField *)field;

@end

.m

#import "EmailTextFieldValidateStrategy.h"

@implementation EmailTextFieldValidateStrategy

- (BOOL)validateTextField:(UITextField *)field{
    
    self.errorMessageStr = nil;
    if (field.text.length <= 0) {
        self.errorMessageStr = @"没有输入";
    }
    return self.errorMessageStr == nil ? YES : NO;
}

@end

ii > PhoneNumberTextFieldValidateStrategy类

.h

#import "TextFieldValidateStrategy.h"

@interface PhoneNumberTextFieldValidateStrategy : TextFieldValidateStrategy

//重载父类的验证方法
- (BOOL)validateTextField:(UITextField *)field;

@end

.m

#import "PhoneNumberTextFieldValidateStrategy.h"

@implementation PhoneNumberTextFieldValidateStrategy

- (BOOL)validateTextField:(UITextField *)field{
    
    self.errorMessageStr = nil;
    if (field.text.length <= 0) {
        self.errorMessageStr = @"没有输入";
    }
    return self.errorMessageStr == nil ? YES : NO;
}
@end

③应用场景:CustomedField类

.h

#import <UIKit/UIKit.h>
#import "TextFieldValidateStrategy.h"

@interface CustomedField : UITextField

//初始化textfield,返回实例对象
- (instancetype)initWithFrame:(CGRect)frame;

//抽象策略的实例对象
@property (nonatomic,strong) TextFieldValidateStrategy *strategy;

//与Strategy类进行交互并且传递数据
- (BOOL)validate;

@end

.m (只增加了Validate方法)
- (BOOL)validate
{
    
    return [self.strategy validateTextField:self];
}

ViewController.m

①在初始化文本输入框时,需要让其持有Strategy实例变量

如:

self.emailField.strategy = [EmailTextFieldValidateStrategy new];
phoneNumberField也是如此,若有多个还是如此=~=

②文本框代理有所改变

- (void)textFieldDidEndEditing:(UITextField *)textField{
    
    CustomedField *field = (CustomedField *)textField;
    if ([field validate] == NO) {
        NSLog(@"%@",field.strategy.errorMessageStr);
    }
    else{
        NSLog(@"验证成功");
    }
}

这样就完成啦~是不是很简单呢,而且代码看起来也很干净~~~

有利即有弊+-+

策略模式可以简练if-else语句,让代码可读性增强,易于维护。

但是它只适用于已经知道了所有的算法的情况。。。换言之,客户端必须知道所有的算法,并且自行选择使用哪一个策略类 -_-~~~


说到这里,已经基本上完啦,有不对的或者有啥表达不当的敬请指正。谢谢大家~撒花~~~笔芯~~~



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值