1

假设我有一些具有构造函数的类,每个类都有 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

4

3 回答 3

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 类型的方法和构造函数。

于 2016-02-23T16:53:51.417 回答
0

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

于 2016-02-23T16:51:33.397 回答
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 方法只允许布尔值的有效组合。请注意,每个参数在检查器中指定为设置或未设置以捕获所有无效组合。主类的构造函数需要调用 checker 方法,如果组合无效,则相应地失败。

于 2016-02-23T17:48:20.520 回答