清除对建造者模式的疑虑

sfr*_*frj 8 java design-patterns builder

我正在学习构建器模式,到目前为止我了解到,它是用于初始化的常用模式的一个很好的替代方案:

  • 伸缩构造函数模式

  • JavaBean模式

问题是,我真的不想从我的域模型中的对象中删除getter和setter.我总是喜欢把它们当作POJO.我不喜欢它的原因之一是:如果我不使用POJO,那么在使用ORM框架时注释变量并不容易......

所以这是我的疑惑: - 是否可以在不使用静态内部类的情况下实现构建器模式? - 如果我必须使用内部类来使用构建器模式,你认为保持getter和setter是正确的吗? - 我为练习做了一个小例子,我试图避开内部课程.你能告诉我你怎么看待它?

产品

    public class Product
{
    private String color;
    private int price;

    public Product() {
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public String toString() {
        return getColor() + "\n" + getPrice();
    }    
}
Run Code Online (Sandbox Code Playgroud)

生成器

public class Builder
{
    private Product product;

    public Builder() {
        product = new Product();
    }
    public Builder withColor(String color) {        
        product.setColor(color);
        return this;
    }

     public Builder withPrice(int price) {        
        product.setPrice(price);
        return this;
    }
    public Product build() {
        return product;
    }
}**
Run Code Online (Sandbox Code Playgroud)

客户

public class Client
{

    public static void main(String[] args) {
        System.out.println(new Builder().withColor("Black").withPrice(11).build());
        System.out.println("-----------------------------------------------------");
        System.out.println(new Builder().withColor("Blue").withPrice(12).build());
    }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

小智 12

Builder模式对于创建不可变对象很有用,并且避免使用带有可选参数的多个构造函数.

IMO使用Builder模式构建可以使用setter更新的POJO是没用的.您只需创建一个附加类.

根据使用的ORM框架,可能不需要存在setter方法.但只能通过反思来分配成员价值.

产品类别:

public final class Product {
    private final String color;
    private final int price;

    public Product(Builder builder) {
        this.color = builder.getColor();
        this.price = builder.getPrice();
    }

    public String getColor() {
        return color;
    }

    public int getPrice() {
        return price;
    }

    public String toString() {
        return getColor() + "\n" + getPrice();
    }    
}
Run Code Online (Sandbox Code Playgroud)

Builder类:

public final class Builder {

    private String color;
    private int price;

    public Builder() {
        // Assign any default values
    }

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

    public Builder price(int price) {        
        this.price = price;
        return this;
    }

    protected String getColor() {
        return color;
    }

    protected int getPrice() {
        return price;
    }

    public Product build() {
        return new Product(this);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 在构建器中使用getter有一个缺点,它使得编写意大利面条代码变得更加容易.以我的答案为例. (2认同)

Phi*_*ipp 5

构建器模式在不可变对象的上下文中最有用。根据定义,不可变对象没有 setter。因此它们的所有属性都必须被压缩到构造函数中。这就是构建器模式派上用场的地方。它允许您将复杂的不可变对象的初始化拆分为多个不言自明的指令,这样您就不需要像这个虚构的示例那样在您的代码中进行构造函数调用,而您无法分辨哪个参数执行什么操作:

Thing foo = new Thing(1, 125, Thing.SOMETHING, new Whatchamacallit(17, 676), getStuffManager(StuffManager.ZOMG), true, false, false, maybe);
Run Code Online (Sandbox Code Playgroud)

我发现当创建的对象是可变的时,构建器模式不会创建任何重要的值。您通过构建器所做的一切也可以直接使用创建的对象来完成。

另外,我认为上面的程序不是构建器模式的教科书示例。您通常不会通过将构建器传递给构造函数来创建对象。您可以通过调用构建器上的方法来创建对象create,然后将其所有属性传递给对象的构造函数。此模式的优点是,它使构建器有机会检查其内部状态的一致性,并可能在开始构建对象之前抛出异常。

java StringBuildertostring类就是一个很好的例子(本例中是 create 方法)。