舉例講解iOS應用開發中對設計模式中的策略模式的使用_IOS

來源:互聯網
上載者:User

策略模式是一種常見的軟體設計模式,這裡簡單得介紹一下策略模式並用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的。其次,多態更多強調的是,不同的對象調用同一個方法會得到不同的結果,而策略模式更多強調的是,同一個對象(事實上這個對象本身並不重要)在不同情況下執行不同的方法,而他們的實現方式又是高度類似的,即共用同一個父類並且各自重寫父類的方法。

以上觀點純屬個人愚見,歡迎大牛指正,互相交流。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.