策略模式
策略模式定义了一系列的算法,并将每一个算法封装起来,使每个算法可以相互替代,使算法本身和使用算法的客户端分割开来,相互独立。
我们假设一种创景,商品打折活动,针对新客户9折,针对老客户8.8折,针对VIP客户5折,下面我们来用策略模式实现一下。
类图:
代码实现:
/**
* 策略模式-价格
*/
public interface PriceStrategy {
/**
* 获取价格
* @param originalPrice 原始价格
* @return 不同客户优惠后的价格
*/
BigDecimal getPrice(BigDecimal originalPrice);
}
/**
* 新客策略类
*/
public class NewCustomerStrategy implements PriceStrategy{
@Override
public BigDecimal getPrice(BigDecimal originalPrice) {
System.out.println("新客9折");
return originalPrice.multiply(new BigDecimal(0.9).setScale(2, BigDecimal.ROUND_HALF_UP));
}
}
/**
* 老客策略类
*/
public class OldCustomerStrategy implements PriceStrategy{
@Override
public BigDecimal getPrice(BigDecimal originalPrice) {
System.out.println("老客8折");
return originalPrice.multiply(new BigDecimal(0.8).setScale(2, BigDecimal.ROUND_HALF_UP));
}
}
/**
* vip策略类
*/
public class VipCustomerStrategy implements PriceStrategy {
@Override
public BigDecimal getPrice(BigDecimal originalPrice) {
System.out.println("vip5折");
return originalPrice.multiply(new BigDecimal(0.5).setScale(2, BigDecimal.ROUND_HALF_UP));
}
}
/**
* 报价上下文
*/
public class QuoteContext {
/**
* 持有报价策略
*/
private PriceStrategy strategy;
/**
* 注入报价策略
* @param strategy
*/
public QuoteContext(PriceStrategy strategy) {
this.strategy = strategy;
}
/**
* 回调具体的报价策略方法
* @param originalPrice 原始价格
* @return
*/
public BigDecimal contextMethod(BigDecimal originalPrice){
return strategy.getPrice(originalPrice);
}
}
public class PriceStrategyTest {
public static void main(String[] args) {
//创建新客报价策略
PriceStrategy priceStrategy = new NewCustomerStrategy();
//创建报价上下文,并设置具体的报价策略
QuoteContext context = new QuoteContext(priceStrategy);
//调用报价上下文的方法
BigDecimal price = context.contextMethod(new BigDecimal(100));
System.out.println("新客的到手价格:"+ price);
}
}
上述例子中,我们首先创建了一个价格策略接口PriceStrategy,其次我们定义了三种客群(其实对应三个实际策略类),QuoteContext实际上是使用了某种策略的类。
策略模式的结构
策略接口PriceStrategy:策略接口,用来约束一系列策略算法
具体的策略实现NewCustomerStrategy、OldCustomerStrategy 、VipCustomerStrategy:具体的策略实现,也就是具体的策略算法
策略上下文QuoteContext:策略上下文,负责和具体的策略实现交互
策略模式的作用
就是把具体的算法实现从业务逻辑中剥离出来,成为一系列独立算法类,使得它们可以相互替换。
策略模式的着重点
策略模式就是把各个平等的具体实现进行抽象、封装成为独立的算法类,然后通过上下文和具体的算法类来进行交互。各个策略算法都是平等的,地位是一样的,正是由于各个算法的平等性,所以它们才是可以相互替换的。虽然我们可以动态的切换各个策略,但是同一时刻只能使用一个策略。
策略模式的本质:
分离算法,选择实现。
如果你仔细思考策略模式的结构和功能的话,就会发现:如果没有上下文,策略模式就回到了最基本的接口和实现了,只要是面向接口编程,就能够享受到面向接口编程带来的好处,通过一个统一的策略接口来封装和分离各个具体的策略实现,无需关系具体的策略实现。
貌似没有上下文什么事,但是如果没有上下文的话,客户端就必须直接和具体的策略实现进行交互了,尤其是需要提供一些公共功能或者是存储一些状态的时候,会大大增加客户端使用的难度;引入上下文之后,这部分工作可以由上下文来完成,客户端只需要和上下文进行交互就可以了。这样可以让策略模式更具有整体性,客户端也更加的简单。
策略模式体现了开闭原则:策略模式把一系列的可变算法进行封装,从而定义了良好的程序结构,在出现新的算法的时候,可以很容易的将新的算法实现加入到已有的系统中,而已有的实现不需要修改。
策略模式体现了里氏替换原则:策略模式是一个扁平的结构,各个策略实现都是兄弟关系,实现了同一个接口或者继承了同一个抽象类。这样只要使用策略的客户端保持面向抽象编程,就可以动态的切换不同的策略实现以进行替换。
参考:https://blog.csdn.net/tugangkai/article/details/88074288
网友评论