优化建造者模式
2018-01-04 本文已影响0人
BigDataFlow
一、问题示例
public void func(String name, String id, String gender, String fullname, long time, boolean flag, Object body){
//具体业务
}
可以看到该方法参数多达七个,并且前四个都是String类型,使用者很容易在传入参数的时候搞错顺序。
二、解决办法
使用建造者模式构建一个Params类,用来管理所有的入参。代码结构如下:
public class Params {
private String name;
private String id;
private String gender;
private String fullname;
private long time;
private boolean flag;
private Object body;
public String getName() {
return name;
}
public String getId() {
return id;
}
public String getGender() {
return gender;
}
public String getFullname() {
return fullname;
}
public long getTime() {
return time;
}
public boolean isFlag() {
return flag;
}
public Object getBody() {
return body;
}
private Params(String name, String id, String gender, String fullname,
long time, boolean flag, Object body) {
this.name = name;
this.id = id;
this.gender = gender;
this.fullname = fullname;
this.time = time;
this.flag = flag;
this.body = body;
}
public static class Builder{
private String name;
private String id;
private String gender;
private String fullname;
private Long time;
private Boolean flag;
private Object body;
private Builder(){
}
public static Builder build(){
return new Builder();
}
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setId(String id) {
this.id = id;
return this;
}
public Builder setGender(String gender) {
this.gender = gender;
return this;
}
public Builder setFullname(String fullname) {
this.fullname = fullname;
return this;
}
public Builder setTime(long time) {
this.time = time;
return this;
}
public Builder setFlag(boolean flag) {
this.flag = flag;
return this;
}
public Builder setBody(Object body) {
this.body = body;
return this;
}
public Params create(){
if (name != null && gender != null && flag != null && id != null) {
return new Params(name, id, gender, fullname, time, flag, body);
} else {
return null;
}
}
}
}
该代码和一般的建造者模式不同在于:
1.对于long等基本类型,在Builder类的成员变量中全都使用其包装类。其作用在于识别用户是否执行了Builder中的setXxxx()接口。
2.对于所有必传参数,在Builder类的create()方法中检测是否为null,检测构建过程中是否使用了必须的setXxxx()接口。
3.所有的类的构造函数都私有化,防止用户直接创建,绕过检测。
4.func方法需要修改成如下方式,必须有布尔型返回值,用来标识参数是否漏传。
public boolean func(Params params){
if(params==null){
return false;
}
//具体业务
return true;
}
三、使用比较
//优化前
func("xiaoli","12344455","man","li ming",System.currentTimeMillis(),true,null);
//优化后
func(Params.Builder.build().setBody(null).setFlag(true).setTime(System.currentTimeMillis()).setFullname("li ming").setName("xiaoli").setGender("man").setId("12344455").create());