else 策略模式去掉if_还在用if else?策略模式了解一下!

本文介绍了如何在订单取消业务中使用策略模式替代if else,提高代码可读性和灵活性。通过创建策略接口和具体策略实现,结合注解及策略上下文,实现了根据订单类型自动调用相应处理逻辑,简化了代码维护。
摘要由CSDN通过智能技术生成

在公司负责的就是订单取消业务,老系统中各种类型订单取消都是通过if else 判断不同的订单类型进行不同的逻辑。在经历老系统的折磨和产品需求的不断变更,决定进行一次大的重构:消灭 if else。

接下来就向大家介绍下是如何消灭 if else。

1. if else模式

@Service

public class CancelOrderService {

public void process(OrderDTO orderDTO) {

int serviceType = orderDTO.getServiceType();

if (1 == serviceType) {

System.out.println("取消即时订单");

} else if (2 == serviceType) {

System.out.println("取消预约订单");

} else if (3 == serviceType) {

System.out.println("取消拼车订单");

}

}

}

若干个月再来看就是这样的感觉

2. 策略模式

2.1 策略模式实现的Service

@Service

public class CancelOrderStrategyService {

@Autowired

private StrategyContext context;

public void process(OrderDTO orderDTO) {

OrderTypeEnum orderTypeEnum = OrderTypeEnum.getByCode(orderDTO.getServiceType());

AbstractStrategy strategy = context.getStrategy(orderTypeEnum);

strategy.process(orderDTO);

}

}

简洁的有点过分了是不是!!!

2.2 各种类型策略实现及抽象策略类

下面选取了即时订单和预约订单的策略.

@Service

@OrderTypeAnnotation(orderType = OrderTypeEnum.INSTANT)

public class InstantOrderStrategy extends AbstractStrategy {

@Override

public void process(OrderDTO orderDTO) {

System.out.println("取消即时订单");

}

}

@Service

@OrderTypeAnnotation(orderType = OrderTypeEnum.BOOKING)

public class BookingOrderStrategy extends AbstractStrategy {

@Override

public void process(OrderDTO orderDTO) {

System.out.println("取消预约订单");

}

}

public abstract class AbstractStrategy {

abstract public void process(OrderDTO orderDTO);

}

2.3 策略类型注解

每个策略中增加了注解OrderTypeAnnotation,以标注适用于不同类型的策略内容.

@Target({ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Inherited

public @interface OrderTypeAnnotation {

OrderTypeEnum orderType();

}

2.4 策略处理器类StrategyProcessor和策略上下文StrategyContext

其中最为核心的为StrategyProcessor 策略处理器类和StrategyContext 策略上下文,

@Component

public class StrategyProcessor implements BeanFactoryPostProcessor {

private static final String STRATEGY_PACKAGE = "com.lujiahao.strategy";

@Override

public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

Map handlerMap = Maps.newHashMapWithExpectedSize(3);

ClassScanner.scan(STRATEGY_PACKAGE, OrderTypeAnnotation.class).forEach(clazz -> {

OrderTypeEnum type = clazz.getAnnotation(OrderTypeAnnotation.class).orderType();

handlerMap.put(type, clazz);

});

StrategyContext context = new StrategyContext(handlerMap);

configurableListableBeanFactory.registerSingleton(StrategyContext.class.getName(), context);

}

}

public class StrategyContext {

private Map strategyMap;

public StrategyContext(Map strategyMap) {

this.strategyMap = strategyMap;

}

public AbstractStrategy getStrategy(OrderTypeEnum orderTypeEnum) {

if (orderTypeEnum == null) {

throw new IllegalArgumentException("not fond enum");

}

if (CollectionUtils.isEmpty(strategyMap)) {

throw new IllegalArgumentException("strategy map is empty,please check you strategy package path");

}

Class clazz = strategyMap.get(orderTypeEnum);

if (clazz == null) {

throw new IllegalArgumentException("not fond strategy for type:" + orderTypeEnum.getCode());

}

return (AbstractStrategy) SpringBeanUtils.getBean(clazz);

}

}

首先会扫描指定包中标有@OrderTypeAnnotation的类

将符合类的对应的枚举值作为key,对应的类作为value,保存在策略Map中

初始化StrategyContext,并注册到spring容器中,同时将策略Map传入其中

我们使用了枚举作为Map中的key,相信大家很少有人这样操作过,不过可以放心操作.通过下面两篇文章解答大家的疑问.

3. 总结

策略模式极大的减少if else等模板代码,在提升代码可读性的同时,也大大增加代码的灵活性,添加新的策略即可以满足业务需求.

本人在我司业务中对策略模式的应用得到了很好的验证,从此再也不用担心产品改需求.

用策略模式一时爽,一直用一直爽😏!

4. 代码

Tips

欢迎收藏和转发,感谢你的支持!(๑•̀ㅂ•́)و✧

欢迎关注我的公众号:庄里程序猿,读书笔记教程资源第一时间获得!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值