在生成器模式中,我们是否需要一个 .build() 方法?

我有一个关于“有效Java”中涵盖的“生成器模式”的问题。我们是否需要一种方法来正确实现模式?例如,假设我们有以下类:.build()

public class CoffeeDrink {

    private int numEspressoShots;
    private short milkType;
    private boolean withWhip;

    private CoffeeDrink() {
    }

    public static CoffeeDrink buildNewDrink() {
        return new CoffeeDrink();
    }

    public CoffeeDrink withEspresso(int n) {
        this.numEspressoShots = n;
        return this;
    }

    public CoffeeDrink withMilkType(shot t) {
        this.milkType = t;
        return this;
    }

    public CoffeeDrink withWhip() {
        this.withWhip = true;
        return this;
    }
}

然后我们如何使用它:

CoffeeDrink c = CoffeeDrink.buildNewDrink()
                         .withEspresso(2)
                         .withMilkType(2)
                         .withWhip();

如果我没有静态内部类,这是否仍然有效?我想其中一个优点是,在调用方法之前,它无法创建新对象,但我仍在创建一个对象。只是寻求一些澄清。BuilderCoffeeDrink.build()Builder


答案 1

不,这不是生成器模式。它是有效的Java,它将编译并运行。但是,您的方法,无论是调用还是其他方法,都只是一个简单的工厂方法,用于创建.这些其他方法就像碰巧返回自己的 setter 方法。buildNewDrink()build()buildNewDrink()CoffeeDrink

嵌套生成器类是必需的。在暂缓创建类实例的同时,它可以执行验证逻辑以确保不会创建无效对象。我不确定 a 是否存在无效状态,但如果它确实如此,使用您的代码,则可以在创建后但在调用其他方法之前创建一个并使其处于无效状态。生成器模式通过在构建实例之前验证数据来消除这种可能性。它还消除了构造函数爆炸的需要,其中需要许多具有所有可能的参数组合的构造函数,以涵盖所有可能的情况。staticCoffeeDrinkCoffeeDrink


答案 2

根据GoF参考,不是必需的。原始引用不使用链接,并且在方法的末尾有一个步骤。该类负责封装构建过程,因此他们不必担心是否正确构建了内容。这是.build()getResult()Director.construct()DirectorClientDirector

下面是生成器上 GoF 引用的序列图:

GoF Builder Sequence Diagram


推荐