一、建造者模式的概念
- 建造者模式:对象创建软件设计模式,其目的是找到伸缩构造器反模式的解决方案
例如我们有如下构造函数
public Hero(Profession profession, String name, HairType hairType, HairColor hairColor, Armor armor, Weapon weapon) {
}
复制代码
可以看到构造函数的参数非常多,以后可能还会继续添加,那么在以后使用构造函数的时候很难理解参数的排列顺序,这就可称之为伸缩构造器反模式。
所以建造者模式的目的就是将复杂对象的构造与其表示分开,以便相同的构造过程可以创建不同的表示。
简单来说,建造者模式允许创建不同风格的对象,同时避免构造函数污染,这在有多种构造函数或者创建对象涉及许多步骤时很有用。
二、实际使用实例
public class QueryPaginationResponse implements Serializable {
/**
*查询是否成功 1,0
*/
private int status;
/**
* 当前页
*/
private int current;
/**
*总页数
*/
private int total;
/**
* 总记录数
*/
private int count;
/**
* 一页的记录数
*/
private int pageSize;
/**
* 得到的数据
*/
private List<Object> list;
public QueryPaginationResponse(int status) {
this.status = status;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public int getCurrent() {
return current;
}
public void setCurrent(int current) {
this.current = current;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public List<Object> getList() {
return list;
}
public void setList(List<Object> list) {
this.list = list;
}
public static class Builder{
private QueryPaginationResponse instance;
public Builder(QueryPaginationResponse q){
this.instance = q;
}
public Builder(int status){
this(new QueryPaginationResponse(status));
}
public Builder setCurrent(int current){
this.instance.current = current;
return this;
}
public Builder setTotal(int total){
this.instance.total = total;
return this;
}
public Builder setCount(int count){
this.instance.count = count;
return this;
}
public Builder setPageSize(int pageSize){
this.instance.pageSize = pageSize;
return this;
}
public Builder setList(List<Object> list){
this.instance.list = list;
return this;
}
public QueryPaginationResponse build(){
return this.instance;
}
}
}
QueryPaginationResponse response = new QueryPaginationResponse.Builder(1).setCount(100)
.setCurrent(1).setTotal(2).setPageSize(50).setList(new ArrayList<>()).build();
System.out.println(response.toString());
复制代码
以往当我们需要new一个QueryPaginationResponse对象的时候,往往直接调用构造函数生成一个对象,如:
public QueryPaginationResponse(int status, int current, int total, int count) {
this.status = status;
this.current = current;
this.total = total;
this.count = count;
}
复制代码
当成员属性只有上述四个的时候,构造函数也只有四个参数。但当加了一个成员属性pageSize的话,那么就要修改构造函数,或者重载构造函数
public QueryPaginationResponse(int status, int current, int total, int count, int pageSize) {
this.status = status;
this.current = current;
this.total = total;
this.count = count;
this.pageSize = pageSize;
}
复制代码
若是又增加了一个属性的话,那么还得重复上述步骤,修改或者重载:
public QueryPaginationResponse(int status, int current, int total, int count, int pageSize, List<Object> list) {
this.status = status;
this.current = current;
this.total = total;
this.count = count;
this.pageSize = pageSize;
this.list = list;
}
复制代码
这就为代码的调用带来了极大的不便 Builder就可以解决这种复杂的对象构造逻辑。
从上述展示的例子代码可以看到,在QueryPaginationResponse类内部,我们新建了一个内部类Builder,Builder类内部含有一个QueryPaginationResponse类型的属性。Builder类内部有两个构造函数,其目的就是实例化这个QueryPaginationResponse类型的属性。
public static class Builder {
private QueryPaginationResponse instance;
public Builder(QueryPaginationResponse q){this.instance = q;}
public Builder(int status){
this(new QueryPaginationResponse(status));
}
复制代码
之后就是创建QueryPaginationResponse对象各个属性的赋值方法了,方法名随意,但是这些赋值方法都是给这个Builder对象连续调用的,所以方法内部还得返回这个Builder对象return this;。
public Builder setTotal(int total){
// 实质给QueryPaginationResponse实例赋值
this.instance.total = total;
return this;
}
public Builder setCount(int count){
this.instance.count = count;
return this;
}
public Builder setPageSize(int pageSize){
this.instance.pageSize = pageSize;
return this;
}
public Builder setList(List<Object> list){
this.instance.list = list;
return this;
}
复制代码
最后声明一个方法将这个Builder类内部的实例返回出去就可以了
public QueryPaginationResponse build(){
return this.instance;
}
复制代码
最终代码就是这个样子,采用Builder设计模式。当我们需要创建不同风格的对象时候,不再需要重载构造函数了,只需要确定Builder实例调用哪个赋值方法就可以了。
// 给5个属性的QueryPaginationResponse实例
QueryPaginationResponse response = new QueryPaginationResponse.Builder(1).setCount(100)
.setCurrent(1).setTotal(2).setPageSize(50).setList(new ArrayList<>()).build();
// 给4个属性的QueryPaginationResponse实例
QueryPaginationResponse response = new QueryPaginationResponse.Builder(1).setCount(100)
.setCurrent(1).setTotal(2).setPageSize(50).build();
复制代码