Java建造者模式在项目中的实际运用

版权声明:本文为博主原创文章,未经博主允许不得转载 https://blog.csdn.net/liujun03/article/details/82789704

建造者模式

建造者模式(Builder Pattern)是对象创建软件设计模式,其目的是找到伸缩构造器反模式的解决方案。先简单说一下伸缩构造器反模式是什么:假如我们有如下构造函数:

public Hero(Profession profession, String name, HairType hairType, HairColor hairColor, Armor armor, Weapon weapon) {
}

可以看到,构造函数参数的数量很多,而且将来可能会添加更多的参数,这就已经很难去控制数量了。并且在使用构造函数的时候很难理解参数的排列顺序,这就可称之为伸缩构造器反模式。

所以建造者模式的目的就是将复杂对象的构造与其表示分开,以便相同的构造过程可以创建不同的表示。

简单来说,建造者模式允许创建不同风格的对象,同时避免构造函数污染,这在有多种构造函数或者创建对象涉及许多步骤时很有用。

下面用实际例子来说明:

/**
 * @Author: BaiDing
 * @Date: 2018/9/20 13:42
 * @Email: [email protected]
 */
public class QueryPaginationResponse implements Serializable{

    private int status;     // 查询是否成功 1,0
    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;
    }

    @Override
    public String toString() {
        return "QueryPaginationResponse{" +
            "status=" + status +
            ", current=" + current +
            ", total=" + total +
            ", count=" + count +
            ", pageSize=" + pageSize +
            ", 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();

猜你喜欢

转载自blog.csdn.net/liujun03/article/details/82789704