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

来源:互联网 发布:进入国外网站软件 编辑:程序博客网 时间:2024/06/05 16:14

这星期碰到了需要对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
原创粉丝点击