Cowboy Tech

iOS设计模式-策略

if-else的问题

如果判断逻辑都使用if - else,将if - else 的每个判断逻辑抽象为对象

typedef enum : NSUInteger {

EType_01,
EType_02,
EType_03,
EType_04,
EType_05,
EType_06,
EType_07,
EType_08,
EType_09,

} ETypes;

// 输入条件
ETypes type = EType_01;

// 输出条件
NSString *showString = nil;

if (type == EType_01) {

    // showString = ...

} else if (type == EType_02) {

    // showString = ...

} else if (type == EType_03) {

    // showStri
    ......

策略的原理

  1. 使用场景有策略的父类(strategy)引用,但是实际利用多态调用的是其子类(strategy A, stategy B, stategy C)的方法, 具体实现的算法封装在各个子类里。
  2. 相同的输入,不同的输出。抽象的父类strategy定义了一个相同的接口,就是相同的输入。具体的实现在其各个子类strategyABC, 输出各不相同,就是不同的输出,因为每个子类里有不同的算法封装
  3. 判断的每个条件生成对应的一个对象
  4. 需要事先知道输入的条件
  5. 策略类对象属于使用场景的一部分

策略的使用案例

抽象的策略 (Strategy)

CustomField: 内含inputValidator验证策略

@interface CustomField : UITextField

@property (nonatomic, strong) InputValidator *validator;

- (BOOL)validate {
return [self.validator validateInput:self];
}
@end

InputValidator:策略的输入

@interface InputValidator : NSObject

@property (nonatomic, strong) NSString *errorMessage;

- (BOOL)validateInput:(UITextField *)input {
return NO;
}

Email的验证 (Strategy A)

EmailValidator:重载了父类的验证方法

@interface EmailValidator : InputValidator

- (BOOL)validateInput:(UITextField *)input {

if (input.text.length <= 0) {
    self.errorMessage = @"没有输入";
} else {
    BOOL isMatch = [input.text isMatch:RX(@"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}")];
    if (isMatch == NO) {
        self.errorMessage = @"请输入正确的邮箱";
    } else {
        self.errorMessage = nil;
    }
}
return self.errorMessage == nil ? YES : NO;
}

Phone的验证 (Strategy B)

PhoneNumberValidator :重载了父类的验证方法

@interface PhoneNumberValidator : InputValidator

- (BOOL)validateInput:(UITextField *)input {

if (input.text.length <= 0) {
    self.errorMessage = @"没有输入";
} else {
    BOOL isMatch = [input.text isMatch:RX(@"^((13[0-9])|(15[^4,\\D])|(18[0,0-9]))\\d{8}$")];
    if (isMatch == NO) {
        self.errorMessage = @"请输入正确的手机号码";
    } else {
        self.errorMessage = nil;
    }
}

return self.errorMessage == nil ? YES : NO;
}

使用场景

ViewController

@property (nonatomic, strong) CustomField  *emailField;
@property (nonatomic, strong) CustomField  *phoneNumberField;

......
self.emailField.validator   = [EmailValidator new];
......
self.phoneNumberField.validator   = [PhoneNumberValidator new];
......
- (void)textFieldDidEndEditing:(UITextField *)textField {
CustomField *customField = (CustomField *)textField;

//使用这行代码也可以 if ([customField.validator validateInput:customField] == NO){...}

if ([customField validate] == NO) {
    [UIInfomationView showAlertViewWithTitle:nil
                                     message:customField.validator.errorMessage
                           cancelButtonTitle:nil
                           otherButtonTitles:@[@"确定"]
                                clickAtIndex:^(NSInteger buttonIndex) {

                                }];
}
}