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即可 , 彼此间互不干扰 。
推荐阅读
- 鸽书说教育|姑娘咱能别再放电了,搞笑GIF:真的快窒息了
- 游人|别再摘了!中华民族园的景观农作物都“秃顶”了
- 儿童饮食|妈妈们别再给宝宝瞎补钙啦!这些症状未必都跟缺钙有关
- 冷无情|杨幂:你别再卖惨了!
- 超兽武装|千面英雄改名英雄觉醒,超兽武装回来了,希望蓝弧别再放鸽子了
- 冷暴力:“冷暴力”处理方式,正在摧毁多少家庭幸福?别再伤害最爱你的人
- 衬衣|蒋欣可别再胖下去了,穿蓝色条纹衬衣造型大翻车,全靠气质撑着
- 开心栗子|门都打开了,你就别再爬了梯子啦!,搞笑GIF趣图:新郎哥哥
- 美剧去哪看|有肚子的女人别再“塞衣角”啦,学日本杂志这样穿,时髦还气质
- 学渣爱吐槽|求求你别再用全景相机拍照了!简直就是恐怖片…”,“老师