策略模式:他定义了一组策略,然后把每个策略都封装起来,每个策略可以互相替换,互相搭配的使用,
从而满足不同场景使用不同策略的需求,我们把策略的实现和使用剖离出来。
使用的场景:多种校验规则封装…
举个例子:
在Dota的世界里,存在着一个大魔王——肉山,将他击败,我们可以得到肉山盾(原地复活一次),
我们如果想单挑过它,就需要一些条件,需要特定的英雄,等级,装备等等…
假如说,这个英雄是拍拍熊,他至少需要11级,还需要一个吸血buff
最简单的写法那肯定直接如下
1 2 3 4 5 6
| function isOk(data) { if (data.hero !== "拍拍熊") return false; if (data.level < 11) return false; if (!data.morbidBuff) return false; return true; }
|
看着有很多if,哈哈还可以这么写
1 2 3 4 5 6
| function isOk(data) { if (data.hero !== "拍拍熊" || data.level < 11 || !data.morbidBuff) { return false; } return true; }
|
上面两种方法都可以完成需求,也都没有问题.或许只是在拓展性和复用性上差了一点。
下面让我们来试试策略模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| const heros = ["拍拍熊", "剑圣", "幻影刺客", "小狗", "骷髅王"]; export const strategies = { handleHero: (hero: string) => { return heros.includes(hero); // 只能是指定英雄 }, handleHeroLevel: (level: number | string) => { return level >= 11; // 英雄至少要达到11级 }, handleMorbidBuff: (flag: boolean) => { return flag; // 肉山是否存在 } }
export class Strategies { constructor() { this.cache = []; } add(method, value) { this.cache.push(() => { return strategies[method](value); }) } handleValidator() { const cacheLength = this.cache.length; if (cacheLength === 0) return false; for (let i = 0; i < cacheLength; i++) { const result = this.cache[i](); if (!result) { return false; } } return true; } }
const validator = new Strategies(); validator.add("handleHero", "剑圣"); validator.add("handleHeroLevel", 1); validator.add("handleMorbidBuff", false); const result = validator.handleValidator(); console.log(result);
|
效果也特别好,他的优点就是拓展性和自由度比较高,可以自己搭配规则.如果规则场景
比较多,是不是可以考虑策略模式是个更好的选择呢?
写在最后,我们并不是说忌惮if else,if else非常的好,甚至是不可避免的,
只要使用的恰当,它会让代码看上去特别清晰和简单,我们在这里只是提供了另一种思路.
我的微信公众号: 梨的前端小屋