使用策略模式的原因
在项目的起始阶段通常需求还是很明确的,但是到了后期因为各种需求的叠加,会导致业务逻辑中存在一长串的if else
或者switch case
,长达10
几个的if else
容易让人看着眼花,不利于代码阅读。所以用策略模式去改善是非常有必要的。
策略模式使用demo
这里就拿订单状态来改造一波,原始代码如下
switch (orderInfoDO.getOrderStatus().toString()){
case "UNPAID":
vo.setOrderStatusDescription("未支付");
break;
case "GRABBING":
vo.setOrderStatusDescription("抢单中");
break;
case "DOING":
vo.setOrderStatusDescription("进行中");
break;
。
。
。
}
使用策略模式
先设计一个接口
package com.xx.xx..strategy;
import com.xx.xx.enums.OrderStatus;
public interface OrderStatusStrategy {
//获取订单状态枚举
OrderStatus getOrderStatusEnum();
//获取订单状态描述
String getOrderStatusDescription();
//解析参数,todo
void reSolve(Object param);
}
未支付状态
package com.xx.xx.strategy;
import com.xx.xx.enums.OrderStatus;
import org.springframework.stereotype.Component;
@Component
public class UnpaidStatusStrategy implements OrderStatusStrategy{
@Override
public OrderStatus getOrderStatusEnum() {
return OrderStatus.UNPAID;
}
@Override
public String getOrderStatusDescription() {
return "未支付";
}
@Override
public void reSolve(Object param) {
}
}
抢单中状态
package com.xx.xx.strategy;
import com.xx.xx.enums.OrderStatus;
import org.springframework.stereotype.Component;
@Component
public class GrabbingStatusStrategy implements OrderStatusStrategy{
@Override
public OrderStatus getOrderStatusEnum() {
return OrderStatus.GRABBING;
}
@Override
public String getOrderStatusDescription() {
return "抢单中";
}
@Override
public void reSolve(Object param) {
}
}
以此类推
.
.
.
策略对外使用service
package com.xx.xx.strategy;
import com.xx.xx.enums.OrderStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
@Component
public class OrderStatusStrategyService implements ApplicationContextAware {
private ApplicationContext applicationContext;
private ConcurrentHashMap<OrderStatus, OrderStatusStrategy> orderStatusStrategyMap = new ConcurrentHashMap<>();
public String getOrderStatusDescription(OrderStatus orderStatus){
OrderStatusStrategy orderStatusStrategy = orderStatusStrategyMap.get(orderStatus);
if(Objects.isNull(orderStatusStrategy)){
log.error("未获取到对应策略 orderStatus:{}, orderStatusStrategyMap.values:{}", orderStatus, orderStatusStrategyMap.keySet());
return "";
}
return orderStatusStrategy.getOrderStatusDescription();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
Map<String, OrderStatusStrategy> strategyMap = this.applicationContext.getBeansOfType(OrderStatusStrategy.class);
strategyMap.values().forEach(el -> orderStatusStrategyMap.put(el.getOrderStatusEnum(), el));
}
}
将switchcase
改成策略模式之后
可以看到代码清晰多了,扩展性也强了
vo.setOrderStatusDescription(orderStatusStrategyService.getOrderStatusDescription(orderInfoDO.getOrderStatus()));