这篇博客并不是介绍策略模式的,网上对策略模式介绍已经很多了,具体的UML图,如下图中,不带X的,就是原版的策略模式,下面是个人的改进意见,有不同意见的欢迎讨论,轻喷……
原本的策略模式的缺点
- Client与Context和Sale都有关联,导致Client和具体的策略方法都耦合在一起
- 策略的创建方法都放在Client客户端,如果策略过多,势必加大了客户端业务的复杂性
- 策略过多的暴露出来,也不利于策略的维护
个人修改意见(去掉X掉的3条线)
- 我将策略方位Context中,并在init方法中初始化并维护,在实际开发中,大多数情况应该是从数据库中获取数据,并生成相应的策略
- 策略不再从Client客户端获得,这样的好处是,客户端不用和具体的策略发生联系,当后期修改策略,也就方便很多了
- Client客户端
public class Client {
public static void main(String[] args) {
Double price = 200d;
Context context = new Context(1);
price = context.strategy(price);
System.out.println(price);
}
}
- Context 用于管理策略和执行策略,当然,在实际开发中,根据单一职责原则,应该将管理策略和执行策略分开,方便后期代码的修改或者维护
/*
1.它的职责是执行策略,如果执行策略的方式变了,就需要修改它
2.所以我们还需要一个容器,用户存储策略(init是初始化策略的方法)
*/
class Context {
Map<Integer,Sale> strategy = new HashMap<Integer,Sale>();
Sale sale = null;
public Context(int activity){
init();
sale = strategy.get(activity);
}
/*
打折策略的方案:
1.正常价格
2.满300 - 100
3.满200 - 50
4.打9.5折扣
5.打8.5折
*/
private void init(){
strategy.put(1,new Discount(1d));
strategy.put(2,new FullReduction(300d,100d));
strategy.put(3,new FullReduction(200d,50d));
strategy.put(4,new Discount(0.95));
strategy.put(5,new Discount(0.85));
}
//执行策略
public double strategy(double price){
return sale.getResult(price);
}
}
- 下面是策略的接口,和对应的子类,这里模拟的是超市满减和打折的策略
package com.design;
public interface Sale {
Double getResult(Double price);
}
/*
* 满减
*/
class FullReduction implements Sale {
Double full = 0d; //满多少
Double reduction = 0d;//减少多少
public FullReduction(Double full,Double reduction){
this.full = full;
this.reduction = reduction;
}
@Override
public Double getResult(Double price) {
if(full <= price){
price = price - reduction;
}
return price;
}
}
// 打折
class Discount implements Sale {
Double discount = 0d;
public Discount(Double discount){
this.discount = discount;
}
@Override
public Double getResult(Double price) {
return discount * price;
}
}
总结
- 策略模式常常用在,系统中有许多算法,并且算法会常常更换,而且算法能够相互替换
- 如果你的业务满足这个场景,可以参考策略模式,看是否满足你的需求