js设计模式之策略模式


策略模式:他定义了一组策略,然后把每个策略都封装起来,每个策略可以互相替换,互相搭配的使用,
从而满足不同场景使用不同策略的需求,我们把策略的实现和使用剖离出来。

使用的场景:多种校验规则封装…

举个例子:
在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非常的好,甚至是不可避免的,
只要使用的恰当,它会让代码看上去特别清晰和简单,我们在这里只是提供了另一种思路.

我的微信公众号: 梨的前端小屋


文章作者: 梨啊梨
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 梨啊梨 !
  目录