您现在的位置是:亿华云 > 数据库
新生代农民工需要懂的策略设计模式
亿华云2025-10-09 07:00:01【数据库】9人已围观
简介本文转载自微信公众号「DYBOY」,作者DYBOY 。转载本文请联系DYBOY公众号。俗话说,凡事讲策略。讲策略的时候,我们往往会考虑每种情况的成本。策略同样可体现在我们的代码之中,合理利用策略模式重
本文转载自微信公众号「DYBOY」,新生需懂作者DYBOY 。代农的策转载本文请联系DYBOY公众号。民工
俗话说,略设凡事讲策略。计模讲策略的新生需懂时候,我们往往会考虑每种情况的代农的策成本。策略同样可体现在我们的民工代码之中,合理利用策略模式重构逻辑复杂的略设代码,会使项目工程更易维护和扩展。计模
这几天朋友圈被“新生代农民工”刷屏了,新生需懂看到有这样一张截图:
新生代农民工正名
代码里写了约 30 个 if else 逻辑,代农的策从程序语义以及程序效率理论上是民工会有一定的影响,最主要的略设是可能会被其他“新生代农民工”嘲笑。
一位经验老道的计模民工则会用一手 switch case 或策略模式来重构代码,那么什么是策略模式呐?
一、定义
策略:为实现一定的战略任务,根据形势发展而制定的行动方针和斗争方式。
策略模式:一种行为设计模式,源码下载它能让你定义一系列算法,并将每种算法分别放入独立的类中,以使算法的对象能够相互替换。
在常见的前端游戏奖励激励交互中,常常会涉及到不同分数会展示不同的动效,这其实就是一种条件策略。
二、优缺点
优点:
隔离算法的实现与使用 运行时可切换算法 用组合代替继承 易扩展,符合开闭原则,无需修改上下文即可引入新策略缺点:
需要暴露所有的策略接口,用于区分策略差异 如果逻辑条件简单,使用策略模式会增加代码冗余度三、实现
策略模式指的是定义了一系例算法,把它们每个都封装起来。将不变的部分和变化的部分隔离开来是设计模式中的一个重要思想,策略模式则是将算法和使用算法两部分的实现拆开,降低耦合度。
基于策略模式的云服务器程序至少有两部分组成:策略类和环境类(Context)。
策略类封装了具体的算法,并负责具体的计算过程,可以理解为“执行者”。
环境类(Context)接受客户的请求,然后将请求委托给一个策略类,可以理解为“调度者”。
四、表单验证中的策略模式
在Web项目中,常见的表单有注册、登陆、修改用户信息等涉及到表单的功能,与此同时我们会在表单提交的时候,做一些例的前端输入框值的条件校验工作。
由于输入框中用户的输入是任意的,校验的规则相对比较复杂,如果不使用设计模式,我们的代码中可能就会写出较多的 if else 判断逻辑,源码库从可阅读性和可维护性来说,确实不是很好。
接下来我们将从前端Web项目中常见的表单验证功能,逐步认识策略设计模式。
4.1 初级的表单验证
在很久很久以前,我的表单验证可能是这么写的:
var username = $(#nuserame).val(); var password = $(#password).val(); if (!username) { alert(用户名不能为空); } else if (username.length < 5) { alert(用户名长度需要大于等于5); } else if (username.length < 13) { alert(用户名长度需要小于13); } else if (!(/[a-z]+/i.test(username))) { alert(用户名只能包含英文大小写字符) } else { regeister(username); } // password的验证同上写法似乎有些不忍直视,不过能用!
4.2 基于策略模式的表单验证
换个思路,结合策略模式的思想,实现一个专用于值校验的 Validator 类,Validator 是一个调度着,也就是策略模式中的环境类。
然后我们在验证目标字段值 targetValue 的时候其用法大致如下:
Validator.addRules(targetValue, [isNonEmpty, minLength:5, maxLength:12]).valid();校验器会返回判断结果 result 字段,以及语义话的提示 msg 字段:
return { result: false, msg: 不能为空 }4.2.1 Validator
根据上述需求,Validator的实现如下:
const formatResult = (isPass: boolean = false, errMsg: string = "") => { return { result: isPass, msg: errMsg, }; }; const ValidStrategies = { isNonEmpty: function (val: string = "") { if (!val) return formatResult(false, "内容不能为空"); }, minLength: function (val: string = "", length: string | number = 0) { console.log(val, length); if (typeof length === "string") length = parseInt(length); if (val.length < length) return formatResult(false, `内容长度不能小于${ length}`); }, maxLength: function (val: string = "", length: string | number = 0) { if (typeof length === "string") length = parseInt(length); if (val.length > length) return formatResult(false, `内容长度不能大于${ length}`); }, default: function () { return formatResult(true); }, }; /** * 验证器 * 策略模式 —— 环境类,负责调度算法 */ class Validator { // 存储规则 private _ruleExecuters: Array<any>; constructor() { this._ruleExecuters = []; } /** * addRules * 添加校验规则 */ public addRules(value: string = "", rules: Array<string>) { this._ruleExecuters = []; rules.forEach((rule) => { const args = rule.split(":"); const functionName = args.shift() || "default"; // 忽略下这里的断言类型👀 const ruleFunc = ValidStrategies[ functionName as "isNonEmpty" | "minLength" | "maxLength" | "default" ].bind(this, value); this._ruleExecuters.push({ func: ruleFunc, args, }); }); return this; } /** * valid */ public valid() { for (let i = 0; i < this._ruleExecuters.length; i++) { const res = this._ruleExecuters[i].func.apply( this, this._ruleExecuters[i].args ); if (res && !res.result) { return res; } } return formatResult(true); } } export default new Validator(); const res = Validator.addRules("123", [ "isNonEmpty", "minLength:5", "maxLength:12", ]).valid(); console.log("res:", res);执行结果
这样在验证表单值的时候,我们就可以直接调用 Validator 验证值的合法性。
与此同时,还可以通过扩展策略类(对象)ValidStrategies 中的验证算法来扩展校验器的能力。
五、表驱动法
策略模式节省逻辑判断的特性让我联想到了之前看过的一个概念“表驱动法”,或者叫“查表法”,这里引用下百度百科的解释:
表驱动方法出于特定的目的来使用表,程序员们经常谈到“表驱动”方法,但是课本中却从未提到过什么是"表驱动"方法。表驱动方法是一种使你可以在表中查找信息,而不必用很多的逻辑语句(if 或 Case)来把它们找出来的方法。事实上,任何信息都可以通过表来挑选。在简单的情况下,逻辑语句往往更简单而且更直接。但随着逻辑链的复杂,表就变得越来越富有吸引力了。
举个例子,假设我们想要获取当前是星期几,代码可能是这样的:
function getDay() { const day = (new Date()).getDay(); switch (day) { case 0: return 星期日; case 1: return 星期一; // ... case 6: return 星期六; default: return ; } }如果是初次编程的同学还可能会有 if else 条件语句来判断返回值,代码就会显得比较冗余。
借助表驱动发法的思想,这里我们是可以有优化空间的,表驱动发法的写法如下:
const days = [星期日, 星期一, 星期二, 星期三, 星期四, 星期五, 星期六]; function getDay2() { return days[(new Date()).getDay()]; }当然上述只是一个非常简单的??,大家在编码过程中只需要主要点,如有涉及类似场景,请用这种方式去编码,体验更愉悦!
六、总结
策略设计模式让各种算法的代码、内部数据和依赖关系与其他代码隔离开来。不同客户端可通过一个简单接口执行算法,并能在运行时进行切换。
当然在设计实现程序功能的时候,如果需要使用策略设计模式,也更需要我们的工程师有一个功能全局把控的能力,才能更好将依赖关系拆分,抽象化,以此才能凸显“新生代”民工的不同!
很赞哦!(66)
相关文章
- 比较短的域名方便用户记忆和传播,它带来的好处往往会超过其他类型的域名,如果你非要域名短而且还要包含关键词,那么往往会事与愿违,现在这种域名基本上是可遇而不可求的。
- 面试官:简历上说精通垃圾收集器?来吧,挨个给我说一遍
- 还在担心双十二涨价,Python做一个天猫商品价格监督器
- JavaScript如何实现字符串拼接操作
- 旧域名的外链是否会对新建站点产生影响?
- 使用Java持久化API
- 一个字符串中到底能有多少个字符?我竟然算错了
- 我能够快速读书的秘密:主要靠“猜”!
- 打开https://www.aizhan.com/输入自己想要查询的域名然后按回车键,如果做过网站都会有数据显示出来
- 在Github上,怎么写出教科书级别的readme