使用注解加反射去除switch重构代码

这星期碰到了需要对switch代码进行重构,这个我是在解析request时碰到的情况,今天记录下来。

废话不多说,先上选来的代码

public class Main {
    public static void main(String[] args){
        String log = "title=123&appcode=234&tt=345&log-type=456";
        DataHandler dataHandler = new DataHandler();
        PrintOutLog.printout(dataHandler.process(log));
    }
}

public class DataHandler {
    public RequestData process(String log){
        RequestData requestData=new RequestData();
        String[] params = log.split("&");
        for(String param : params){
            String[] data=param.split("=");
            switch (data[0]){
                case "title":
                    requestData.setTitle(data[1]);
                    break;
                case "appcode":
                    requestData.setAppcode(data[1]);
                    break;
                case "log-type":
                    requestData.setLogtype(data[1]);
                    break;
                case "tt":
                    requestData.setTt(data[1]);
                    break;
                case "deltt":
                    requestData.setTt(data[1]);
                    break;
            }
        }

        return requestData;
    }
}

public class RequestData {
    private String title;
    private String appcode;
    private String tt;
    private String logtype;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAppcode() {
        return appcode;
    }

    public void setAppcode(String appcode) {
        this.appcode = appcode;
    }

    public String getTt() {
        return tt;
    }

    public String getLogtype() {
        return logtype;
    }

    public void setLogtype(String logtype) {
        this.logtype = logtype;
    }

    public void setTt(String tt) {
        this.tt = tt;
    }


}

public class PrintOutLog {
    public static void printout(RequestData requestData){
        StringBuilder sb = new StringBuilder();
        sb.append("title:"+requestData.getTitle()+",");
        sb.append("appcode:"+requestData.getAppcode()+",");
        sb.append("tt:"+requestData.getTt()+",");
        sb.append("logtype:"+requestData.getLogtype());
        System.out.println(sb.toString());
    }
}


最后输出结果是:


这个例子差不多就可以用来展示我需要的功能了,实际情况也就是会有更多的case分支

可能大家已经主要到了在case分支上有一个tt和deltt,这是因为有可能会有别名情况出现


大家也可以自行想一下有什么更好的方案


好 ,下面就来进行我的代码重构之路(主要刚看了重构这本书,感觉有逼格)

第一步,创建注解

//对字段进行注解
@Target(ElementType.FIELD)
//需要反射的话这里应该设为RUNTIME
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldMeta {
    public String[] name() default "";
}


具体里面的参数是干嘛的,我就不详细介绍了,网上都有,我是看了Thinking in Java中注解那一章

然后对之前的存放RequestData类进行修改

public class RequestData {
    @FieldMeta(name={"title"})
    private String title;
    @FieldMeta(name={"appcode"})
    private String appcode;
    @FieldMeta(name={"tt","deltt"})
    private String tt;
    @FieldMeta(name={"log-type"})
    private String logtype;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAppcode() {
        return appcode;
    }

    public void setAppcode(String appcode) {
        this.appcode = appcode;
    }

    public String getTt() {
        return tt;
    }

    public String getLogtype() {
        return logtype;
    }

    public void setLogtype(String logtype) {
        this.logtype = logtype;
    }

    public void setTt(String tt) {
        this.tt = tt;
    }


}




最后一步便是对DataHandler进行重构

public class DataHandler {
    public RequestData process(String log) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
//        获得这个类
        Class clazz = Class.forName("com.slz.demo.switchdemo.RequestData");
//        获得一个对象
        Object object = clazz.newInstance();
//        获得类中的属性
        Field[] fFields = clazz.getDeclaredFields();

        String[] params = log.split("&");
        for(String param : params) {
            String[] data = param.split("=");
//            遍历属性,寻找与request的key相对应的属性并赋值
            for (Field field : fFields){
//                该属性是否包含注解
                if(field.isAnnotationPresent(FieldMeta.class)){
//                    修改属性的访问权限,原先时private,不能直接修改
                    field.setAccessible(true);
//                    获取字段注解
                   FieldMeta fieldMeta = field.getAnnotation(FieldMeta.class);
                    String[] names = fieldMeta.name();
                    for (String name : names){
                        if (name.equals(data[0])){
//                            通过反射赋值
                            field.set(object,data[1]);
                        }
                    }
                }
            }
        }
        return (RequestData)object;
    }
}


输出结果跟上相同




这次的请求解析就到这结束了。希望有兴趣的朋友可以一起讨论一起进步,也请大神批评指正。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值