在写业务代码的时候发现需要大量使用If,同时里面还写满了业务逻辑代码。为了使代码更加简洁一些,使用设计模式把原有If或者Switch简化。
本篇博客参考了(对二者结合整理):
一、策略模式
需求:虚拟一个业务需求,让大家容易理解。假设有一个订单系统,里面的一个概念是根据订单的不同类型做出不同的处理。
AOrderTypeHandler
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package com.oy.test.handler;
import com.oy.test.bean.OrderDTO;
public abstract class AOrderTypeHandler {
abstract public String handler(OrderDTO dto); }
|
HandlerContext
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| package com.oy.test.handler;
import java.util.Map;
public class HandlerContext { private Map<String, AOrderTypeHandler> handlerMap;
public HandlerContext(Map<String, AOrderTypeHandler> handlerMap) { this.handlerMap = handlerMap; }
public AOrderTypeHandler getInstance(String type) { if (type == null) { throw new IllegalArgumentException("type参数不能为空"); } AOrderTypeHandler clazz = handlerMap.get(type); if (clazz == null) { throw new IllegalArgumentException("该类型没有在枚举OrderTypeHandlerAnno中定义,请定义:" + type); } return clazz; } }
|
HandlerProccessor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| package com.oy.test.handler;
import com.oy.test.common.OrderTypeEnum; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils;
import java.util.Collection; import java.util.HashMap; import java.util.Map;
@Component public class HandlerProccessor implements BeanFactoryPostProcessor {
@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { Map<String, AOrderTypeHandler> handlerMap = new HashMap<>(); for (OrderTypeEnum temp : OrderTypeEnum.values()) { AOrderTypeHandler beanInstacle = getBeansWithAnnotation(beanFactory, AOrderTypeHandler.class, OrderTypeHandlerAnno.class, temp.getCode()); handlerMap.put(temp.getCode(), beanInstacle); } HandlerContext context = new HandlerContext(handlerMap); beanFactory.registerSingleton(HandlerContext.class.getName(), context); }
private <T> T getBeansWithAnnotation(ConfigurableListableBeanFactory beanFactory, Class<T> manager, Class<? extends OrderTypeHandlerAnno> annotation, String code) throws BeansException { if (ObjectUtils.isEmpty(code)) { throw new RuntimeException("code is null "); } Collection<T> tCollection = beanFactory.getBeansOfType(manager).values(); for (T t : tCollection) { OrderTypeHandlerAnno orderTypeHandlerAnno = t.getClass().getAnnotation(annotation); if (ObjectUtils.isEmpty(orderTypeHandlerAnno)) { throw new RuntimeException("该注解没有写入值 :" + code); } if (code.equals(orderTypeHandlerAnno.value().getCode())) { return t; } } throw new RuntimeException("通过code没有找到该注解对应的实体类 :" + code); } }
|
OrderTypeHandlerAnno
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package com.oy.test.handler;
import com.oy.test.common.OrderTypeEnum;
import java.lang.annotation.*;
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface OrderTypeHandlerAnno { OrderTypeEnum value(); }
|
GroupOrderHandler
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package com.oy.test.handler.biz;
import com.oy.test.bean.OrderDTO; import com.oy.test.common.OrderTypeEnum; import com.oy.test.handler.AOrderTypeHandler; import com.oy.test.handler.OrderTypeHandlerAnno; import org.springframework.stereotype.Component;
@Component @OrderTypeHandlerAnno(OrderTypeEnum.Group) public class GroupOrderHandler extends AOrderTypeHandler { @Override public String handler(OrderDTO dto) { return "处理团队订单"; } }
|
NormalOrderHandler
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package com.oy.test.handler.biz;
import com.oy.test.bean.OrderDTO; import com.oy.test.common.OrderTypeEnum; import com.oy.test.handler.AOrderTypeHandler; import com.oy.test.handler.OrderTypeHandlerAnno; import org.springframework.stereotype.Component;
@Component @OrderTypeHandlerAnno(OrderTypeEnum.Normal) public class NormalOrderHandler extends AOrderTypeHandler {
@Override public String handler(OrderDTO dto) { return "处理普通订单"; } }
|
PromotionOrderHandler
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package com.oy.test.handler.biz;
import com.oy.test.bean.OrderDTO; import com.oy.test.common.OrderTypeEnum; import com.oy.test.handler.AOrderTypeHandler; import com.oy.test.handler.OrderTypeHandlerAnno; import org.springframework.stereotype.Component;
@Component @OrderTypeHandlerAnno(OrderTypeEnum.Promotion) public class PromotionOrderHandler extends AOrderTypeHandler { @Override public String handler(OrderDTO dto) { return "处理促销订单"; } }
|
OrderDTO
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| package com.oy.test.bean;
import java.math.BigDecimal;
public class OrderDTO { private String code; private BigDecimal price;
private String type;
public String getCode() { return code; }
public void setCode(String code) { this.code = code; }
public BigDecimal getPrice() { return price; }
public void setPrice(BigDecimal price) { this.price = price; }
public String getType() { return type; }
public void setType(String type) { this.type = type; } }
|
OrderTypeEnum
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| package com.oy.test.common;
public enum OrderTypeEnum { Normal("1", "普通"), Group("2", "团队"), Promotion("3", "促销"); private String code; private String name; OrderTypeEnum(String code, String name) { this.code = code; this.name = name; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getName() { return name; } public void setName(String name) { this.name = name; }
public static String getNameByCode(String code) { for (OrderTypeEnum temp : OrderTypeEnum.values()) { if (temp.getCode().equals(code)) { return temp.getName(); } } return null; } }
|
service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
public interface IOrderService {
String orderHandler(OrderDTO dto); }
@Service public class OrderServiceImpl implements IOrderService { @Override public String orderHandler(OrderDTO dto) { if ("1".equals(dto.getType())) { } else if ("2".equals(dto.getType())) { } else if ("3".equals(dto.getType())) { } return null; } }
@Service public class OrderServiceImpl2 implements IOrderService { @Autowired private HandlerContext handlerContext;
@Override public String orderHandler(OrderDTO dto) {
AOrderTypeHandler instance = handlerContext.getInstance(dto.getType()); return instance.handler(dto); }
}
|
二、策略模式+工厂方法
我们把每个条件逻辑代码块,抽象成一个公共的接口,我们根据每个逻辑条件,定义相对应的策略实现类
interface 接口
1 2 3
| public interface NameService { String getName(); }
|
service
1 2 3 4 5 6 7 8
| public class LisiName implements NameService { @Override public String getName() { System.out.println("我是李四"); return "我是李四"; } }
|
1 2 3 4 5 6 7 8
| public class WangwuName implements NameService { @Override public String getName() { System.out.println("我是王五"); return "我是王五"; } }
|
1 2 3 4 5 6 7 8
| public class ZhansanName implements NameService { @Override public String getName() { System.out.println("我是张三"); return "我是张三"; } }
|
factory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class NameServiceFactory { private static final Map<String, NameService> map = new HashMap<>(); static { map.put("张三", new ZhansanName()); map.put("李四", new LisiName()); map.put("王五", new WangwuName()); } public static NameService getNameService(String name){ return map.get(name); } }
|
测试
1 2 3 4
| public static void main(String[] args) { NameService nameService = NameServiceFactory.getNameService("张三"); nameService.getName(); }
|
Springboot 简化if else 和 Switch