31

私は、いくつかのFooを伴うのいくつかFooBuilderの実装がある問題に取り組んでいます。は、設定する必要があるいくつかの共通変数を共有していますが、特定の機能を実装Fooするためにそれぞれが必要とする個別の変数もあります。簡潔にするために、次のように、のセッターにメソッドチェーンを使用さFooBuilderせたいと思います。FooBuilder

public abstract class FooBuilder {
  ...

  public FooBuilder setA(int A) {
    this.A = A;
    return this;
  }

  ...
}

public class FooImplBuilder extends FooBuilder{
  ...
  public FooImplBuilder setB(int B) {
    this.B = B;
    return this;
  }
  public FooImplBuilder setC(int C) {
    this.C = C;
    return this;
  }
  ...
}

など、いくつかの異なるFooBuilder実装があります。これは技術的には私が望むすべてを行いますが、このアプローチはメソッドチェーンが実行されるときのメソッド呼び出しの順序に敏感です。以下には、メソッド未定義のコンパイル エラーがあります。

someFoo.setA(a).setB(b)...

開発者がチェーン内のメソッド呼び出しの順序について考える必要があります。FooBuilderこれを避けるために、セッターが何らかの方法で実際の実装サブクラスを返すようにしたいと思います。しかし、これを行う方法がわかりません。最善のアプローチは何ですか?

4

3 に答える 3

21

これは良い質問であり、実際の問題です。

Java でこれを処理する最も簡単な方法は、Jochen の回答で述べたように、ジェネリックを使用することです。

Using Inheritance with Fluent Interfacesに関するこのブログ エントリには、この問題に関する適切な議論と合理的な解決策があります。これは、ジェネリックとビルダー サブクラスでオーバーライドされるメソッドの定義を組み合わせてgetThis()、常に正しいクラスのビルダーを返すという問題を解決します。

于 2012-06-10T13:40:58.053 に答える
5

ジェネリックはここに行く方法かもしれません。

setA()を次のように宣言すると(擬似コード)

<T> T setA(int a)

コンパイラは実際の型を理解できるはずです。そうでない場合は、次のようなコードでヒントを与えることができます。

obj.<RealFoo>setA(42)
于 2012-06-10T12:18:54.707 に答える