既存の抽象クラスとそのパラメーターのリファクタリング


8

私が持っているabstract class A抽象メソッドを宣言しているがdoStuff。現在、を継承しAて実装するクラスが多数ありますdoStuff

クラスのインスタンスはAFactory、ユーザー入力に基づいて実行時に初期化されます。元々、すべてのクラスには同じ単一のパラメーター(ユーザー入力)がありました。しかし今、私はAニーズを継承する新しいクラスだけである追加のパラメーターを持っています。

だから私はそれを次のロジックで分解します:

  • ユーザー入力(AFactoryもちろん使用)に基づいてインスタンスを生成するインタープリタークラスは、この追加のパラメーターを認識していませんでした。

    • それをクラスインタープリタクラスにプッシュしようとすると、本当に厄介なことになります。それは、いつファクトリーに渡すかを知らなければならず、そもそもファクトリーを持つという全体の目的に反するためです。
    • それを何かに使うかもしれないと期待して盲目的にファクトリーに送ることも、かなり醜いようです。
  • 私の現在の解決策:一方、にリファクタリングA.doStuff(Param param)することにしましたA.doStuff(AParams params)

    AParams必要なパラメータをすべて保持doStuffでき、興味がない場合は無視できます。これは私にとっても少し厄介なようで、WIN32APIで構造体を送信することを抑制します。この構造体は、醜く役に立たない多くのパラメーターを保持する可能性があり、私はそれが好きではありません。

この問題に取り組むよりエレガントな方法はありますか?それとも私が見落とし、これを解決したいくつかのデザインパターン?

  • Java 1.7を使用しています
  • クラスの名前は、理論上の設計上の問題を強調するためにばかげていますが、実際には、わかりやすく意味のある名前が付けられています。
  • 私はかなり多くのことを検索しましたが、(このコードをXスローしている理由とは対照的に)特定の抽象的な理論的な問題をWebで検索するのは非常に難しいことがわかったExceptionので、とにかく尋ねることにしたので、これが複製。

編集1

  • 明確化:サブクラス固有の引数をdoStuffメソッドに渡す必要があります。

編集2

  • 私はKilian Fothの意図を完全には理解していなかったので、問題をよりよく説明し、解決策を理解するのに役立つJava疑似コードをいくつか書きました。そう:

    これは私の問題の骨組みです。

    これは私のソリューションの骨組みです。

    これは キリアンフォスの解決策かもしれないと思いますが、よくわかりません。


問題が、特定のサブクラスのファクトリメソッドに特定の引数を追加する必要があるかどうか、またはサブクラス固有の引数をdoStuffメソッドに渡す必要があるかどうかを明確にできますか?
マーティンウィックマン2013

@MartinWickman答えは次のとおりです。サブクラス固有の引数をdoStuffメソッドに渡す必要があります。これを提示してくれてありがとう、私は十分に明確ではなかったことをお詫び申し上げますが、今はより良いと思います:) 質問を編集しました...
Scis

リンクしているソリューションでビルダーに似たものを見つけたようです(これは私が行ったことです-ビルダーについて聞いたことがありませんが、必要なことを行うコードを作成しただけです)行う)。
エイミーブランケンシップ2013

本当にparamをdoStuffに渡す必要がありますか、それともオブジェクトを構築するときにparam値がわかっていますか?また、追加のパラメーターはどこから来ますか?
アーロンクルツハルス2013

@AaronKurtzhals「問題」のスケルトンファイルで書いたように、現在、追加のパラメーターの値は、EntryPointそれmainを呼び出しInterpreterて、パラメーターとして追加のパラメーターを現在受け取っていないものを呼び出し、ファクトリーを呼び出すことがわかっています。追加のパラメーターは、UserInput(残念ながら変更できない)で説明されていない別のタイプのユーザー入力に由来します。
Scis 2013

回答:


9

ファクトリのポイントは、わずかに異なるクラスからオブジェクトを取得する可能性があるという事実を隠すことです。したがって、これらのオブジェクトのいくつかが特定のデータを必要とし、他のオブジェクトが必要としない場合...

  • 同じ工場で生産できるほど似ていません。次に、複数の工場を持ち、現在よりも早く決断する必要があります。

  • それとも、あるクライアントは、彼らが得る1世話になっていないことに類似十分。そうすれば、クライアントが追加のデータを送信するかどうかを気にする必要はありません。したがって、それらは常に渡される必要がありますが、ファクトリはクライアントにその実装の詳細を気にせずに無視することがあります。それ以外のものは、工場が隠蔽することになっていた非常に明確な区別でクライアントに負担をかけます。


まあそれら十分に似ています :)しかし、私はあなたの解決策を理解しているのかわかりません。編集した質問を見て(問題と異なるアプローチを示すスケルトンを作成しようとしました)、私の解釈が正しいかどうか教えてください。
Scis 2013

2

私は、さまざまなファクトリを含むビルダーのようなものを使用してこれを処理します。Builderには、さまざまなタイプのオブジェクトを作成するためのファクトリーを含むハッシュが与えられ、ハッシュを調べて、任意の基準に基づいて正しいファクトリーを取得します。

たとえば、私には複数の質問タイプがあり、これらすべてはIQuestionFactoryのいくつかの実装によって作成できます。ほとんどのIQuestionFactory実装はBaseQuestionFactoryのサブクラスであり、1つの質問を表すXMLを受け取り、それを質問のルールに従って解析し、BaseQuestionのいくつかのサブクラスを返します。

一部の質問は、フォーム入力の質問である場合、フォームで使用されるフィールドを定義する質問を含むXMLのセクションがある場合など、詳細情報が必要です。これらの質問を作成するファクトリはIEnhancedQuestionFactoryを実装し、ビルダーはQuestionFactoryRegistryから取得したファクトリをチェックし、このインターフェイスを実装しているかどうかを確認します。含まれている場合は、createQuestionメソッドに渡される個別のXMLに加えて、質問を含むファイルの完全なXMLを渡します。

これがいかに柔軟かを示すために、IQuestionFactory実装のいくつかは、複数の質問ファクトリを含む単純なシェルであり、受信XMLを調べて内部ファクトリーを呼び出し、何でもできるものを返すことができます。これは、XMLファイルに複数の質問タイプが含まれている場合に使用します。

ただし、エクササイズ(基本的には質問のコレクションにラップされたコントローラーです)を構築する方法のようなものが必要であるように思われます。特定のファクトリが登録されている場合は、それが返されます。また、追加のプロパティを持つExerciseサブクラスを作成する特定のFactoryが1つあります。これには、XMLを調べて、そのプロパティを設定するために必要な情報を見つける追加機能があります。

だから、私は同意するだろうキリアンFothのポイントというの工場は、オブジェクトが構築されているかの実装の詳細を非表示にすることですが、あなたは、工場(たとえば、クリエイティブな方法で複数の工場を組み合わせることはできませんと言うものはありません実際の作業を行う他のファクトリが含まれています)。


2
  • このような場合の通常のアプローチ(コマンドパターン)では、コンストラクターで追加のパラメーターを渡します。あなたの場合、それは建設中に追加すること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

上記が不可能な場合は、現在行っていること(パラメーター引数を広げる)以外に選択の余地はありません。この項目を過度に分析しないでください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.