Skip to content

建造者模式

建造者模式是一种创建型设计模式,它允许逐步构建复杂对象,并且能够使构建过程和表示分离。这样做的好处是可以在不改变最终产品结构的情况下,提供不同的构造选项,只需要通过选择不同的建造者模式就能得到不同的对象,具体构建的过程和细节就不需要知道。

标准建造者模式:

核心:

  • Product(产品角色):需要被构建的复杂对象。
  • Builder(抽象建造者):定义了构建 Product 对象各个部分的接口或抽象类。
  • ConcreteBuilder(具体建造者):实现了 Builder 接口,提供构建 Product 对象的具体实现。
  • Director(指挥者):使用 ConcreteBuilder 来构建复杂的对象。负责控制产品的生成过程,但并不知道具体的构建细节。

使用场景

说明与示例
对象创建参数过多当构造一个对象需要大量参数,尤其是很多是可选参数时,避免“构造函数爆炸”。
例如:Person(name, age, address, phone, email...)
构建过程复杂或步骤多构建对象需要多个步骤、顺序明确,每个步骤可能独立变化。
例如:构建一个 Computer 需要安装 CPU、内存、硬盘等。
构建不同表现形式的对象同样的构建流程,生成不同的产品实例。
例如:制作不同类型的汉堡套餐(儿童套餐、家庭套餐)。
希望解耦构建逻辑和表示细节客户端不需要知道对象如何一步步构建,只需要指定类型即可。
例如:游戏中的角色构建器(战士/法师/弓箭手)。
支持链式调用(Fluent Interface)提供更优雅、易读的 API 调用方式。
例如:User user = new UserBuilder().setName("Tom").setAge(25).build();
避免使用 JavaBean 方式设置属性带来的不一致性风险在构建过程中保证对象的状态一致性,而不是逐步赋值导致中间状态错误。
例如:某些字段必须在构建时就完成初始化。
用于不可变对象(Immutable Object)的构建如果对象是不可变的(final 字段),不能通过 setter 设置,建造者模式非常适合。
例如:Java 中的 BigDecimal 或自定义的不可变类。

示例:

java

@Slf4j
@Data
public class Product {
    private String name;
    private String packing ;
    private BigDecimal price;
    private String desc;

    public void show(){
        log.info("产品名称: {}, 包装方式: {}, 价格: {}, 描述: {}", name, packing, price, desc);
    }

}
java

public abstract class ProductBuilder {
    protected Product product;


    public abstract void setPacking();
    public abstract void setName();
    public abstract void setPrice();
    public abstract void setDesc();

    public Product getProduct() {
        return product;
    }

}
java

public class KrustyKrabProductBuilder extends ProductBuilder {

    public KrustyKrabProductBuilder() {
        this.product = new Product();
    }

    @Override
    public void setPacking() {
        product.setPacking("纸盒装");
    }

    @Override
    public void setName() {
        product.setName("蟹黄堡");
    }

    @Override
    public void setPrice() {
        product.setPrice(new BigDecimal("5.00"));
    }

    @Override
    public void setDesc() {
        product.setDesc("蟹黄堡desc");
    }
}
java

public class ProductDirector {
    private ProductBuilder builder;
    public ProductDirector(ProductBuilder builder) {
        this.builder = builder;
    }
    public Product createProduct() {
        builder.setPacking();
        builder.setName();
        builder.setPrice();
        builder.setDesc();
        return  builder.getProduct();
    }
}

内部类建造者

核心:

在需要建造者的类中创建一个内部的建造者,建造者中的方法中返回建造者本身,通过内部的建造者链式调用的方式进行属性赋值,最后通过 build 方法创建对象。

示例:

java
public class Product {
    private String name;
    private String packing ;
    private BigDecimal price;
    private String desc;

    private  Product(Builder builder) {
        this.name = builder.name;
        this.packing = builder.packing;
        this.price = builder.price;
        this.desc = builder.desc;
    }

    public static  class  Builder{
        private String name;
        private String packing ;
        private BigDecimal price;
        private String desc;

        public Builder name(String name) {
            this.name = name;
            return this;
        }

        public Builder  packing(String packing) {
            this.packing = packing;
            return this;
        }

        public  Builder price(BigDecimal price) {
            this.price = price;
            return this;
        }
        public Builder desc(String desc) {
            this.desc = desc;
            return this;
        }
        public  Product build() {
            return new Product(this);
        }
    }

}
java
public class Main {
    public static void main(String[] args) {
        Product build = new Product.Builder()
                .name("可乐")
                .packing("瓶装")
                .price(new BigDecimal("3.00"))
                .desc("可乐desc")
                .build();
    }
}
最近更新