Java减少了构造函数的数量

时间:2016-02-23 16:49:50

标签: java builder-pattern

假设我有一些具有构造函数的类,每个构造函数都有2个参数 例如,我有5种类型,其中两种可以作为第一个参数传递,三个作为第二种传递

假设类型为A,B,C,D,E。基本上我有这样的事情:

public SomeClass(A,C) {}
public SomeClass(A,D) {}
public SomeClass(A,E) {}

public SomeClass(B,C) {}
public SomeClass(B,D) {}
public SomeClass(B,E) {}

因此,您可以看到这些类型的所有可能组合 并且没有可选的参数,例如标准的构建器模式。

我可以做些什么来减少构造函数?有什么模式可以帮助我吗?

修改

我不能使用标准制造商,因为如果我提供A,那么我就无法供应B. 如果我提供了C,那么我就无法提供D或E

3 个答案:

答案 0 :(得分:2)

您可以创建受限制的构建器模式:

class MyBuilder {

    public MyBuilder(A) { ... }
    public MyBuilder(B) { ... }

    public SomeClass build(C) { ... }
    public SomeClass build(D) { ... }
    public SomeClass build(E) { ... }

}

使用示例:

new MyBuilder(A).build(C)

如果您只有6种可能的组合,我可能会容忍现有代码中的复杂性和重复。但如果有更多的可能性和/或将来会扩展代码,那么我会在这里推荐这种模式。

您可以将此模式扩展为更多参数,但由于需要更多中间类,因此它会变得更加丑陋。对于3个参数,您可以实现类似:

class MyBuilder1 {
    public MyBuilder1(A) { ... }
    public MyBuilder1(B) { ... }

    public MyBuilder2 build(C) { ... }
    public MyBuilder2 build(D) { ... }
    public MyBuilder2 build(E) { ... }

    class MyBuilder2 {
        public MyBuilder2(C) { ... }
        public MyBuilder2(D) { ... }
        public MyBuilder2(E) { ... }

        public SomeClass build(F) { ... }
        public SomeClass build(G) { ... }
    }
}

SomeClass x = new MyBuilder1(B).build(D).build(F);

不幸的是,中间阶段需要复制C,D,E类型的方法和构造函数。

答案 1 :(得分:0)

创建2个接口,一个用于第一个参数,一个用于第二个参数。 A和B实现第一个,C,D和E是第二个。

答案 2 :(得分:0)

一个建议。将逻辑放入构建器等效类中。添加一个方法来检查参数组合是否有效。

class MyBuilder {

  int paramA;
  bool paramAset = false;

  long paramB
  bool paramBset = false;

  // etc for all parameters.

  void setParamA(int newAval) {
    if (checkParamA(newAval)) {
      paramA = newVal;
      paramAset = true;
    }
  }

  void setParamB(long newBval) {
    if (checkParamB(newBval)) {
      paramB = newBval;
      paramBset = true;
    }
  }

  // etc. for all parameters.

  // Parameter checker method.
  bool checkValid() {
    if (
        paramAset && !paramBset && /* other params */ ||
        !paramAset && paramBset && /* other params */ ||
        // other allowed parameter combinations
       ) {
      return true;
    } else {
      return false;
    }
  }

} // end class MyBuilder

每个参数都有自己的值和一个布尔值来表示它是否已设置。检查器方法仅允许布尔值的有效组合。请注意,每个参数都指定为设置或未设置在检查器中以捕获所有无效组合。主类的构造函数需要调用checker方法,如果组合无效,则需要适当地失败。