このような状況でどのようなパターンや特定の言語技法が使われているのかわからないという強い気持ちがあります。
それで、問題自体は、OOPをサポートする言語でクラス階層の成長するパラメータリストをどのように管理するかです。つまり、階層内のルートクラス、たとえば3つまたは4つのパラメーターの場合、その派生クラスでは、ベースコンストラクターを呼び出し、オブジェクトの派生部分に追加のパラメーターを渡す必要があります。パラメーターリストは次のようになります。継承の深さが2つ以上ある場合でも、膨大です。
多くのSOwersがこの問題に直面したと確信しています。そして、私はそれを解決する方法に興味があります。よろしくお願いします。
6 に答える
長いパラメーターリストを持つコンストラクターは、クラスがやりすぎを試みていることを示しています。この問題を解決するための1つのアプローチは、問題を分解し、「コーディネーター」クラスを使用して問題を管理することです。スーパークラスとは大幅に異なるコンストラクターパラメーターリストを持つサブクラスは、クラスのパフォーマンスが高すぎるもう1つの例です。サブクラスが本当にスーパークラスである場合、その仕事をするためにそれほど多くのデータを必要とすべきではありません。
とはいえ、クラスが多数の関連オブジェクトを処理する必要がある場合があります。この状況では、関連するパラメーターを保持するための新しいオブジェクトを作成します。
代替案:
- コンストラクタインジェクションの代わりにセッターインジェクションを使用する
- パラメータを別のコンテナクラスにカプセル化し、代わりにコンストラクタ間で渡します。
可能性:
- 事前に提供するために非常に多くの状態を必要とする場合、おそらくあなたのクラスはやりすぎですか?単一責任の原則を順守することを目指します。
- おそらく、これらのパラメーターのいくつかは、それ自体がパラメーターとして渡される独自の値オブジェクトに論理的に存在する必要がありますか?
- 構築が実際に複雑なクラスの場合は、ビルダーまたはファクトリパターンを使用して、これらのオブジェクトを読みやすい方法でインスタンス化することを検討してください。メソッド名とは異なり、コンストラクターパラメーターには自己文書化する機能がありません。
オブジェクト全体を一度に初期化するためにコンストラクターを使用しないでください。(1)オブジェクトの存在に絶対に必要なもの、および(2)オブジェクトの作成時にすぐに実行する必要があるもののみを初期化します。これにより、渡す必要のあるパラメーターの数が劇的に減少します(ゼロになる可能性があります)。
このような一般的な階層SalariedEmployee >> Employee >> Person
では、オブジェクトのさまざまなプロパティを取得および変更するためのゲッターとセッターがあります。
コードを見ると、解決策を提案するのに役立ちます。
ただし、長いパラメータリストはコードの臭いなので、これを必要とする設計を注意深く見ていきます。これに対抗するために提案されたリファクタリングは次のとおりです。
ただし、これと長い継承チェーンが絶対に必要であることがわかった場合は、オブジェクトのようなハッシュ/プロパティバッグを唯一のパラメータとして使用することを検討してください
public MyClass(PropertyBag configSettings)
{
// each class extracts properties it needs and applies them
m_Setting1 = configSettings["Setting1"];
}
もう1つのヒント:クラス階層を浅く保ち、継承よりも構成を優先します。そうすれば、コンストラクターのパラメーターリストは短くなります。