Introduced
The policy pattern defines the algorithm family, which is encapsulated separately so that they can be replaced by each other, and this pattern allows the algorithm to change without affecting the client using the algorithm.
Body
Before we understand the strategy pattern, let's start with an example, in general, if we are going to validate the data legitimacy, often in accordance with the Swith statement to judge, but this brings a few problems, first of all, if we increase the demand, we also need to modify this code to increase the logic, And it's getting more and more complicated when it comes to unit testing, code like this:
Validator = {validate:function(Value, type) {Switch(type) { Case' Isnonempty ': {return true;//nonempty Validation Results} Case' Isnumber ': {return true;//Number Validation Results Break; } Case' Isalphanum ': {return true;//alphanum Validation Results}default: {return true; } } } };//TestAlert (Validator.validate ("123", "Isnonempty"));
How to avoid the problem in the above code, according to the policy model, we can separate the same work code into different classes, and then through a unified policy processing class to handle, OK, we first define the policy processing class, the code is as follows:
varValidator = {//all the validation rules that can be processed where the class is stored, will be defined separately laterTypes: {},//error message for validation typeMessages: [],//Of course, the type of authentication you need to useConfig: {},//public authentication method of exposure //the parameters passed in are key = = value toValidatefunction(data) {varI, MSG, type, checker, RESULT_OK;//Clear all the error messages This. messages = []; for(IinchData) {if(Data.hasownproperty (i)) {type = This. Config[i];//query for presence validation rules based on keyChecker = This. Types[type];//gets the validation class for the validation rule if(!type) {Continue;//If the validation rule does not exist, it is not processed}if(!checker) {//throws an exception if the validation rule class does not exist Throw{Name: "ValidationError", Message: "No handler to validate type" + type }; } RESULT_OK = Checker.validate (Data[i]);//validation using the single validation class found if(!RESULT_OK) {msg = "Invalid value for *" + i + "*," + checker.instructions; This. Messages.push (msg); } } }return This. HasErrors (); },//HelperHasErrors:function() {return This. messages.length!== 0; }};
Then the rest of the work is to define the various validation classes stored in the types, and here are just a few examples:
//verifies that a given value is not emptyValidator.types.isNonEmpty = {validate:function(value) {returnValue!== ""; }, instructions: "The value passed in cannot be null"};//verifies whether a given value is a numberValidator.types.isNumber = {validate:function(value) {return!isnan (value); }, instructions: "The value passed in can only be a valid number, for example: 1, 3.14 or 2010"};//verifies whether a given value is just a letter or a numberValidator.types.isAlphaNum = {validate:function(value) {return!/[^a-z0-9]/i.test (value); }, instructions: "Incoming values can only protect letters and numbers, and cannot contain special characters"};
When used, we first define the set of data that needs to be validated, and then we need to define the types of rules that each data needs to validate, with the following code:
var data = { first_name: "Tom", last_name: "Xu", Age : "Unknown", Username: "Tomxu"}; Validator.config = { first_name: ' Isnonempty ', age : ' Isnumber ', username: ' Isalphanum '};
Finally, the code to get the results of the validation is simple:
Validator.validate (data); if (Validator.haserrors ()) { Console.log (validator.messages.join ("\ n"));}
Summarize
The strategy pattern defines a series of algorithms, conceptually, all of which are doing the same thing, just implementing the difference, he can call all the methods in the same way, reducing the coupling between the various algorithm classes and the use of the algorithm class.
On the other hand, it is easy to define the algorithm classes individually, as well as unit tests, because they can be individually tested by their own algorithms.
In practice, not only can encapsulation algorithms, but also can be used to encapsulate almost any type of rules, in the analysis process need to apply different business rules at different times, you can consider the strategy mode to deal with various changes.
Copyright NOTICE: This article for Bo Master http://www.zuiniusn.com original article, without Bo Master permission not reproduced.
In-depth understanding of the JavaScript series (33): A strategy model for design patterns