- • 使用策略模式重构后,我们后续仅需配置的方式来完成。
- • 扩展题目:那如果想给用户名还想再添加一个规则,那如何完成呢?
- • 添加规则方式如下:
validator.add(username, [ { strategy: "isEmpty", msg: "用户名不能为空" }, { strategy: 'minLength:6', msg: '密码不能少于 6 位' } ]);
- • 实现:
let infoForm = { username: "阿斯顿发生的", password: "ss1sdf", tel: 15829485647, }; var strategies = { isEmpty: function (val, msg) { if (!val) return msg; }, minLength: function (val, length, msg) { if (val.length < length) return msg; }, isTel: function (val, msg) { if (!/(^1[3|5|8][0-9]{9}$)/.test(val)) return msg; }, }; var validFn = function () { var validator = new Validator(); let { username, password, tel } = infoForm; validator.add(username, [ { strategy: "isEmpty", msg: "用户名不能为空", }, { strategy: "minLength:6", msg: "密码不能少于 6 位", }, ]); validator.add(password, [ { strategy: "minLength:6", msg: "密码不能少于 6 位", }, ]); validator.add(tel, [ { strategy: "isTel", msg: "手机号码格式不正确", }, ]); var msg = validator.start(); return msg; }; class Validator { constructor() { this.cache = []; } add(attr, rules) { for (let i = 0; i < rules.length; i++) { var rule = rules[i]; var ruleArr = rule.strategy.split(":"); var msg = rule.msg; var cacheItem = this.createCacheItem(ruleArr, attr, msg); this.cache.push(cacheItem); } } start() { for (let i = 0; i < this.cache.length; i++) { var msg = this.cache[i](); if (msg) return msg; } } createCacheItem(ruleArr, attr, msg) { return function () { var strategy = ruleArr.shift(); ruleArr.unshift(attr); ruleArr.push(msg); return strategies[strategy].apply(attr, ruleArr); }; } } function submit() { let msg = validFn(); if (msg) { Toast(msg); return false; } console.log("verify success"); // ..... } submit();
策略模式的优缺点
- • 优点:
- 1. 利用组合,委托,多态等技术有效避免了多重条件语句
- 2. 提供了对开封-封闭原则的完美支持
- 3. 复用性较强,避免许多重复的 C,V 工作
- • 缺点:
- 1. 客户端要先了解所有的策略类,才能选择合适的策略类。
策略模式的角色
- 1.
Context(环境类)
:持有一个 Strategy 类的引用,用一个 ConcreteStrategy 对象来配置 - 2.
Strategy(环境策略类)
:定义了所有支持的算法的公共接口,通常是以一个接口或抽象来实现。Context 使用这个接口来调用其 ConcreteStrategy 定义的算法。 - 3.
ConcreteStrategy(具体策略类)
:以 Strategy 接口实现某种算法
- • 比如以上的例子算法:
策略模式的应用场景
- 1. 想使用对象中各种不同算法变体来在运行时切换算法时
- 2. 拥有很多在执行某些行为时有着不同的规则时
Tip: 文章部分内容参考于曾探
大佬的《JavaScript 设计模式与开发实践》。文章仅做个人学习总结和知识汇总。
特殊字符描述
•问题标注 Q:(question)
•答案标注 R:(result)
•注意事项标准:A:(attention matters)
•详情描述标注:D:(detail info)
•总结标注:S:(summary)
•分析标注:Ana:(analysis)
•提示标注:T:(tips)