Illustrate the use of policy patterns in design patterns in iOS application development

  • 2020-05-30 21:06:12
  • OfStack

Policy pattern is a common software design pattern. Here, we simply introduce 1 policy pattern and implement 1 with IOS.
The so-called strategy pattern, as its name implies, is to adopt different strategies. Generally speaking, the way to deal with a particular problem is not the same in different situations. For example, sorting a string and sorting a number, although they both use quicksort, is obviously impossible to use a common piece of code. Some people say that compareTo in java can do it, but if you consider the following problem: the elderly are weak and need a lot of rest when they are traveling, while the children are energetic and want to visit more scenic spots. How to express this information in the same pattern and encapsulate it in a reasonable design pattern instead of rewriting a lot of similar code requires learning and adopting the policy pattern.

example
This example mainly USES the policy pattern to judge whether UITextField meets the input requirements. For example, the input can only be a number, if it is only a number, there will be no prompt, and if there are other characters, there will be an error. Verify that the letter is also 1.
First, let's define an abstract policy class, IputValidator. The code is as follows:
InputValidator.h


#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h> static NSString * const InputValidationErrorDomain = @"InputValidationErrorDomain";
@interface InputValidator : NSObject // The stub method that actually validates the policy
-(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

This is just a policy base class, and we're going to subclass NumericInputValidator and AlphaInputValidator. The specific code is as follows:
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;
    // Using configured NSRegularExpression Object to check the number of matches of numeric types in the text box.
    //^[0-9]*$: This means starting at the beginning of the line ^ ) to the end ( Represented as a $) There should be several word sets (marked as [0-9] ) in the 0 Or more characters (denoted as * )
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^[0-9]*$" options:NSRegularExpressionAnchorsMatchLines error:&regError];
   
   
    NSUInteger numberOfMatches = [regex numberOfMatchesInString:[input text] options:NSMatchingAnchored range:NSMakeRange(0, [[input text] length])];
   
    // If there is no match, an error and is returned 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;
    // Using configured NSRegularExpression Object to check the number of matches of numeric types in the text box.
    //^[0-9]*$: This means starting at the beginning of the line ^ ) to the end ( Represented as a $) There should be several word sets (marked as [0-9] ) in the 0 Or more characters (denoted as * )
    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])];
   
    // If there is no match, an error and is returned 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

Both of them are subclasses of InputValidator. Then define 1 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

Finally, the validation is tested in 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

Result: when we enter a message that does not meet the criteria, we will display a prompt message, and when we enter a message that does not meet the criteria, there will be no prompt.

advantages

The strategy pattern is a way to define a series 1 algorithm. Conceptually, all these algorithms do the same job, but with different implementations. It can invoke all algorithms in the same way, reducing the coupling between the various algorithm classes and the algorithm classes used. The Stategy class hierarchy of the policy pattern defines 1 column of reusable algorithms or behaviors for Context. Inheritance helps extract common functions from an algorithm. The advantage of the policy pattern is that it simplifies unit testing because each algorithm has its own class and can be tested individually through its own interface.

Usage scenarios

A class USES multiple conditional statements in its operations to define many behaviors. We can move related conditional branches into their own policy classes You need variations of the algorithm You need to avoid exposing complex algorithmic data structures to the client

conclusion
In essence, the implementation of the policy method needs to complete one thing (travel), but it is not clear what kind of policy is needed. Therefore, a function is encapsulated to pass in the required policy (young OR old) as a parameter, and the corresponding policy is used to complete the processing of this event.

Finally simple talking 1 personal for the strategy pattern and polymorphism of object-oriented thought understanding, first polymorphism is a high-level, highly abstract concept, independent of language, is the essence of the object-oriented thought, and the strategy pattern is one kind of software design pattern, relatively more explicit, and the specific implementation depends on the specific programming language, such as java OC and realization method are not the same, is language - dependent. Second, polymorphism is more emphasize that different object call with a method to get different results, and the strategy pattern is more emphasize that with one object (the object itself is not important, in fact) use different methods in different situations, and the implementation of the way they are highly similar, that is Shared with one parent and rewriting of the parent class method.

The above views are purely personal, Daniel is welcome to correct, mutual exchange.


Related articles: