架构师进阶之五常用的策略模式,太多if ese语句优化方案

引入

以前在编码中,遇到过下面的情况,根据设备类型,调用不同的Converter转换类。最初代码如下:

if(type1){
   convert1();
}
else if(type2){
   convert2();
}
else if(type3){
   convert3();
}

如果增加类型,需要修改代码,增加if else逻辑。我当时感觉代码ugly,所以用了一个map,映射设备类型和converter类。应用层代码如下:

Converter converter=map.get(type);
converter.converte()

所有设备类型转换类都实现Converter接口。这样代码简洁很多。但是问题没有解决,增加type类型,还需要修改我的map代码,往map添加记录。有没有其他方法呢?根据设计模式,代码应该是对扩展开发,对修改关闭的。我的思路应用了策略模式,但是不够完美。

优化设计

优化是如何不维护map的映射关系?期待的是增加设备类型的converter之后,自动能够进行转换。

1. 新建converter类,实现converter接口。converter类增加一个注解,注解的值是设备类型。

2  启动的时候,获取实现converter接口的所有类,利用annoatation和类,动态生成我们的map结构  

3调用方法

Converter convert=ConverterContext.getConverter(Enum.DMA);
converter.converter();

代码

package com.puhui.shoppingmallloan.web.controller;

import com.sun.xml.internal.ws.handler.ServerLogicalHandlerTube;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.annotation.PostConstruct;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;

/**
 * 2 * @Author: kerry
 * 3 * @Date: 2019/2/27 13:37
 * 4
 */
@Service
public class ConverterContext implements ApplicationRunner {



    @Autowired
    private ApplicationContext applicationContext;

    private static Map<String,Converter> map=new HashMap<>();

    @Override
    public void run(ApplicationArguments sce) {
        Map<String, Converter> allClasses = applicationContext.getBeansOfType(Converter.class);
        for(Map.Entry entry:allClasses.entrySet()){
            Converter converter=(Converter) entry.getValue();
            DeviceType annotation=applicationContext.findAnnotationOnBean((String) entry.getKey(),DeviceType.class);
            map.put(annotation.type(),converter);
        }


    }


    public static Converter getConverter(TypeEnum typeEnum){
        return map.get(typeEnum);
    }
}
package com.puhui.shoppingmallloan.web.controller;

import java.lang.annotation.*;

/**
 * 2 * @Author: kerry
 * 3 * @Date: 2019/2/27 13:28
 * 4
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface DeviceType {

    String type() default "";
}
package com.puhui.shoppingmallloan.web.controller;

import org.springframework.stereotype.Service;

import java.lang.reflect.Type;

/**
 * 2 * @Author: kerry
 * 3 * @Date: 2019/2/27 13:28
 * 4
 */
@DeviceType(type ="DMA")
@Service
public class DMAConverter implements  Converter {

    @Override
    public void converter() {

    }
}
package com.puhui.shoppingmallloan.web.controller;

/**
 * 2 * @Author: kerry
 * 3 * @Date: 2019/2/27 13:30
 * 4
 */
public enum TypeEnum {

    DMA("DMA"),XMA("XMA"),MCU("MCU");

    private String code;


    private TypeEnum(String code) {
        this.code = code;
    }

    public String getCode() {
        return code;
    }


    @Override
    public String toString() {

        return this.code;
    }
}

猜你喜欢

转载自blog.csdn.net/hanruikai/article/details/87969635
今日推荐