AndroidでSimpleExpandableListAdapter
を拡張しています。 Androidのアダプターは、コンストラクターにかなり複雑な引数が多数あり、セッターやビルダーがないため、あまりうまく実装されていないと思います。私のクラスでは、これらの引数のほとんどは呼び出し元のクラスに依存していないため、内部的に構築したいと思います。ただし、引数はネストされたList
sと、プログラムで構築する必要がある整数と文字列の配列です。
super
コンストラクターの前には何も呼び出すことができず、super
呼び出しが戻る前にインスタンスメソッドを呼び出すことができないため、super
から呼び出す静的メソッドがいくつかありますコール:
super(getContext(), initGroupData(), groupLayout, initGroupFrom(), initGroupTo(),
initChildData(), childLayout, initChildFrom(), initChildTo());
これを処理する方法は3つあります。私と同じように静的メソッドを呼び出す、おそらくこれらと同じメソッドを呼び出して静的変数を初期化してsuper
呼び出しで使用する、またはこれらすべてをカプセル化する大きな静的イニシャライザを使用するメソッドをビルダーに組み込みます。
今はビルダーに傾いていると思いますが、これを処理するためのより良い方法があるかどうか疑問に思っています。
静的ヘルパー関数を使用してコンストラクター引数を作成することは完全に正気のソリューションですが、これらの関数はそれぞれ正確に1つの引数を生成する必要があり、互いに通信できないため、実行できる操作が制限されます。
インターフェースConstructor(A, B, C)
をより使いやすいインターフェースConstructor(X, Y)
に適合させる最も一般的なケースでは、プライベートArgumentObject
を受け取るプライベートヘルパーコンストラクターを定義できます。既存のコンストラクタにチェーンします。次に、より使いやすいコンストラクターが静的ヘルパー関数を介してヘルパーコンストラクターにチェーンし、引数オブジェクトを作成します。
_class Constructor {
// constructor you want to wrap
public Constructor(A a, B b, C c) { ... }
// better constructor you are defining
public Constructor(X x, Y y) { this(createArgumentObject(x, y)); }
// helper constructor using an ArgumentObject
private Constructor(ArgumentObject ao) { this(ao.a, ao.b, ao.c); }
// helper to create the argument object
private static ArgumentObject createArgumentObject(X x, Y y) { ... }
private static class ArgumentObject { ... }
}
_
同じクラス(C++ 03など)内にチェーンコンストラクターがない言語では、ヘルパーコンストラクターの中間サブクラスを定義する必要があります。
ただし、この手法は、コンストラクター引数での静的関数の使用を一般化したものにすぎません。あなたが提案した他のソリューションにはさまざまな欠点があります。そのため、それらを好む十分な理由がない限り、私はそれらを回避します。
優れたビルダーを実装するには、非常に小さな価値のために多大な労力が必要です。新しいコンストラクターが十分に単純であれば、ビルダーなしで実行できます。ラップしているクラスが確実な検証を実行すると仮定すると、Constructor(new Constructor.Arguments {{ foo = 42; bar = baz; }})
イディオムを使用して引数を渡すことができるように、引数オブジェクトをパブリックにすることができます。
静的初期化ブロックで計算された静的変数を使用することは、真に静的なデータには意味がありますが、グローバル状態を回避するように注意する必要があります。初期化が非常に単純な場合を除き、初期化をテスト可能にするには、静的関数を使用してこれらの変数を初期化する必要があります。現在、静的メソッドを直接使用することの唯一の利点は、値が一度だけ計算され、すべての初期化で再利用されることです。
あなたの質問はこれらの初期化がより複雑になる可能性があることを示しているので、静的な初期化子ブロックを使用することは、テスト容易性があなたにとって重要である場合、大きなノーノーです。 (そうでない場合は、より緊急の問題があります。)