开发业务代码过程中,如果能过类似JQuey那种链式编程或者Java中的Builder模式一样可以一直点下去,是一种非常爽的体验。
如果内部有一些类似Map、JSONObject的属性,怎样更表意呢?怎样隐藏内部数据结构呢?
普通的Builder模式应该外部创建Map或者JSONObject对象并赋值,能否有更好的解决方案呢?
当然也可以通过uilder中写一个put方法可以避免多出现一个对象,但是如何更表意呢?
public Builder put(String key, String value){
data.put(key, value);
return this;
}
下面介绍一个不错的技巧
借助Builder模式和中间类实现链式编程和淡化内部特殊类型(JSONObject)的属性的效果。
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
/**
* 明明如月
* liuwangyangedu@163.com
*/
@Data
public class MyConfig {
private JSONObject data;
private String appName;
private Long logTime;
private MyConfig(Builder builder) {
this.data = builder.data;
this.appName = builder.appName;
this.logTime = builder.logTime;
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private JSONObject data = new JSONObject();
private String appName;
private Long logTime;
public Builder appName(String appName) {
this.appName = appName;
return this;
}
public Builder logTime(Long logTime) {
this.logTime = logTime;
return this;
}
public SemiData key(String key) {
return new SemiData(this, key);
}
public MyConfig build() {
return new MyConfig(this);
}
public class SemiData {
private String key;
private Builder parent;
private SemiData(Builder myConfig, String key) {
this.parent = myConfig;
this.key = key;
}
public Builder value(Object value) {
parent.data.put(key, value);
return parent;
}
}
}
}
用法
@Test
void builder() {
String appName = "test";
Long currentTime = System.currentTimeMillis();
MyConfig myConfig = MyConfig.builder()
.appName(appName)
.logTime(currentTime)
.key("name").value("张三")
.key("age").value(24)
.key("sex").value("男")
.build();
assertEquals(appName, myConfig.getAppName());
assertEquals(currentTime, myConfig.getLogTime());
JSONObject data = myConfig.getData();
assertEquals(data.get("name"),"张三");
}
不使用Builder模式,通过中间类实现链式编程和淡化内部特护类型(JSONObject)的属性的效果。
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
/**
* 明明如月
* liuwangyangedu@163.com
*/
@Data
public class MyConfig {
private JSONObject data = new JSONObject();
private String appName;
private Long logTime;
public MyConfig appName(String appName) {
this.appName = appName;
return this;
}
public MyConfig logTime(Long logTime) {
this.logTime = logTime;
return this;
}
public SemiData key(String key) {
return new SemiData(this, key);
}
public class SemiData {
private String key;
private MyConfig parent;
private SemiData(MyConfig myConfig, String key) {
this.parent = myConfig;
this.key = key;
}
public MyConfig value(Object value) {
parent.data.put(key, value);
return parent;
}
}
}
用法
@Test
void builder() {
String appName = "test";
Long currentTime = System.currentTimeMillis();
MyConfig myConfig = new MyConfig().appName(appName)
.logTime(currentTime)
.key("name").value("张三")
.key("age").value(24)
.key("sex").value("男");
assertEquals(appName, myConfig.getAppName());
assertEquals(currentTime, myConfig.getLogTime());
JSONObject data = myConfig.getData();
assertEquals(data.get("name"),"张三");
}