持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情
策略模式的定义
- 将定义的一组算法封装起来,使其相互之间可以替换。封装的算法具有一定独立性,不会随客户端变化而变化
- 避免大量的if else或switch case 举个例子,不同类别的顾客(普通顾客/会员顾客/vip顾客)打折情况不同,会员顾客打九折,vip顾客打八折,普通顾客原价。
类图
代码
不考虑使用设计模式,简单实现如下:
class Customer(){
constructor(type){
this.type = type;
}
pay(amount){
if(this.type == 'member'){
return amount*.9;
}
else if(this.type == 'vip'){
return amount*.8;
}
else{
return amount;
}
}
}
let c = new Customer('normal');
console.log(c.pay(100));
缺陷:
- pay逻辑复杂
- 很多if else 那么要如何改进呢?可以考虑使用策略模式:定义多个不同的策略类,再调用不同的策略类即可。这样写就不会再出现大量的if/else,而且pay方法的逻辑也简单了许多。
class Customer(){
constructor(kind){
this.kind = kind;
}
pay(amount){
return this.kind.pay(amount);
}
class Normal{
pay(amount){return amount;}
}
class Member{
pay(amount){return amount*.9;}
}
class VIP{
pay(amount){return amount*.8;}
}
let c1 = new Customer(new Normal());
console.log(c1.pay(100));
c1.kind = new Member;
console.log(c1.pay(100));
也可以使用以下写法,也同样运用了策略模式:在类里面定义几种算法,然后在pay中调用指定算法即可
class Customer(){
constructor(kind){
this.kinds = {
normal:function(amount){return amount;},
member:function(amount){return amount*.9;},
vip:function(amount){return amount*.8;}
};
}
pay(kind,amount){
return this.kind[kind](amount);
}
let c2 = new Customer();
console.log(c2.pay('normal',100));
总结而言,就是给不同的类型,策略,调不同的方法。
应用场景
- form表单不同的校验规则策略
- animate
- animater()方法执行css属性集的自定义动画
- 该方法通过css样式将元素从一个状态改变为另一个状态。
策略模式和状态模式的区别
- 策略模式和状态模式都有上下文,有策略类或者状态类,上下文把这些请求委托给这些类来执行
- 策略模式中各个类是平等的,没有关系,客户端需要知道算法主动切换,状态模式中,状态的切换和行为需要了解细节。