pc|别再if-else走天下了,整个注解多优雅
策略模式
经常在网上看到一些名为“别再if-else走天下了” , “教你干掉if-else”等之类的文章 , 大部分都会讲到用策略模式去代替if-else 。 策略模式实现的方式也大同小异 。 主要是定义统一行为(接口或抽象类) , 并实现不同策略下的处理逻辑(对应实现类) 。 客户端使用时自己选择相应的处理类 , 利用工厂或其他方式 。
注解实现
本文要说的是用注解实现策略模式的方式 , 以及一些注意点 。 话不多说 , 还是以最常 见的订单处理为例 。 首先定义这样一个订单实体类:
@Datapublic class Order { /** * 订单来源 */ private String source /** * 支付方式 */ private String payMethod /** * 订单编号 */ private String code /** * 订单金额 */ private BigDecimal amount // ...其他的一些字段}
假如对于不同来源(pc端、移动端)的订单需要不同的逻辑处理 。 项目中一般会有OrderService这样一个类 , 如下 , 里面有一坨if-else的逻辑 , 目的是根据订单的来源的做不同的处理 。
@Servicepublic class OrderService { public void orderService(Order order) { if(order.getSource().equals("pc")){ // 处理pc端订单的逻辑 }else if(order.getSource().equals("mobile")){ // 处理移动端订单的逻辑 }else { // 其他逻辑 } }}
策略模式就是要干掉上面的一坨if-else , 使得代码看起来优雅且高大上 。 现在就让我们开始干掉这一坨if-else 。 先总览下结构:
本文插图
1.首先定义一个OrderHandler接口 , 此接口规定了处理订单的方法 。
public interface OrderHandler { void handle(Order order)}
2.定义一个OrderHandlerType注解 , 来表示某个类是用来处理何种来源的订单 。
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Servicepublic @interface OrderHandlerType { String source()}
3.接下来就是实现pc端和移动端订单处理各自的handler , 并加上我们所定义的OrderHandlerType注解 。
@OrderHandlerType(source = "mobile")public class MobileOrderHandler implements OrderHandler { @Override public void handle(Order order) { System.out.println("处理移动端订单") }} @OrderHandlerType(source = "pc")public class PCOrderHandler implements OrderHandler { @Override public void handle(Order order) { System.out.println("处理PC端订单") }}
4.以上准备就绪后 , 就是向spring容器中注入各种订单处理的handler , 并在OrderService.orderService方法中 , 通过策略(订单来源)去决定选择哪一个OrderHandler去处理订单 。 我们可以这样做:
@Servicepublic class OrderService { private Map> orderHandleMap @Autowired public void setOrderHandleMap(List
OrderHandler
orderHandlers) { // 注入各种类型的订单处理类 orderHandleMap = orderHandlers.stream().collect( Collectors.toMap(orderHandler -> AnnotationUtils.findAnnotation(orderHandler.getClass(), OrderHandlerType.class).source(), v -> v, (v1, v2) -> v1)) } public void orderService(Order order) { // ...一些前置处理 // 通过订单来源确定对应的handler OrderHandler orderHandler = orderHandleMap.get(order.getSource()) orderHandler.handle(order) // ...一些后置处理 }}
在OrderService中 , 维护了一个orderHandleMap , 它的key为订单来源 , value为对应的订单处理器Handler 。 通过@Autowired去初始化orderHandleMap(这里有一个lambda表达式 , 仔细看下其实没什么难度的) 。 这样一来 , OrderService.orderService里的一坨if-else不见了 , 取而代之的仅仅是两行代码 。 即 , 先从orderHandleMap中根据订单来源获取对应的OrderHandler , 然后执行OrderHandler.handle方法即可 。 这种做法的好处是 , 不论以后业务如何发展致使订单来源种类增加 , OrderService的核心逻辑不会改变 , 我们只需要实现新增来源的OrderHandler即可 , 且团队中每人开发各自负责的订单来源对应的OrderHandler即可 , 彼此间互不干扰 。
推荐阅读
- 北京日报|安全带插片网上热销 专家:别再花钱买“危险”
- 银行|有30万元存款,别再傻傻存定期了,银行行长:这样存年利过万
- 民生经济|原创 有30万元存款,别再傻傻存定期了,银行行长:这样存年利过万
- 经济|银行行长:手中有10万别再存定期,这样存一年利息近1万!
- 球鞋|央视点名曝光!这一行业涨的比房价还快,别再傻傻掉进“传销”
- [食物浪费 农产品 进出口 猪肉 蔬菜]|别再说吃不起猪肉,你每年浪费的猪肉量是进口量的2倍
- 球鞋|央视点名批评!这一行业已沦为下一个“传销”,别再傻傻“入套”
- |信用卡不为人知的4个“秘密”,小心被“吞钱”,别再多交钱了
- |DAO才是DeFi的最终形式?错过DeFi,千万别再错过DAO
- 民生经济|年轻人注意了,又一做法正在"掏空"你的钱包,别再傻傻买单
