重构使用Builder模式或Telescoping构造函数模式

BB.*_*BB. 10 parameters refactoring constructor design-patterns

根据Effective Java 2ed Item 2

telescoping构造函数模式,其中您提供仅具有所需参数的构造函数,另一个具有单个可选参数,第三个具有两个可选参数,依此类推,最终在具有所有可选参数的构造函数中.

应用此模式的类的构造函数的示例借用于何时使用Builder模式?

代码集1a

Pizza(int size) { ... }        
Pizza(int size, boolean cheese) { ... }    
Pizza(int size, boolean cheese, boolean pepperoni) { ... }    
Pizza(int size, boolean cheese, boolean pepperoni, boolean bacon) { ... }
Run Code Online (Sandbox Code Playgroud)

size是必需参数.奶酪,意大利辣香肠和培根是可选参数.假设我想提供如下构造函数.

代码集1b

Pizza(int size) { ... }        
Pizza(int size, boolean cheese) { ... }    
Pizza(int size, boolean pepperoni) { ... }    
Pizza(int size, boolean cheese, boolean pepperoni, boolean bacon, int price, int) { ... }
Run Code Online (Sandbox Code Playgroud)

另一个例子是

代码集2

public AttributeKey(String key, Class<T> clazz)
public AttributeKey(String key, Class<T> clazz) 
public AttributeKey(String key, Class<T> clazz, @Nullable T defaultValue, boolean isNullValueAllowed)
public AttributeKey(String key, Class<T> clazz, @Nullable T defaultValue, boolean isNullValueAllowed, @Nullable ResourceBundleUtil labels)
Run Code Online (Sandbox Code Playgroud)

我给出的两个最新例子没有像代码集1a那样遵循伸缩构造函数的特性

  1. 代码集1b和2是否包含在伸缩构造函数中?如果没有,它叫什么?
  2. 与使用Builder Pattern相比,哪一个(在Builder和代码集1a,2之间)提供了更多的好处

And*_*ite 2

在这种情况下,我会选择构建器或不同的机制,调用者可以在其中传递浇头集合。如果您需要验证允许使用哪些浇头,可以在构造函数或浇头设置器中执行此操作。伸缩/链接构造函数方法可能需要您将来添加额外的构造函数来处理额外的配料组合,而集合方法将自动处理任何场景。我还会避免在披萨类中为不同类型的配料提供特定的属性。如果您需要处理额外的奶酪怎么办?单个cheese布尔值无法处理这个问题。该类Topping可以是具有子类的成熟对象,也可以仅用字符串替换它。

public class Pizza
{
    // setters don't have to be private...
    public int Size {get; private set;}
    private List<Topping> toppings {get; private set;}

    public Pizza(int size) : this(size, new List<Topping>()) // call the other ctor with an empty list of toppings
    {
    }

    public Pizza(int size, List<Topping> toppings)
    {
        Size = size;
        Toppings = toppings;
    }
}
Run Code Online (Sandbox Code Playgroud)