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

时间:2011-04-09 05:30:33

标签: design-patterns parameters constructor refactoring

根据Effective Java 2ed 第2项

  

伸缩构造函数模式,in   你提供了一个构造函数   只有所需的参数,另一个   使用单个可选参数,a   第三个有两个可选参数,   等等,最终成为一个   所有可选的构造函数   参数。

应用此模式的类的构造函数示例来自When would you use the Builder Pattern?

代码集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) { ... }

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) { ... }

另一个例子是

代码集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)

最新的两个例子我给没有遵循伸缩构造函数的特性,因为代码集1a没有

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

2 个答案:

答案 0 :(得分:2)

  

这种构造函数参数的模式叫什么?

这本身不是设计模式,但它是一种称为构造函数链接的编程技术。

  

与使用Builder Pattern相比,哪一个提供更多好处

同样的问题:你借来的When would you use the Builder Pattern?也很好地解释了差异。简而言之,构造函数优于构造函数链接,因为它可能导致构造函数的增殖,这可能变得难以维护。

希望有所帮助。

答案 1 :(得分:1)

在这种情况下,我会选择构建器或调用者可以传递一组浇头的不同机制。如果需要验证允许的配件,可以在构造函数或Toppings setter中执行此操作。伸缩/链接构造方法可能要求您在将来添加其他构造函数以处理其他浇头组合,而收集方法将自动处理任何方案。我也会避免在披萨类中为不同类型的浇头提供特定属性。如果你需要处理额外的奶酪怎么办?单个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;
    }
}