Open Closed Principle(OCP)とDependency Inversion Princible(DIP)の違いを理解しようとしていました。
これまでにインターネットで行った調査に基づいて、「DIPはOCPを達成するための1つのオプション」という結論に達しました。
これでいいの?
DIPではなくOCPに従っている例を教えてください。
Open Closed Principle(OCP)とDependency Inversion Princible(DIP)の違いを理解しようとしていました。
これまでにインターネットで行った調査に基づいて、「DIPはOCPを達成するための1つのオプション」という結論に達しました。
これでいいの?
DIPではなくOCPに従っている例を教えてください。
回答:
以前に、オープンクローズドプリンシパル(OCP)とリスコフの代用プリンシプル(LSP)について回答を書きましたが、これらの原則は相互に大きく関連していますが、一方はあるが他方はないといういくつかの不自然な例では概念的に異なっています。この答えのために、OCPについて簡単に触れて、DIPの詳細とそのチェックの理由について説明します。
まず、異なる原則を最初に説明することにより、依存関係反転原理(DIP)とOCPがどのように関連し、どのように異なるかについて議論してみましょう。
ボブおじさんのOODの原則を読むと、DIPが次のように述べていることがわかります。
コンクリートではなく、抽象に依存します。
Javaでの抽象化はinterface
、abstract
キーワードとキーワードで簡単に実現されます。つまり、コードが従わなければならないソフトウェアエンティティの「契約」があります。一部のプログラミング言語には、従うコードの動作を明示的に設定する機能がないため、コンパイラーが契約の実施を支援するのではなく、より手動で抽象化に従う必要があります。たとえば、C ++には、仮想メソッドを持つクラスや、Javascriptなどの動的プログラミング言語があり、オブジェクトを同じ方法で使用する必要があります(ただし、Javascriptの場合は、TypeScriptで拡張され、型システムを追加して支援します)コンパイラーによって検証される契約書を作成します)。
名前には、「反転」という用語が含まれます。これは、伝統的に(プログラミングの古い暗黒時代では知っている)、低レベルモジュールに依存する高レベルモジュールを含むソフトウェア構造を記述したためです。たとえばButtonAtKitchen
、a KitchenLamp1
およびの入力を処理することは理にかなっていKitchenLamp2
ます。残念なことに、ソフトウェアは必要以上に具体的になり、オブジェクトグラフは次のようになります。
したがって、「契約」を追加することにより、ソフトウェアをより一般的なものにします。オブジェクトグラフの矢印がどのように方向を「反転」するかに注目してください。そのキッチンランプは今、に依存していButton
ます。言い換えれば、詳細は現在、他の方法ではなく抽象化に依存しています。
したがって、DIPのより一般的な定義は、Uncle BobによるDIPの元の記事でも詳述されています。
A.高レベルモジュールは低レベルモジュールに依存しないでください。どちらも抽象化に依存する必要があります。B.抽象化は詳細に依存すべきではありません。詳細は抽象化に依存する必要があります。
ボブおじさんの原則から続けて、OCPは次のように述べていることがわかります。
クラスの動作を変更せずに拡張できるはずです。
これを達成するための1つの例は、採用することであるStrategyパターンContext
クラスがされた変更のため閉鎖(つまり、あなたはそれがすべてで内部コードです変更することはできません)もある拡張のためのオープン、それは依存関係(すなわち戦略クラス)を共同でいてを。
より一般的な意味では、モジュールはその拡張ポイントを介して拡張可能に構築されます。
いいえ、そうでもありません。
どちらも抽象化について議論していますが、概念的には異なります。両方の原則は、異なるコンテキスト、1つの特定のモジュールでのOCP、およびいくつかのモジュールでのDIPに注目しています。Gang of Fourのほとんどのデザインパターンと同じように両方を同時に実現できますが、それでもパスから離れることができます。
上記のDIPの例では、ボタンとキッチンランプでは、キッチンランプはいずれも拡張できません(現在のところ、その必要性を説明する要件もありません)。デザインはOCPを壊していますが、DIPに従います。
逆の(そして不自然な)例は、キッチンランプが拡張可能であることです(拡張ポイントはのようなものですLampShade
)が、ボタンはまだランプに依存しています。それは破壊DIPが、OCPを次の。
これは実際には、運用コードで頻繁に発生するものであり、その一部は原則に違反する可能性があります。大規模なソフトウェアシステム(つまり、上記の例よりも大きいもの)では、コードをシンプルに保つ必要があるため、一方の原則を破り、通常はもう一方の原則を破ることがあります。私の考えでは、これは単一の責任原則(SRP)に関連したコンテキストにあるため、小型で自己完結型のモジュールには問題ありません。
一部のモジュールが複雑になると、おそらくすべての原則を念頭に置いてそれを調べ、よく知られているパターンに再設計またはリファクタリングする必要があります。