web-dev-qa-db-ja.com

「具体化ではなく抽象化に依存する」この用語の正確な意味は何ですか

私は[〜#〜] solid [〜#〜] Webサイトの原則を読んでいましたが、Dの場合-依存関係逆転の原則それは言う:

「具体化ではなく抽象化に依存する」

言い換えると。さまざまなモジュールを抽象レイヤーを使用して互いに分離できるようにソフトウェアを設計する必要があります。

依存関係の逆転の原則の例

SpringフレームワークでのBean構成のこの原則の古典的な使用。

Springフレームワークでは、すべてのモジュールが個別のコンポーネントとして提供され、他のモジュールに依存関係を挿入するだけで連携できます。この依存関係は、XMLファイルで外部的に管理されます。

これらの個別のコンポーネントは、境界が非常に閉じているため、Spring以外のソフトウェアモジュールでも同じように簡単に使用できます。これは、依存関係の逆転とオープンクローズの原則によって達成されました。すべてのモジュールは、別のモジュールの機能またはプラグインを拡張するのに役立つ唯一の抽象化を公開します。

いくつか質問があります。

  • 具体化ではなく、抽象化に依存しますこれは、具体的なクラスではなく、インターフェイスへのコーディングを意味しますか?
  • なぜ春豆の例が与えられるのですか?はい、インターフェイスを使用して依存関係を注入できます。しかし、具体的なクラスを注入することもできますか?
8
kulsin

具体化ではなく、抽象化に依存するそれは、具体的なクラスではなく、インターフェイスへのコーディングを意味しますか?

インターフェースをサポートする言語の場合、これが一般的です。ただし、その抽象化レイヤーは、抽象クラス、ファクトリー、リフレクションなどの他の手段で提供できます。重要なことは、名前付きの具象クラスに要件を直接結合しないことです。

*なぜSpring Beanの例が示されているのですか?はい、インターフェイスを使用して依存関係を注入できます。しかし、具体的なクラスを注入することもできますか?

おそらく、あなたは "(SOLID Principles inJava" (私の強調)を見ているためです。 SpringはJavaで人気のあるDIフレームワークです。 「しかし、具体的なクラスを注入することもできますか?」常に具体的なクラスを注入します。しかし、どの具象クラスはあなたの春の構成によって決定されます。インジェクションの受信者は、特定のクラスではなく、抽象化のみに依存します。他に何か使用して具体的にどのように実装するかを指示することがDIの本質です。

8
David Arno

具体化ではなく、抽象化に依存します。
それは、具体的なクラスではなく、インターフェイスへのコーディングを意味しますか?

「実装ではなく、インターフェイスへのコーディング(interfaceキーワードと混同しないように」)とも呼ばれます。
それは抽象化と呼ばれる古代の技術です。抽象化のどのレイヤーでも、無関係な詳細を隠そうとすることで複雑さを軽減し、より大きくエラーの発生しにくいシステムを構築できるようにします。コストは、それらを隠す方法と、詳細自体を利用しない方法の両方でコストがかかることが多いことです。

クラス、関数、定数などとは何の関係もありません。それは単に契約に依存することを意味し、実装は「私のために働く」(今、ここでは誰も見ていない)と行くのではなく、欠陥と呼ばれる苦痛を尊重しなければならないという約束です。

なぜ春豆の例が与えられるのですか?はい、インターフェイスを使用して依存関係を注入できます。しかし、具体的なクラスを注入することもできますか?

Dependency Inversion Principle(DIP)は、さまざまな実装を簡単に、しかも予想どおりに置き換えることができるため、これに大きく依存しています。

著名なJavaフレームワークが使用される理由は、単にソースがJavaで動作するということです。

classinterfaceのどちらを注入してもDIPに影響はありませんが、interfacesはJavaのMIへのバックドアであり、最小限のハードコードされた動作とデータなし。

6
Deduplicator

抽象化は必ずしもインターフェースを意味するわけではありません。 2つの相互作用するコンポーネントについて考えると、コードの進化に伴って変化するものがありますが、多かれ少なかれ同じままである側面があります。ただし、1つのコンポーネントの変更は、通常、他の依存コンポーネントの変更を引き起こします。

変化しない、または相互作用の本質的な機能を形成するこれらの側面を認識した場合、それらを抽象化に「抽出」します。これらの側面の表現であるもの:インターフェース、具体的または抽象的なベースである可能性があります継承可能なクラス、データ構造、共同作業を行うクラスのセットなどです。ただし、これはnot aboutの間にインターフェースを追加するだけです。これは単なる追加のコードです。インターフェイスは、変更されることなく(ほとんどの場合-安定するまで)ほとんどの場合をカバーするのに十分な表現力を持つ、適切に設計された一般化である必要があります。したがって、正しく理解するのは必ずしも容易ではありません。

いったんそれを行ったら、その抽象化(「インターフェースへのコーディング」と呼ばれるもの)の観点から両方のコンポーネントを書き直します-通常、一方は抽象化を介して呼び出しを行い、もう一方は抽象化の背後にあるサービスを提供します。抽象化によって定義された「契約」を遵守します。

独自のコードで、Bに依存するコンポーネントAがある場合、それらすべてに共通するものを見つけ、それをインターフェイスまたは他の種類に引き出す前に、Bのいくつかの異なるバリアントが出現するのを待つ必要がある場合があります。抽象化の。または、問題の領域について十分に理解していて、優れた抽象化がどのようになるかを推測できる場合もあります。

1