设计模式-建造者模式(应用场景)

424 阅读2分钟

Builder 模式,翻译为建造者模式或者构建者模式,也有人叫它生成器模式。

什么是建造者模式

建造者模式,属于创建型模式。将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。 (听起来好像不是人话,后面结合实例才好理解!)

建造者模式的应用

  • 什么时候需要建造者模式? 要回答这个问题,要从我们的需求着手。现在假设我们有一个类需要生成,具体规则: (举个简单的例子)
  1. 有默认值的不需要赋值,没有默认值的需要赋值。
public class Config {

    private static final int DEFAULT_TOTAL = 8;
    private static final int DEFAULT_MAX = 8;
    private static final int DEFAULT_MIN = 0;

    private int maxTotal = DEFAULT_TOTAL;
    private int maxIdle = DEFAULT_MAX;
    private int minIdle = DEFAULT_MIN;

    private String name;
    
    private Integer age;

    private Integer sex;
}
  • 实现方式:
	// 使用构造方法赋值
    public Config(String name, Integer age, Integer sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

问题,参数过多时,那构造函数就又会出现参数列表很长的问题,参数过多时代码可读性不好。

  • 只能选择替代方案set设置值
  public void setName(String name) {
        this.name = name;
    }

set方式,导致我们无法对已生成的对象校验必填值是否填写

  • 建造者模式,将设置值和对值的校验结合
public class Config {

    private static final int DEFAULT_TOTAL = 8;
    private static final int DEFAULT_MAX = 8;
    private static final int DEFAULT_MIN = 0;

    private int maxTotal = DEFAULT_TOTAL;
    private int maxIdle = DEFAULT_MAX;
    private int minIdle = DEFAULT_MIN;

    private String name;

    private String age;

    private String sex;

    public Config(String name, String age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    private Config(Builder builder){
        this.name = builder.name;
        this.age = builder.age;
        this.sex = builder.sex;
    }

    public static class Builder{


        private String name;

        private String age;

        private String sex;
        
        // 建造者对参数进行校验,然后再创建对象。
        public Config build(){
            if (StringUtils.isBlank(name)) {
                throw new IllegalArgumentException("...");
            }
            if (StringUtils.isBlank(age)) {
                throw new IllegalArgumentException("...");
            }
            if (StringUtils.isBlank(sex)) {
                throw new IllegalArgumentException("...");
            }
            return new Config(this);
        }


        public void setName(String name) {
            this.name = name;
        }

        public void setAge(String age) {
            this.age = age;
        }

        public void setSex(String sex) {
            this.sex = sex;
        }
    }
}

建造者模式很工厂模式的区别

刚才发现建造者和工厂模式十分相似,都是用来创建对象的。在实际使用过程中,什么情况下该使用建造者模式呢。

网络上一个很经典的例子:
我们利用工厂模式,根据用户不同的选择,来制作不同的食物,比
如披萨、汉堡、沙拉。对于披萨来说,用户又有各种配料可以定制,比如奶酪、西红柿、起
司,我们通过建造者模式根据用户选择的不同配料来制作披萨。

简单的说,工厂可以用来通过定制化制作不同的食物,建造者只能选择不同的原材料,建造一种东西。