web-dev-qa-db-ja.com

戦略パターンと依存性注入を使用して継承を完全に置き換えることはできますか?

例えば:

var duckBehaviors = new Duckbehavior();
duckBehaviors.quackBehavior = new Quack();
duckBehaviors.flyBehavior = new FlyWithWings();
Duck mallardDuck = new Duck(DuckTypes.MallardDuck, duckBehaviors)

Duckクラスにはすべての動作(抽象)が含まれているため、新しいクラスMallardDuckDuckを拡張)を作成する必要はないようです。

参照:ヘッドファーストデザインパターン、第1章。

10
Deepak Mishra

確かですが、これを構成と委任と呼びます。戦略パターンと依存性注入は構造的に似ているように見えるかもしれませんが、それらの意図は異なります。

ストラテジーパターンを使用すると、同じインターフェイスで実行時に動作を変更できます。私はマガモに飛ぶように言って、羽ばたくのを見ることができました。次に、それをジェットパイロットのアヒルと交換して、デルタ航空で飛ぶのを見てください。プログラムの実行中にそれを行うのは戦略パターンのことです。

Dependency Injectionは、依存関係のハードコーディングを回避して、クライアントが変更されたときにクライアントを変更することなく、独立して変更できるようにする手法です。クライアントは、彼らがどのように満たされるかを知らなくても、単に彼らのニーズを表明します。したがって、それらがどのように満たされるかは、他の場所(通常はメイン)で決定されます。この手法を利用するのに2羽のアヒルは必要ありません。どのアヒルを知らないか気にせずにアヒルを使うものだけです。アヒルを構築したり探したりはしませんが、手にしたアヒルを何でも使って喜んでくれるもの。

具体的なアヒルのクラスがある場合は、フライの動作を実装させることができます。状態変数に基づいて、fly-with-wingsからfly-with-Deltaに動作を切り替えることもできます。その変数は、ブール値、int、またはFlyBehaviorのいずれかで、flyメソッドがあり、ifでテストしなくても、あらゆる飛行スタイルを実行できます。これで、アヒルのタイプを変更せずに飛行スタイルを変更できます。今ではマガモがパイロットになることができます。これは構成と委任です。アヒルはFlyBehaviorで構成されており、飛行要求を委譲できます。このようにしてすべてのアヒルの動作を一度に置き換えるか、各動作または何かの間の任意の組み合わせに対して何かを保持できます。

これにより、継承には1つを除いてすべて同じ権限が与えられます。継承を使用すると、DuckサブタイプでオーバーライドしているDuckメソッドを表現できます。構成と委任では、最初からサブタイプに明示的に委任する必要があります。これははるかに柔軟ですが、より多くのキーボード入力を必要とし、Duckはそれが起こっていることを知る必要があります。

ただし、継承は最初から明示的に設計する必要があると多くの人が信じています。継承されていない場合は、継承を許可しないようにクラスをシール/最終としてマークする必要があります。あなたがその見方をすると、継承は本当に構成と委任に勝るものはありません。なぜなら、どちらの方法でも、最初から拡張性を考慮して設計するか、後で物事を分解する用意があるかです。

物事を壊すことは実際に人気のあるオプションです。問題がある場合があることに注意してください。次のリリースで更新するつもりのないコードのライブラリーまたはモジュールを個別にデプロイした場合、現在の状況について何も知らないクラスのバージョンを処理することに行き詰まる可能性があります。

後で物事を引き裂こうとする意欲があれば、設計のやり直しから解放されますが、アヒルを使用したときに実際に何が行われるかを知らなくても、アヒルを使用するものを設計できるという点で非常に強力です。知らないことは強力なものです。これにより、しばらくの間アヒルについて考えるのをやめ、コードの残りの部分について考えることができます。

「できるか」と「すべきか」は異なる質問です。 継承よりも好きな構成 継承を使用しないとは言わない。継承が最も理にかなっている場合がまだあります。お見せします 私のお気に入りの例

public class LoginFailure : System.ApplicationException {}

継承を使用すると、より具体的でわかりやすい名前の例外を1行で作成できます。

作曲でそれをやってみてください、あなたは混乱を得るでしょう。また、継承の危険を冒すことはありません yo-yo問題 ここには、継承の連鎖を再利用および奨励するデータまたはメソッドがないためです。これがすべて良い名前です。良い名前の価値を過小評価しないでください。

21
candied_orange

ほとんどすべての方法論を他の方法論に置き換えても、機能するソフトウェアを作成できます。それでも、一部の問題は他の問題より特定の問題に適しています。

どれが望ましいかは、多くの事柄に依存します。アプリケーションの先行技術、チームでの経験、予想される将来の発展、個人的な好み、そしていくつか例を挙げると、新人が頭を悩ませるのはどれほど難しいでしょう。

あなたがより経験を積み、他の人々の創造物とより頻繁に苦労するにつれて、あなたはおそらく最後の熟考をより強調するでしょう。

継承は依然として有効で強力なモデリングツールであり、必ずしも最も柔軟であるとは限りませんが、問題ドメインへの明確なマッピングに感謝している可能性がある新しい人々に強力なガイダンスを提供します。

7
Martin Maat