Design patterns 增强构建器-对构建器进行子类化或创建构建器装饰器?

Design patterns 增强构建器-对构建器进行子类化或创建构建器装饰器?,design-patterns,Design Patterns,我正在设计一个新的应用程序,并考虑以下问题 背景信息 我将有一个名为HouseBuilder的builder类来构建House类型的对象。建造商将提供以下方法: buildRoof() buildWindow() buildDoor() 等等, getHouse() 在客户机代码中,我通常会使用以下生成器类: HouseBuilder builder = new HouseBuilder(); House house = builder.buildRoof().buildWindow().

我正在设计一个新的应用程序,并考虑以下问题


背景信息

我将有一个名为HouseBuilder的builder类来构建House类型的对象。建造商将提供以下方法:

  • buildRoof()
  • buildWindow()
  • buildDoor()
  • 等等,
  • getHouse()
在客户机代码中,我通常会使用以下生成器类:

HouseBuilder builder = new HouseBuilder();
House house = builder.buildRoof().buildWindow().buildWindow().buildDoor().getHouse();
HouseBuilder builder = new CottageBuilder();
House house = builder.buildCottage().getHouse();
这是正在使用的生成器设计模式的经典示例


问题

在客户端代码中,我需要构建一个特定类型的房子,比如说一个小屋。每次我需要一个新的构建块时,从基本的构建块构建小屋(如上面的示例中所示)似乎都有很多不必要的重复代码

因此,我将创建一个新的构建器类,比如CottageBuilder,它将允许如下内容:

HouseBuilder builder = new HouseBuilder();
House house = builder.buildRoof().buildWindow().buildWindow().buildDoor().getHouse();
HouseBuilder builder = new CottageBuilder();
House house = builder.buildCottage().getHouse();
我不确定设计CottageBuilder的最佳方法是什么。我想到两个选择:

  • 让CottageBuilder成为房屋建筑商的子类,并在Build小屋方法中使用父类的方法
  • 让CottageBuilder接受一个HouseBuilder实例,并在Build小屋方法中调用它的方法(无论如何,我都会让CottageBuilder子类化HouseBuilder,以获得多态性行为——因此我会让CottageBuilder成为HouseBuilder周围的装饰者)
哪种方法更好

我能想到的第二种方法的一个缺点是CottageBuilder需要依赖于另一个HouseBuilder实例,我会让它在其构造函数中请求依赖关系。然而,从客户端代码的角度来看,将HouseBuilder实例设置到CottageBuilder实例中似乎很奇怪


请注意,我的构建者实际上并不是要构建房屋对象,而是来自不同域的对象。我决定不通过描述目标域来污染这个问题,而是建立这个类比,在我看来,这个类比非常适合原始问题。

一个“构建者”通常通过一系列步骤来构建对象,例如您的示例中的
房屋构建者。您的
CottageBuilder
实际上不是一个建筑商,而是一个返回特定类型房屋的“工厂”。因此,我将有一个
HouseFactory
类,其中包含用于创建不同类型房屋的静态方法:

public class HouseFactory {
  public static House createCottage() {
    HouseBuilder builder = new HouseBuilder();
    // use builder to build cottage
    return builder.getHouse();
  }

  // more methods for other types of houses
}

CottageBuilder
是否总是建造相同类型的房子,或者是否可以像
HouseBuilder
那样进行进一步定制?总是建造相同类型的房子。我正在寻找一种创建小屋的捷径的最佳方法,而不是每次我需要新的小屋时都从基本的建筑块中创建。听起来不错,谢谢!不过,我不会让CreateChattle方法是静态的,而是让HouseFactory接受HouseBuilder的实例作为构造函数参数。测试、重用等应该更容易。@DušanRychnovský:我通常避免使用静态类,但这是一个可以接受的用例,因为
createbutch
只是一个实用方法——正如您前面提到的,“创建小屋的快捷方式”,而不是重复代码。如果你真的觉得有必要测试这个方法,那么你应该把它重构成更小的可测试的部分。