设计模式---策略模式

策略模式(前端)

策略模式指的是定义一些列的算法,把他们一个个封装起来,目的就是将算法的使用与算法的实现分离开来,避免多重判断条件,更具有扩展性。
下面也是举个例子,现在超市有活动,vip为5折,老客户3折,普通顾客没折,计算***需要支付的金额,如果不使用策略模式,我们的代码可能和下面一样:

function Price(personType, price) { 
 //vip 5 折 
 if (personType == 'vip') { 
 return price * 0.5; 
 }  
 else if (personType == 'old'){ //老客户 3 折 
 return price * 0.3; 
 } else { 
 return price; //其他都全价 
 } 
} 

在上面的代码中,我们需要很多个判断,如果有很多优惠,我们又需要添加很多判断,这里已经违背了刚才说的设计模式的六大原则中的开闭原则了,如果使用策略模式,我们的代码可以这样写:

// 对于vip客户 
function vipPrice() { 
 this.discount = 0.5; 
} 
  
vipPrice.prototype.getPrice = function(price) { 
 return price * this.discount; 
} 
// 对于老客户 
function oldPrice() { 
 this.discount = 0.3; 
} 
  
oldPrice.prototype.getPrice = function(price) { 
 return price * this.discount; 
} 
// 对于普通客户 
function Price() { 
 this.discount = 1; 
} 
  
Price.prototype.getPrice = function(price) { 
 return price ; 
} 
// 上下文,对于客户端的使用 
function Context() { 
 this.name = ''; 
 this.strategy = null; 
 this.price = 0; 
} 
  
Context.prototype.set = function(name, strategy, price) { 
 this.name = name; 
 this.strategy = strategy; 
 this.price = price; 
} 
Context.prototype.getResult = function() { 
 console.log(this.name + ' 的结账价为: ' + this.strategy.getPrice(this.price)); 
} 
var context = new Context(); 
var vip = new vipPrice(); 
context.set ('vip客户', vip, 200); 
context.getResult(); // vip客户 的结账价为: 100 
var old = new oldPrice(); 
context.set ('老客户', old, 200); 
context.getResult(); // 老客户 的结账价为: 60 
var Price = new Price(); 
context.set ('普通客户', Price, 200); 
context.getResult(); // 普通客户 的结账价为: 200 

总结:在上面的代码中,通过策略模式,使得客户的折扣与算法解藕,又使得修改跟扩展能独立的进行,不影到客户端或其他算法的使用。

当我们的代码中有很多个判断分支,每一个条件分支都会引起该“类”的特定行为以不同的方式作出改变,这个时候就可以使用策略模式,可以改进我们代码的质量,也更好的可以进行单元测试。

策略模式(后端)

在这里插入图片描述
其中,Context是上下文,用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用;Strategy是策略类,用于定义所有支持算法的公共接口;ConcreteStrategy是具体策略类,封装了具体的算法或行为,继承于Strategy。

1. Context上下文
  Context上下文角色,也叫Context封装角色,起承上启下的作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。

 1 public class Context {
 2     
 3     Strategy strategy;
 4     
 5     public Context(Strategy strategy) {
 6         this.strategy = strategy;
 7     }
 8     
 9     //上下文接口
10     public void contextInterface() {
11         strategy.algorithmInterface();
12     }
13 
14 }

2. 策略角色
  抽象策略角色,是对策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性。algorithm是“运算法则”的意思。

1 public abstract class Strategy {
2     
3     //算法方法
4     public abstract void algorithmInterface();
5 
6 }

3. 具体策略角色
  用于实现抽象策略中的操作,即实现具体的算法,下方用print代替。测试类共3个ConcreteStrategy,其它两个类与ConcreteStrategyA同理,就不再赘述了。

1 public class ConcreteStrategyA extends Strategy {
2 
3     @Override
4     public void algorithmInterface() {
5         System.out.println("算法A实现");
6     }
7 
8 }

4. Client客户端
  下面依次更换策略,测试一下策略模式。

 1 public class Client {
 2     
 3     public static void main(String[] args) {
 4         Context context;
 5         
 6         context = new Context(new ConcreteStrategyA());
 7         context.contextInterface();
 8         
 9         context = new Context(new ConcreteStrategyB());
10         context.contextInterface();
11         
12         context = new Context(new ConcreteStrategyC());
13         context.contextInterface();
14     }
15 
16 }

在这里插入图片描述

策略模式的应用

1. 何时使用
一个系统有许多类,而区分它们的只是他们直接的行为时
2. 方法
将这些算法封装成一个一个的类,任意的替换
3. 优点
算法可以自由切换
避免使用多重条件判断(如果不用策略模式我们可能会使用多重条件语句,不利于维护)
扩展性良好,增加一个策略只需实现接口即可
4. 缺点
策略类数量会增多,每个策略都是一个类,复用的可能性很小
所有的策略类都需要对外暴露
5. 使用场景
多个类只有算法或行为上稍有不同的场景
算法需要自由切换的场景
需要屏蔽算法规则的场景
6. 应用实例
出行方式,自行车、汽车等,每一种出行方式都是一个策略
商场促销方式,打折、满减等
Java AWT中的LayoutManager,即布局管理器
7. 注意事项
如果一个系统的策略多于四个,就需要考虑使用混合模式来解决策略类膨胀的问题

参考: https://www.cnblogs.com/adamjwh/p/11011095.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值