抽象メソッドdoStuff
を宣言する_abstract class A
_があります。現在、A
を継承し、doStuff
を実装するクラスが多数あります。
クラスのインスタンスは、ユーザー入力に基づいてAFactory
を介して実行時に初期化されます。元々、すべてのクラスには同じ単一のパラメーター(ユーザー入力)がありました。しかし、A
を継承する新しいクラスだけが必要とする追加のパラメーターがあります。
だから私は次のロジックについてそれを分解します:
ユーザー入力(もちろんAFactory
を使用)に基づいてインスタンスを生成するインタープリタークラスは、この余分なパラメーターを認識していませんでした。
私の現在の解決策:一方、A.doStuff(Param param)
をA.doStuff(AParams params)
にリファクタリングすることにしました。
AParams
は、必要なパラメータを保持でき、doStuff
は、興味がない場合は無視できます。これは私にとっても少し厄介なようであり、WIN32APIで構造体を送信することを抑制します。この構造体は、醜く役に立たない多くのパラメーターを保持する可能性があり、私はそれが好きではありません。
この問題に取り組むためのよりエレガントな方法はありますか?それとも私が見落とし、これを解決したいくつかのデザインパターン?
注記:
X
がException
をスローする理由とは対照的です)。とにかく尋ねるので、これが重複しているかどうかすみません。編集1:
doStuff
メソッドに渡す必要があります。編集2:
ファクトリのポイントは、わずかに異なるクラスからオブジェクトを取得する可能性があるという事実を隠すことです。したがって、これらのオブジェクトのいくつかが特定のデータを必要とし、他のオブジェクトが必要としない場合...
同じ工場で生産できるほど似ていません。次に、複数の工場を持ち、現在よりも早く決断する必要があります。
または、それらはあるクライアントがどちらが取得するかを気にする必要がないほど十分に似ています。そうすれば、クライアントが追加のデータを送信するかどうかを気にする必要はありません。つまり、それらはalwaysを渡さなければならないということになりますが、ファクトリはクライアントにその実装の詳細を気にせずに無視することがあります。それ以外のものは、工場が隠蔽することになっていた非常に明確な区別でクライアントに負担をかけるでしょう。
私は、さまざまなファクトリを含む Builder のようなものを使用してこれを処理します。 Builderには、さまざまなタイプのオブジェクトを作成するためのファクトリーを含むハッシュが与えられ、ハッシュを調べて、任意の基準に基づいて正しいファクトリーを取得します。
たとえば、私には複数の質問タイプがあり、これらすべてはIQuestionFactoryのいくつかの実装によって作成できます。ほとんどのIQuestionFactory実装はBaseQuestionFactoryのサブクラスであり、1つの質問を表すXMLを受け取り、それを質問のルールに従って解析し、BaseQuestionのいくつかのサブクラスを返します。
一部の質問は、フォーム入力の質問である場合、フォームで使用されるフィールドを定義する質問を含むXMLのセクションがある場合など、詳細情報が必要です。これらの質問を作成するファクトリはIEnhancedQuestionFactoryを実装し、ビルダーはQuestionFactoryRegistryから取得したファクトリをチェックし、このインターフェイスを実装しているかどうかを確認します。含まれている場合は、createQuestionメソッドに渡される個別のXMLに加えて、質問を含むファイルの完全なXMLを渡します。
これがいかに柔軟かを示すために、一部のIQuestionFactory実装は、複数の質問ファクトリーを含む単純なシェルであり、着信XMLを調べて内部ファクトリーを呼び出し、作成したものを返すことができます。これは、XMLファイルに複数の質問タイプが含まれている場合に使用します。
ただし、エクササイズ(基本的には質問のコレクションにラップされたコントローラーです)を構築する方法のようなものが必要と思われます。ハッシュ(ExerciseFactoryMap)は、ほとんどの場合デフォルトのファクトリを返すように設定されていますが、場合によっては特定のファクトリが登録されている場合は、それが返されます。さらに、追加のプロパティを持つExerciseサブクラスを作成する特定のFactoryが1つあります。これには、XMLを調べて、そのプロパティを設定するために必要な情報を見つける追加機能があります。
したがって、私は Killian Foth に同意しますaファクトリのポイントは、オブジェクトの実装の詳細を非表示にすることですが構築されていますが、複数のファクトリを創造的な方法で組み合わせることができないということは何もありません(たとえば、実際の作業を行う他のファクトリを含むファクトリ)。
このような場合の通常のアプローチ(コマンドパターン)では、コンストラクターで追加のパラメーターを渡します。あなたの場合、それは構築中にotherArgument
をB
に追加することを意味します。
ロジックを変えると、いくつかのオプションが開かれる場合があります。たとえば、doStuffをAParamsに移動します。
for (String arg : listOfArgs) {
AParams p = AParams.create(arg, otherArgument));
for (A a : listOfA) {
p.doStuff(a); // Let AParams to the lifting depending on type of A
}
}
または、プライドを飲み込んで、ループでinstanceof
を確認し、otherArgument
を呼び出す前にdoStuff
を手動で設定することもできます。
上記が不可能な場合は、現在行っていること(パラメーター引数を広げる)以外に選択の余地はありません。この項目を過度に分析しないでください。