ThinkSSL🔒 一键申购 5分钟快速签发 30天无理由退款 购买更放心 广告
[TOC] # 策略模式 定义一系列的算法,把它们一个个的封装起来,并且使它们可以相互替换。目的就是算法的使用和算法的实现分离出来。 由两部分组成: - 策略类:封装了具体的算法,并负责具体的计算过程 - 环境类:接受客户的请求,随后把请求委托给某一个策略类 ## 面向对象的实现 ```javascript var S = function(){}; S.prototype.calculate = function(salary){ return salary * 4; } var A = function(){}; A.prototype.calculate = function(salary){ return salary * 3; } var B = function(){}; B.prototype.calculate = function(salary){ return salary * 2; } var Bouns = function(){ this.salary = null; this.strategy = null; } Bouns.prototype.setSalary = function(salary){ this.salary = salary } Bouns.prototype.setStrategy = function(strategy){ this.strategy = strategy; } Bouns.prototype.getBouns = function(){ return this.strategy.calculate(this.salary); } var bouns = new Bouns(); bouns.setSalary(1000); bouns.setStrategy(new B()); // 设置策略对象 bouns.getBouns();// 输出 ``` ## JavaScript中的实现 ```javascript var Strategy = { S: function(salary){ return salary * 4; }, A: function(salary){ return salary * 3; }, B: function(salary){ return salary * 2; } }; var getBouns = function(strategy, salary){ return Strategy[strategy](salary); } getBouns('B', 1000); // 2000 ``` ## 多态在策略模式中的体现 环境类并没有计算的能力,而是将计算委托给了策略类,会返回不同的计算结果,也正是多态的表现,也是“它们可以相互替换”的目的。 ## 更广义的“算法” 策略模式可以用来封装一系列的“业务规则”,只要这些业务规则指向的目标一致,并且可以被替换使用,我们就可以用策略模式来封装它们。比如表单校验。 ## 表单校验 ```javascript var strategies = { isNonEmpty: function(value, errorMsg){ .... }, minLength: function(value, length, errorMsg){ .... }, isMobile: function(value, errorMsg){ ... } }; var Validator = function(){ this.cache = []; }; Validator.prototype.add = function(dom, rule, errorMsg){ var ary = [rule]; this.cache.push(function(){ var strategy = ary.shift(); ary.unshift(dom.value); ary.push(errorMsg); return strategies[strategy].apply(dom, ary); }); } Validator.prototype.start = function(){ for(var i=0, validatorFunc; validatorFunc = this.cache[i++]){ var msg = validatorFunc(); if(msg){ return msg; } } } var validatorFunc = function(){ var validator = new Validator(); // 创建一个对象 validator.add(...); var errorMsg = validator.start(); // 获取校验结果 } var registerForm = document.getElementById('form'); registerForm.onsubmit = function(){ var errorMsg = validatorFunc(); if(errorMsg){ return false; } } ``` ## 策略模式的优缺点 1. 避免多重条件选择语句 2. 将算法独立在策略类中,使得它们易于切换、易于理解、易于扩展 3. 策略类可以用在系统的其它地方中 4. 策略类可以利用组合和委托来让环境类拥有执行算法的能力,这也是继承的一种更轻便的替代方案