strategy mode
The strategy pattern refers to defining a series of algorithms and encapsulating them one by one, the purpose is to separate the use of the algorithm from the implementation of the algorithm. To put it bluntly, it is the way of writing that used to require a lot of judgments, but now the content of judgments is extracted and turned into small individuals.
Example of form validation:
<form action="http:// xxx.com/register" id="registerForm" method="post"> Please enter a username: <input type="text" name="userName" /> Please enter a password: <input type="text" name="password"/> Please enter the phone number: <input type="text" name="phoneNumber" /> <button>提交</button> </form>
Common ways to write code:
var registerForm = document.getElementById('registerForm'); registerForm.onsubmit = function(){ if (registerForm.userName.value == '') { alert('Username cannot be empty'); return false; } if (registerForm.password.value.length < 6) { alert('password length cannot be less than 6 digits'); return false; } if (!/(^1[3|5|8][0-9]{9}$)/.test(registerForm.phoneNumber.value)) { alert('Mobile phone number format is incorrect'); return false; } }
Strategy Mode:
This mode involves three roles:
- ConcreteStrategy Role: Wraps related algorithms or behaviors .
- Abstract Strategy (Strategy) role: This is an abstract role, usually implemented by an interface or abstract class. This role gives all the interfaces required by concrete policy classes .
- Context role : holds a reference to a Strategy .
The first step encapsulates the strategy object (algorithm):
var strategies = { isNonEmpty:function(value,errorMsg){ //Not empty if (value === '') { return errorMsg; } }, minLength:function(value,length,errorMsg){ //Limit the minimum length if (value.length < length) { return errorMsg; } }, isMobile:function(value,errorMsg){ //Mobile phone number format if (!/(^1[3|5|8][0-9]{9}$).test(value)) { return errorMsg; } } }
The second step encapsulates the abstract class (interface):
var Validator = function(){ this.cache = []; //Save the validation rules } Validator.prototype.add = function(dom,rule,errorMsg){ var ary = rule.split(':'); //separate strategy and parameters this.cache.push(function(){ //Wrap the verification steps with empty functions and put them in the cache var strategy = ary.shift(); //strategy selected by the user ary.unshift(dom.value); //Add the input value to the parameter list ary.push(errorMsg); //Add errorMsg to the parameter list return strategies[strategy].apply(dom,ary); }) } Validator.prototype.start = function(){ for (var i = 0,validatorFunc;validatorFunc = this.cache[i++];) { var msg = validatorFunc(); //Start verification and get the return information after verification if(msg){ //If there is an exact return value, the verification fails return msg; } } }
Implementation of the third step strategy (reference):
var validataFunc = function(){ var validator = new Validator(); //Create a validator class /********************Add some validation rules**********************/ validator.add(registerForm.userName,'isNonEmpty','username cannot be empty'); validator.add(registerForm.password,'minLength:6','password length cannot be less than 6 digits'); validator.add(registerForm.phoneNumber,'isMobile','Mobile phone number format is incorrect'); var errorMsg = validator.start(); //Get the verification result return errorMsg; //return the verification result } var registerForm = document.getElementById('registerForm'); registerForm.onsubmit = function(){ var errorMsg = validataFunc(); //If errorMsg has an exact return value, it means that the verification failed if(errorMsg){ alert(errorMsg); return false; // prevent form submission } }