web-dev-qa-db-ja.com

クラスによって多くのステップが実行されるときにコンストラクターで多くのオブジェクトを回避する方法

特定の順序で8つのステップを実行する必要があるプロセスがあります。ステップの1つは、電子メールの送信、別のFTPサーバーでの送信、データベースのクエリなどです。これらの8つのステップを単体テストできるようにするには、それぞれを個別のクラスのメソッドにします。ここまでは順調ですね。

ここで私が直面している問題は、ステップを呼び出す「親」クラスがコンストラクター8クラスで受信されることです。これは明らかにコードの匂いです。最初の4つのステップで1つのクラスを作成し、他の4つのステップで別のクラスを作成するだけで、親はコンストラクターで2つのクラスを受け取るだけです。私の考えでは、これも間違っているように感じます。複雑さを増しているので、問題を実際に解決しているわけではないという印象があります。

クラスが多くのステップを呼び出さなければならないときに使用するデザインパターンまたは別のテクニックはありますか?

5
user1861857

クラスが操作に制御されたシーケンスを提供するだけであり、各操作の複雑さが依存クラスによって管理されている点までクラスが本当に単純化されている場合、解決すべき問題はないと思います。

このプロセスの操作のシーケンスが本当に8ステップである場合、8つの依存関係を持つコンストラクターは、プロセスの複雑さを適切に公開します。

リファクタリングを検討する必要がある場合、それはプロセスそのものです。簡略化できますか?少ないステップで済むのでしょうか?そうでない場合は、必要なだけシンプル/複雑であり、調整クラスのコンストラクターはそれを反映する必要があります。

任意のステップグループ化によって必要な複雑さを隠そうとすると、大規模なコンストラクターよりもコードの臭いが悪くなります。

9
Eric King

良い警告であるエリックキングの答えにさらに。

一連の操作をシーケンス処理する必要がある場合は、それらを呼び出すことができる共通のインターフェースを提供できるほど類似しているかどうかを検討し、それらを抽象タスクのコレクションとして扱うことができるようにします。

考慮すべきもう1つのことは、部品を変更または交換する必要がある場合-変更したい場合-物事をどのように再配置したいかがより明白になるかもしれません。

あなたの解決策は問題と同じ「形」であり、これはしばしば良い兆候です。

3
Jamie

8つのクラス間に相互作用はありますか?そうでない場合、1つの可能性は、8つのクラスすべてが単一の関数doTheThing()を持つインターフェースを実装することです(さまざまなサンプル関数名、実際のコードでは使用しないでください)。次に、それらを渡すことができます。 8つの個別のパラメータとしてではなく、IList内。次に、「親」クラスは、このリストを反復処理し、各メンバーに対してdoTheThing()を呼び出すだけです。

0
Pete