前段時間項目中涉及到輸入驗證比較多,有簡單的是否為純數字輸入的驗證,是否為純字母輸入的驗證,也有複雜的正則檢查驗證。
偶爾翻閱去年買的一本設計模式的書,看到了一種設計模式:策略模式。
運用策略模式,把輸入驗證抽象出來,寫成一個單獨的類,在需要的地方調用豈不是很方便。
下面是實現的過程:
一、設計基類
抽象出一個基類,把不同的驗證寫成子類,這樣在所有地方就可以調用同一個介面,大大降低使用者的複雜度。
基類的設計先看代碼:
#import <Foundation/Foundation.h>static NSString* const InputValidationErrorDomain = @"InputValidationErrorDomain";@interface InputValidator : NSObject-(BOOL) validateInput:(UITextField*)input error:(NSError**)error;@end
可以看到我們僅僅提供了一個執行個體方法把要驗證的對象傳進去,然後傳一個填充error的指標。返回驗證結果為BOOL型。
再來看實現:
#import "InputValidator.h"@implementation InputValidator-(BOOL) validateInput:(UITextField *)input error:(NSError **)error{ if (error) { *error=nil; } return NO;}@end
基類就這麼簡單。
然後,就是根據需求去具體實現子類。
二、設計子類
子類是根據我們的需求具體去設計及實現。我這裡提供兩個簡單的驗證:純數字驗證、純字母驗證。
先看純數位驗證:
#import "InputValidator.h"@interface NumericInputValidator : InputValidator- (BOOL) validateInput:(UITextField *)input error:(NSError **)error;@end
可以看到我們繼承了基類,然後需要重載唯一的執行個體方法。再看實現:
#import "NumericInputValidator.h"@implementation NumericInputValidator- (BOOL) validateInput:(UITextField *)input error:(NSError **)error{ NSError* regError = nil; NSRegularExpression* regex =[ NSRegularExpression regularExpressionWithPattern:@"^[0-9]*$" options:NSRegularExpressionAnchorsMatchLines error:Error]; NSUInteger numberOfMatches = [regex numberOfMatchesInString:[input text] options:NSMatchingAnchored range:NSMakeRange(0, [[input text]length])]; if (numberOfMatches==0) { if (error != nil) { NSString* description = NSLocalizedString(@"Input Validation Failed", @""); NSString* reason = NSLocalizedString(@"The input can contain only numerical values", @""); NSArray* objArray = [NSArray arrayWithObjects:description,reason, nil]; NSArray* keyArray = [NSArray arrayWithObjects:NSLocalizedDescriptionKey,NSLocalizedDescriptionKey, nil]; NSDictionary* userInfo = [NSDictionary dictionaryWithObjects:objArray forKeys:keyArray]; *error = [NSError errorWithDomain:InputValidationErrorDomain code:1001 userInfo:userInfo]; } return NO; } return YES;}@end
可以看到實現就豐滿起來了。
再看純字母驗證的:
標頭檔:
#import "InputValidator.h"@interface AlphaInputValidator : InputValidator{ }- (BOOL) validateInput:(UITextField *)input error:(NSError **)error;@end
實現:
#import "AlphaInputValidator.h"@implementation AlphaInputValidator- (BOOL) validateInput:(UITextField *)input error:(NSError **)error{ NSError* regError = nil; 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])]; if (numberOfMatches==0) { if (error != nil) { NSString* description = NSLocalizedString(@"Input Validation Failed", @""); NSString* reason = NSLocalizedString(@"The input can contain only letters", @""); NSArray* objArray = [NSArray arrayWithObjects:description,reason, nil]; NSArray* keyArray = [NSArray arrayWithObjects:NSLocalizedDescriptionKey,NSLocalizedDescriptionKey, nil]; NSDictionary* userInfo = [NSDictionary dictionaryWithObjects:objArray forKeys:keyArray]; *error = [NSError errorWithDomain:InputValidationErrorDomain code:1002 userInfo:userInfo]; } return NO; } return YES;}@end