策略模式的使用场景,利用策略模式来避免冗长的if-else或者switch分支判断。还可以像模板模式那样,提供框架的扩展点等等。
策略模式,英文名Strategy Design Pattern。定义一族算法类,将每个算法类封装起来,让它们可以相互替换。策略模式可以使算法类的变化独立于使用它们的客户端。(客户端指的是调用者)
策略模式用来解耦策略的定义、创建和使用。实际上一个完整策略模式就是由这三部分组成起来的。
1、策略的定义
策略类的定义比较简单,包含一个接口和一组实现这个接口的策略类。
2、策略的创建
策略的创建由工厂类来完成,封装策略的创建方式。这里需要分两种情况
a、如果策略类是无状态的,不包含成员变量,只是纯粹的算法实现,这样的策略对象是可以被共享使用的,不需要每次获取策略对象的时候都创建一个新的对象。针对这种情况,我们可以事先创建好每个策略对象,缓存到工厂类中,用的时候直接返回
b、如果策略类有状态,根据业务场景的需求,希望每次都返回一个新的对象。针对这种情况,每次使用的时候都返回一个新创建的策略对象。
3、策略的使用
策略模式包含一组可选策略,客户端代码如何来使用这些策略中的哪一个,有两种确定方法:编译时静态确认和运行时动态确认。其中“运行时动态确认”才是策略模式最典型的应用场景。
策略模式如何移除if-else分支判断?
举个栗子,代码示例如下。根据订单类型来计算商品的折扣。使用的if-else,将策略的定义、创建以及使用直接耦合再一起。
/**
* 订单处理类
*/
public class OrderService {
public double discount(Order order){
double disount=0.0;
String orderType=order.getType();
if(orderType.equals(OrderTypeEnum.NORMAL.getType())){ //普通订单
// ...省略折扣计算算法
}else if(orderType.equals(OrderTypeEnum.GROUPON.getType())){ //团购订单
// ...省略折扣计算算法
}else if(orderType.equals(OrderTypeEnum.PROMOTION.getType())){ //促销订单
// ...省略折扣计算算法
}
return disount;
}
}
那如何使用策略模式移除if-else呢?将策略的定义、策略的创建以及策略的使用分离呢?
1、策略定义
/**
* 折扣策略接口
*/
public interface DiscountStrategy {
//计算折扣
double calDiscount();
}
public class NomalDiscountStrategy implements DiscountStrategy {
@Override
public double calDiscount() {
//..省略计算折扣的实现代码
}
}
public class GrouponDiscountStrategy implements DiscountStrategy {
@Override
public double calDiscount() {
//..省略计算折扣的实现代码
}
}
public class PromotionDiscountStrategy implements DiscountStrategy {
@Override
public double calDiscount() {
//..省略计算折扣的实现代码
}
}
2、策略创建
a、策略类无状态,策略创建代码如下
/**
* 策略类无状态,策略工厂
*/
public class DiscountStrategyFactory {
public static final Map<String,DiscountStrategy> strategys=new HashMap<>();
static {
map.put(OrderTypeEnum.NORMAL.getType(),new NomalDiscountStrategy());
map.put(OrderTypeEnum.GROUPON.getType(),new GrouponDiscountStrategy());
map.put(OrderTypeEnum.PROMOTION.getType(),new PromotionDiscountStrategy());
}
public static DiscountStrategy getInstance(String orderType){
return map.get(orderType);
}
}
b、策略类有状态,策略创建代码如下
/**
* 策略类有状态,策略工厂
*/
public class DiscountStrategyFactory {
public static DiscountStrategy getInstance(String orderType){
if(orderType.equals(OrderTypeEnum.NORMAL.getType())){ //普通订单
return new NomalDiscountStrategy();
}else if(orderType.equals(OrderTypeEnum.GROUPON.getType())){ //团购订单
return new GrouponDiscountStrategy();
}else if(orderType.equals(OrderTypeEnum.PROMOTION.getType())){ //促销订单
return new PromotionDiscountStrategy();
}
return null;
}
}
3、策略使用
重构OrderService,代码如下:
/**
* 订单处理类
*/
public class OrderService {
public double discount(Order order){
double disount=0.0;
String orderType=order.getType();
disount= DiscountStrategyFactory.getInstance(orderType).calDiscount();
return disount;
}
}
类图如下
参考:设计模式之美--王争