JavaScript设计模式之策略模式【组合委托】
2020-08-18 10:53
232 查看
前言:语言只是工具,思想才是核心
今天要总结的是 策略模式 策略在开发中的应用非常广泛,所以也是非常常见且使用的设计模式。 在实际开发中,往往在实现一个功能时,有多种解决方案可行。
常见场景:
- 解压:gzip算法解压,gzip算法解压
- 表单验证:手机号验证,邮箱验证,密码格式验证
- 工资计算:技术猛男工资,鼓励师妹妹工资,冷血产品经理工资
总结策略模式的使用场景,在想实现某个效果时,有多种不同的达成方式。这个时候就要考虑策略模式(如果你写了很多ifelse)
使用策略模式的优点:
- 1.使代码更加清晰可读,减少繁多的if-else
- 2.功能更易拓展,可维护,健壮性【单一指责,抽离变与不变。如果你看了上篇单例设计模式你就看到我也强调过这一点】
- 3.策略可重用
策略模式的应用场景:
场景一:
工资计算
财务妹妹想要给技术猛男、鼓励师妹妹、冷血产品经理来统计他们本月的工资。但他们的工资计算方式不一样呀,这可咋整?
- 技术猛男:(10000基本+1000项目奖励)* 1.2绩效
- 鼓励师妹妹:(9000基本)*1绩效
- 冷血产品经理:(500基本)*1.5绩效
- 【绩效每月都不同】
本着抽离变与不变的思路:
- 变:不同角色不同计算方式
- 不变:都需要计算工资
面对对象思路的写法:
<script> // 策略类 定义各个角色的工资计算方式 function WageStrategy() { } WageStrategy.prototype.ROLE = { IT: 'itHandsomeBoy', ENCOURAGE: 'encourager', MANAGER: 'productManager', }; WageStrategy.prototype.itHandsomeBoy = function (performance) { return (10000 + 2000) * performance; } WageStrategy.prototype.encourager = function (performance) { return (9000) * performance; } WageStrategy.prototype.productManager = function (performance) { return (500) * performance; } WageStrategy.prototype.getRoleWage = function (role, performance) { return this[role](performance); } // 中间类 (发起计算的财务)【持有策略对象】 function FinancialMan(strategy) { this.strategy = strategy; } FinancialMan.prototype.getWage = function (role, performance) { return this.strategy.getRoleWage(role, performance); }; // 运行 let financialMan = new FinancialMan(new WageStrategy()); console.log(financialMan.getWage(financialMan.strategy.ROLE.IT, 1.2)); console.log(financialMan.getWage(financialMan.strategy.ROLE.ENCOURAGE, 1)); console.log(financialMan.getWage(financialMan.strategy.ROLE.MANAGER, 1.5)); </script>
上面是模拟像Java这样基于类的语言,而js中存在很多不一样的特性,例如:函数即对象!所以以下是改进的 Js版本的策略模式。
<script> // 策略对象,封装工资算法 let wageStrategy = { ROLE : { IT : 'itHansomeBoy', ENCOURAGE : 'encourager', MANAGER : 'productManager', }, itHansomeBoy: function (performance) { return (10000 + 2000) * performance; }, encourager: function (performance) { return (9000) * performance; }, productManager: function (performance) { return (500) * performance; }, }; // 计算工资对象 let getWage= function (role, performance) { return wageStrategy[role](performance); } console.log(getWage(wageStrategy.ROLE.IT, 1.2)); // 14400 console.log(getWage(wageStrategy.ROLE.ENCOURAGE, 1)); // 9000 console.log(getWage(wageStrategy.ROLE.MANAGER, 1.5)); // 750 </script>
场景二:
表单验证(注册账号) 用户在填完一堆信息后【如:手机号、邮箱号、姓名、密码、验证码】,点击注册,此时应该先对每个字段进行检查,都通过后才能提交到后台。
比较猛的写法:
let register = function () { let name, phone, if(!name) { return; }else if (!phone || phone.length !== 11) { return; } // do register request }
随着需要检验的字段越来越多,那么else if的逻辑越来越重。并且,如果有个完善信息页面,同样需要用到手机号,邮箱号这些信息检测怎么复用勒?
那么,策略模式来了:
<script> // 表单检验策略类 let checkInfoStrategy = { phone: function (phone) { let pass = true; let tips = ''; if (!phone) { pass = false; tips = '手机号不能为空'; } return { pass, tips }; }, email: function (email) { let pass = true; let tips = ''; if (!email) { pass = false; tips = '邮箱不能为空'; } else if (email.indexOf('@') < 0) { pass = false; tips = '邮箱格式不正确'; } return { pass, tips }; } } // 中间者 发起表单检验 let Checker = function () { this.cache = []; // 存放需要检验项:{策略,待检验字符} // 添加待检查项 this.add = function (stragetyItem, beCheckInfo) { this.cache.push({ item: stragetyItem, info: beCheckInfo }); return this; }; // 开始检查 this.startCheck = function () { let result = { pass : true, tips : '' }; for (let i = 0; i < this.cache.length; i++) { let checkItem = this.cache[i]; let {pass, tips} = checkItem.item(checkItem.info); result.pass = pass; result.tips = tips; if (!pass) { break; } } return result; }; } // 执行 let phone = '18826274139'; let email = ''; let checker = new Checker(); checker.add(checkInfoStrategy.phone, phone).add(checkInfoStrategy.email, email); let { pass, tips } = checker.startCheck(); console.log(':::' + pass, tips); // :::false 邮箱格式不正确 </script>
其他不多说了,一定要动过。 思路就是抽离变与不变。策略类之放不同的算法/逻辑,使用中间类来协助发起策略类的使用。
相关文章推荐
- 委托之异步调用 、抽象方法、策略模式、接口
- 设计模式---复合模式(策略-适配器-装饰者-抽象工厂-组合-观察者)
- JavaScript设计模式 - 策略模式
- 16.组合游戏单位——策略模式
- Javascript设计模式与开发实践详解(二:策略模式)
- javascript设计模式_第二部分_组合模式
- JavaScript设计模式开发中组合模式的使用教程
- 委托之异步调用 、抽象方法、策略模式、接口
- 《Javascript设计模式与开发实践》关于设计模式典型代码的整理(上):单例模式、策略模式、代理模式、迭代器模式、发布-订阅模式、命令模式、组合模式
- 策略模式-组合优于继承的实现(转)
- JavaScript设计模式与开发实践 策略模式
- javascript设计模式学习之五——策略模式
- JavaScript设计模式--组合模式
- javascript设计模式入门之策略模式
- javascript设计模式——组合模式
- .NET 下运用策略模式(组合行为和实体的一种模式)
- 《javascript设计模式》笔记之第九章:组合模式
- JavaScript设计模式之策略模式实例
- javascript设计模式之策略模式学习笔记
- javascript设计模式--策略模式之输入验证