轻便更换策略
- 概念
- 类图
- 代码实例
概念
当不同时间段,业务上会采取不同的策略,这个可以采用策略模式,将一种抽象计算方式通过一个Context类暴露给Client,然后在Context中会根据条件选择具体的算法实现策略。一种方式是通过客户端决定具体的算法策略通过Context()构造方法传入,还有一种方式通过简单工厂方式,传入一个type创建具体算法策略由Context决定,第二种方式更大降低了与客户端的的耦合性
好处:可以轻松的替换和增加具体算法策略,不会影响客户端,降低了耦合性。
类图
Strategy:抽象策略接口
ConcreteStrategy:具体的一种策略
Context:上下文类,暴露给客户端,里面包含Strategy
Client:客户端类,通过Context来使用一种具体策略完成对应的逻辑
代码实例
场景:
设计一个店员计费器,可以输入商品的单价和数量,最终获取总额,其中可能会有活动,商品打折情况,满多少减多少情况等各种策略(算法),为了替换算法时不会影响客户端,采用策略模式。
CashSuper接口(Strategy)
/**
* @author duanyimiao
* @create 2018-09-11 6:09 PM
* @description 定义一个抽象的收费抽象类
**/
public abstract class CashSuper {
/**
*
* @param money 原始金额
* @return 优惠后的金额
*/
public abstract double acceptCash(double money);
}
CashNormal具体策略类(ConcreteStrategy1)
/**
* @author duanyimiao
* @create 2018-09-11 6:12 PM
* @description 正常计费
**/
public class CashNormal extends CashSuper{
@Override
public double acceptCash(double money) {
return money;
}
}
CashRebate具体策略类(ConcreteStrategy2)
/**
* @author duanyimiao
* @create 2018-09-11 6:12 PM
* @description 折扣
**/
public class CashRebate extends CashSuper {
private double moneyRebate = 1;
public CashRebate() {
}
public CashRebate(String rebate) {
this.moneyRebate = Double.parseDouble(rebate);
}
@Override
public double acceptCash(double money) {
return money*moneyRebate;
}
}
CashReturn具体策略类(ConcreteStrategy3)
/**
* @author duanyimiao
* @create 2018-09-11 6:12 PM
* @description 满多少减多少
**/
public class CashReturn extends CashSuper {
private double moneyCondition;
private double moneyReturn;
public CashReturn() {
}
public CashReturn(String moneyCondition, String moneyReturn) {
this.moneyCondition = Double.parseDouble(moneyCondition);
this.moneyReturn = Double.parseDouble(moneyReturn);
}
@Override
public double acceptCash(double money) {
return money - (Math.floor(money/moneyCondition)*moneyReturn);
}
}
CashContext(Context)策略上下文
* @author duanyimiao
* @create 2018-09-11 6:35 PM
* @description CashContext中的getMoney()方法暴露给client端
*
* 策略模式和简单工厂模式结合
**/
public class CashContext {
private CashSuper cashSuper;
public CashContext() {
}
public CashContext(String discountWay) {
switch (discountWay) {
case "five-discount":
cashSuper = new CashRebate("0.5");
break;
case "eight-discount":
cashSuper = new CashRebate("0.8");
break;
case "util 50 return 1":
cashSuper = new CashReturn("50", "1");
break;
default:
cashSuper = null;
}
}
//此方法暴露给Client,避免将CashSuper类以及其方法暴露到客户端,客户端只需要Context类就行,关于其内部的具体实现逻辑无需care
public double getMoney(double money){
return cashSuper.acceptCash(money);
}
}
Client 客户端类
/**
* @author duanyimiao
* @create 2018-09-11 6:36 PM
* @description
**/
public class Client {
public static void main(String[] args) {
/**
* 客户端只知道CashContext,通过传入type,最终获取到计算后结果,无须关注具体这些计算的方式
*/
CashContext cashContext1 = new CashContext("eight-discount");
double money1 = 100*1;
double total1 = cashContext1.getMoney(money1);
double money2 = 50*3;
CashContext cashContext2 = new CashContext("util 50 return 1");
double total2 = cashContext2.getMoney(money2);
System.out.println("total "+(total1+total2));
}
}
输出结果:
total 227.0