抽象策略类
先定义一个接口,这个接口就是抽象策略类,该接口定义了计算价格方法,具体实现方式由具体的策略类来定义。
public interface Buyer {
/**
* 计算应付价格
*/
public BigDecimal calPrice(BigDecimal orderPrice);
}
具体策略类
针对不同的会员,定义三种具体的策略类,每个类中都分别实现计算价格方法。
/**
* 专属会员
*/
public class ParticularlyVipBuyer implements Buyer {
@Override
public BigDecimal calPrice(BigDecimal orderPrice) {
if (orderPrice.compareTo(new BigDecimal(30)) > 0) {
return orderPrice.multiply(new BigDecimal(0.7));
}
}
}
/**
* 超级会员
*/
public class SuperVipBuyer implements Buyer {
@Override
public BigDecimal calPrice(BigDecimal orderPrice) {
return orderPrice.multiply(new BigDecimal(0.8));
}
}
/**
* 普通会员
*/
public class VipBuyer implements Buyer {
@Override
public BigDecimal calPrice(BigDecimal orderPrice) {
int superVipExpiredDays = getSuperVipExpiredDays();
int superVipLeadDiscountTimes = getSuperVipLeadDiscountTimes();
if(superVipExpiredDays < 7 && superVipLeadDiscountTimes =0){
return orderPrice.multiply(new BigDecimal(0.8));
}
return orderPrice.multiply(new BigDecimal(0.9));
}
}
上面几个类的定义体现了封装变化的设计原则,不同会员的具体折扣方式改变不会影响到其他的会员。
定义好了抽象策略类和具体策略类之后,我们再来定义上下文类,所谓上下文类,就是集成算法的类。这个例子中就是收银台系统。采用组合的方式把会员集成进来。
public class Cashier {
/**
* 会员,策略对象
*/
private Buyer buyer;
public Cashier(Buyer buyer){
buyer = buyer;
}
public BigDecimal quote(BigDecimal orderPrice) {
return this.buyer.calPrice(orderPrice);
}
}
这个Cashier类就是一个上下文类,该类的定义体现了多用组合,少用继承、针对接口编程,不针对实现编程两个设计原则。
由于这里采用了组合+接口的方式,后面我们在推出其他类型会员的时候无须修改Cashier类。只要再定义一个类实现Buyer接口 就可以了。
除了增加会员类型以外,我们想要修改某个会员的折扣情况的时候,只需要修改该会员对应的策略类就可以了,不需要修改到其他的策略。也就控制了变更的范围。大大降低了成本。
下面定义一个客户端来测试一下:
public class Test {
public static void main(String[] args) {
//选择并创建需要使用的策略对象
Buyer strategy = new VipBuyer();
//创建上下文
Cashier cashier = new Cashier(strategy);
//计算价格
BigDecimal quote = cashier.quote(300);
System.out.println("普通会员商品的最终价格为:" + quote.doubleValue());
strategy = new SuperVipBuyer();
cashier = new Cashier(strategy);
quote = cashier.quote(300);
System.out.println("超级会员商品的最终价格为:" + quote.doubleValue());
}
}
输出结果:
//普通会员商品的最终价格为:270.0
//超级会员商品的最终价格为:240.0
从上面的示例可以看出,策略模式仅仅封装算法,提供新的算法插入到已有系统中,策略模式并不决定在何时使用何种算法。在什么情况下使用什么算法是由客户端决定的。