一、策略设计模式简介
策略模式(Strategy Pattern)
- 定义⼀系列的算法,把它们⼀个个封装起来, 并且使它们可相互替换
- 淘宝天猫双⼗⼀,正在搞活动有打折的、有满减的、有返利的等等,这些算法只是⼀种策略,并且是随时都可 能互相替换的, 我们就可以定义⼀组算法,将每个算法都封装起来,并且使它们之间可以互换
应用场景
- 计划外出旅游,可以选择骑⾃⾏⻋、坐汽⻋、⻜机等, 每⼀种旅⾏⽅式都是⼀个策略
- 如果在⼀个系统⾥⾯有许多类,它们之间的区别仅在于它们的⾏为,那么可以使⽤策略模式
- 不希望暴露复杂的、与算法有关的数据结构,那么可以使⽤策略模式来封装算法
角色
- Context上下⽂:屏蔽⾼层模块对策略、算法的直接访问,封装可能存在的变化
- Strategy策略⻆⾊:抽象策略⻆⾊,是对策略、算法家族的抽象,定义每个策略或算法必须具有的⽅法和属性
- ConcreteStrategy具体策略⻆⾊:⽤于实现抽象策略中的操作,即实现具体的算法
二、优缺点
优点:
- 满⾜开闭原则,当增加新的具体策略时,不需要修改上 下⽂类的代码,上下⽂就可以引⽤新的具体策略的实例
- 避免使⽤多重条件判断,如果不⽤策略模式可能会使⽤ 多重条件语句不利于维护,和⼯⼚模式的搭配使⽤可以 很好地消除代码if-else的多层嵌套(⼯⼚模式主要是根 据参数,获取不同的策略)
缺点:
- 策略类数量会增多,每个策略都是⼀个类,复⽤的可能 性很小
- 对外暴露了类所有的⾏为和算法,⾏为过多导致策略类膨胀
三、代码实现
/**
*抽象策略⻆⾊
**/
public abstract class Strategy {
/**
* 根据简单订单对象,计算商品折扣后的价格
* @param productOrder
* @return
*/
public abstract double computePrice(ProductOrder productOrder);
}
/**
* 订单类
**/
public class ProductOrder {
private double oldPrice;
private int userId;
private int productId;
public ProductOrder(double oldPrice, int userId, int productId){
this.oldPrice = oldPrice;
this.userId = userId;
this.productId = productId;
}
public double getOldPrice() {
return oldPrice;
}
public void setOldPrice(double oldPrice) {
this.oldPrice = oldPrice;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public int getProductId() {
return productId;
}
public void setProductId(int productId) {
this.productId = productId;
}
}
/**
*无折扣具体策略
**/
public class NormalActivity extends Strategy{
@Override
public double computePrice(ProductOrder productOrder) {
//直接返回价格
return productOrder.getOldPrice();
}
}
/**
* 打折具体策略
**/
public class DiscountActivity extends Strategy{
/**
* 具体的折扣
*/
private double rate;
public DiscountActivity(double rate){
this.rate = rate;
}
@Override
public double computePrice(ProductOrder productOrder) {
//一系列复杂的计算,返回折扣后价格
return productOrder.getOldPrice() * rate;
}
}
/**
*优惠券具体策略
**/
public class VoucherActivity extends Strategy {
/**
* 传入优惠券
*/
private double voucher;
public VoucherActivity(double voucher){
this.voucher = voucher;
}
@Override
public double computePrice(ProductOrder productOrder) {
if(productOrder.getOldPrice() > voucher){
return productOrder.getOldPrice() - voucher;
}else {
return 0;
}
}
}
/**
* 促销活动类--策略上下文
**/
public class PromotionContext {
private Strategy strategy;
public PromotionContext(Strategy strategy){
this.strategy = strategy;
}
/**
* 根据策略计算最终的价格
* @param productOrder
* @return
*/
public double executeStrategy(ProductOrder productOrder){
return strategy.computePrice(productOrder);
}
}
public class Main {
public static void main(String[] args) {
ProductOrder productOrder = new ProductOrder(1000,1,10);
//无折扣
PromotionContext promotionContext1 = new PromotionContext(new NormalActivity());
System.out.println(promotionContext1.executeStrategy(productOrder));
//打八折
PromotionContext promotionContext2 = new PromotionContext(new DiscountActivity(0.8));
System.out.println(promotionContext2.executeStrategy(productOrder));
//300优惠券
PromotionContext promotionContext3 = new PromotionContext(new VoucherActivity(300));
System.out.println(promotionContext3.executeStrategy(productOrder));
}
}
注释:个人学习观点以作笔记,如有瑕疵望谅解