记录利用设计模式取代if-else的一些方法

1.循环判断法

         典型用例:springmvc中的handlerAdapter中

   在执行类中定义判断方法和执行方法。

public interface HandlerAdapter {
    //判断该实现类是否能在这个对象上使用
    boolean support(Object handler);
    
    //执行方法
    Class<?> process(Object handler);
}

提前注入所有的handlerAdapter类(所有的实现类需要交给spring容器保管)

@Component
public class HandlerAdapterContext {
    @Autowired
    private List<HandlerAdapter> handlerAdapterList;  //注册所有的HandlerAdapter类

    public List<HandlerAdapter> getHandlerAdapterList(){
        return handlerAdapterList;
    }
}

客户端:

public class Client {
    @Autowired
    private HandlerAdapterContext handlerAdapterContext;
    @Test
    public void test(){
        Object o = new Object();
        for (HandlerAdapter handlerAdapter : handlerAdapterContext.getHandlerAdapterList()) {
            if (handlerAdapter.support(o)) {//找到适配的就执行
                o = handlerAdapter.process(o);
            }
        }
    }
}

优点:扩展时只需要将新的接口实现类注入到sprin容器中即可

缺点;每次都需要遍历全部的接口类,且无法控制执行顺序

2.map获取法

        典型用例:springmvc中参数转换,将string类型的接收参数动态的转换成函数的参数类型

定义接口类:

public interface ParseStringValue {

    Object parse(String value);
}

定义实现类:

public class LongParseStringValue implements ParseStringValue{
    @Override
    public Object parse(String value) {
        return Long.valueOf(value);
    }
}
public class IntegerParseStringValue implements ParseStringValue{
    @Override
    public Object parse(String value) {
        return Integer.valueOf(value);
    }
}
public class DoubleParseStringValue implements ParseStringValue{
    @Override
    public Object parse(String value) {
        return Double.valueOf(value);
    }
}

提前注入实现类。如果在spring中的话可以使用@PostConstruct

public class ParseStringValueContext {
    private static Map<Class<?>, ParseStringValue> parseStringValueMap;
    static {
        parseStringValueMap = new HashMap<>();
        parseStringValueMap.put(Integer.class, new IntegerParseStringValue());
        parseStringValueMap.put(Double.class, new DoubleParseStringValue());
        parseStringValueMap.put(Long.class, new LongParseStringValue());
    }
    
    public static ParseStringValue getResolver(Class<?> clazz){
        return parseStringValueMap.get(clazz);
    }
}

使用:

public class Client {
    private static void test(Integer num1, Long num2, Double num3) {
        System.out.println("num1 = " + num1);
        System.out.println("num2 = " + num2);
        System.out.println("num3 = " + num3);
    }
    public static void main(String[] args) {
        String[] requestParameters = new String[]{"111", "1111111111111111", "1.11"};//模拟请求参数
        try {
            Method method = Client.class.getDeclaredMethod("test", Integer.class, Long.class, Double.class);
            List<Object> values = new ArrayList<>();
            Parameter[] parameters = method.getParameters();
            for (int i = 0; i < parameters.length; i++) {
                Parameter parameter = parameters[i];
                //根据参数类型解析参数
                ParseStringValue resolver = ParseStringValueContext.getResolver(parameter.getType());
                Object parse = resolver.parse(requestParameters[i]);
                values.add(parse);
            }
            Client client = Client.class.getDeclaredConstructor().newInstance((Object[]) args);
            method.invoke(client, values.get(0), values.get(1), values.get(2));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

结果:

优点:可以自定义处理器的获取方式,比如用class来获取

缺点;无法控制执行顺序,扩展时需要额外修改context类

 3.责任链模式

        典型用例:springmvc中的拦截器

之前的文章中有讲:

用spring boot的@Order注解实现责任链模式

优点:可以按顺序执行处理器,扩展时只需要添加接口类即可

缺点;只能处理一个类,不同的类需要定义不同的责任链,可以考虑跟1.2结合实现动态处理。

4.利用spring上下文

        前端传过来一个对应service的名字,然后用context.getBean()函数直接获取对应的请求处理类来处理。

优点:实现简单,扩展简便

缺点;需要告诉前端每个请求的处理类名,并且注入bean的时候需要保证bean名字的唯一。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值