这星期碰到了需要对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分支上有一个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;
}
}
输出结果跟上相同
这次的请求解析就到这结束了。希望有兴趣的朋友可以一起讨论一起进步,也请大神批评指正。