构建器模式的实现

Implementing the builder pattern

我见过两种流行的构建器模式实现方法:

// 1. The build() approach
Product p = builder.part1()
                   .part2()
                   .build();

// 2.The constructor approach
builder.part1()
       .part2();
Product p = new Product(builder);

以下哪个更好?

第一个是要走的路...

如果您使用第二个选择,那么这样做:

Product p = new Product(builder);

将为产品添加依赖项class..

这意味着产品 class 现在至少需要一个带有参数 builder

的构造函数

我倾向于结合使用这两个示例。

我会在产品 class 中定义一个构建器 class 并为产品 class 提供一个采用 ProductBuilder 的私有构造函数。

这个问题有点模糊,但是如果你有一个静态构建器 class,joshua bloch 的有效 java 书建议一个结构更像第一个带有构建方法的结构。这是一种更清洁、更安全的方式。

Product p= new Product.ProductBuilder("hw", "sw")
    .version(30)
    .mac("1234567")
    .address("Fake address 1234")
    .build();

这是两种不同的方法。权衡是不同的。 您必须根据您的需要和上下文使用和调整模式,而不是根据硬性规则...

使用类似的生成器:

Product p = new Product(builder);

允许创建您的构建器并重复使用它。 如果您需要重用构建器或在另一个 class 中创建构建器,这是一个很好的实现。你打开你的 API 因为你需要它。
该解决方案的缺点是无法直接创建对象。
关于设计质量和依赖性,我认为这是一个错误的问题。 是的,使用 Product 的 public 构造函数,您可以在 Product 和构建器之间创建 public 依赖关系,并公开 Product 构造函数。 但是,如果在 Product 构造函数中,您将构建 Product 的任务分派给构建器实例,耦合是否会降低代码的灵活性? Never.
此外,真正的耦合位于 Product 构造中,因为构建器使用镜像属性来构建 Product 对象。因此,无论发生什么,真正的强耦合都会保持不变:这两个 classes 必须一起工作并且必须看起来像。

使用类似的生成器:

Product p = builder.part1()
               .part2()
               .build();

不允许重用构建器,但更直接地用于 class 的客户端,并且它至少打开了构建器与产品之间的依赖关系。 如果您不需要重复使用构建器或在另一个 class 中创建构建器,这是最好的,因为您不会以无用的方式打开您的 API。

所以,事实上,这两种解决方案都很接近。 如果我必须重用构建器或者我需要在另一个 class 中创建构建器,我会使用带有构造函数的解决方案,如果不需要,我会使用没有构造函数的解决方案。