「依存性逆転の原則」の版間の差分

削除された内容 追加された内容
m Wikipedia:表記ガイド に従い、文末のピリオドを「。」に統一
m Wikipedia:表記ガイドに従い、本文中の敬体 (です・ます) を常体 (である) に修正
82行目:
 
=== 家系モジュール ===
ある家系システムでは人々の間の関係を第一レベル関係のグラフとして表現するかもしれませんない(父親/息子, 父親/娘, 母親/息子, 母親/娘, 夫/妻, 妻/夫...)。これは非常に効率的である(そして拡張も可能: 元夫/元妻, 法的保護者...)。
 
しかし、上位レベルモジュールでは家系をブラウズするためのより簡単な方法が必要になるかもしれませんない: 人には、子供、父親、母親、兄弟と姉妹(異母兄弟を含む含まないも合わせて)、祖父、祖母、伯父、伯母、従兄弟... などがいるかもしれませんない
 
家系モジュールの使用法に応じて、共通の関係を明確で直接的な属性として(グラフを隠して)表示することは上位レベルモジュールと家系モジュールの間の結合を遥かに軽くでき、モジュールの使用になんの影響も与えることなく内部表現を完全に変更することを可能にしま。またそれによって、家系モジュールに対し兄弟、姉妹(異母兄弟であるかどうか)の正確な定義を埋め込む事が可能になります... またそれは[[単一責務の法則]]を強制することにも繋がります
 
最終的に、もし最初の一般化された拡張可能なグラフアプローチが一番拡張可能に思えるのであれば、家系モジュールの利用は更に特殊化及び単純化された関係の実装がアプリケーションに対して十分であることを示しているかもしれませんないし、より効率的なシステムを作成する手助けになるかもしれませんない
 
この例でのモジュール間の相互関係の抽象化は下位レベルモジュールのインターフェースの単純化だけでなく、より単純化された実装につながるかもしれませんない
 
=== リモートファイルサーバークライアント ===
リモートファイルサーバー(FTP, cloud strage ...)に対するクライアントを実装しなければならないケースを想像してくださいせよ。あなたはそのクライアントに抽象インターフェースを持たせる事を考えるでしょだろう。
 
# Connection/Disconnection (a connection persistence layer may be needed)
102行目:
# File history management ...
 
ローカルファイル、リモートファイルの両方が同じ抽象インターフェースを提供する場合、ローカルファイルと完全に実装された依存性逆転パターンを使用するどんな上位レベルモジュールもローカルとリモートの区別なくファイルにアクセスすることが可能になります
 
ローカルディスクは一般的にフォルダーを使用します、リモートストレージもフォルダーを使用するかもしれませんない(もしくはタグのみ、フォルダーとタグの両方など)。 もし可能であればそれらを統一する方法を決めておく必要があります
 
リモートファイルに対しては、作成と置換のみを行う必要があるかもしれませんない(ローカルファイルに比べてリモートファイルのランダムアップデートはあまりに遅く、実装も難しくなる可能性があるので、リモートファイルの更新は意味をなさない)。リモートファイルに対して部分的な読み込みと書き込みを行う必要があるかもしれませんない(少なくともリモートファイルモジュールの内部では通信中断後のダウンロードとアップロードの再開をできるようにする必要がある)。しかし、ローカルキャッシュを利用している場合を除き、ランダムリードは適しませんさない
 
ファイル検索は "pluggable" であるかもしれません:ない ファイル検索は OS、特にタグや全文検索に依存し、異なるシステムでも実装する事ができます。(OS に組み込まれていたり、別に入手する事も可能) 並行実行される置換または削除の検出は、他の抽象インタフェースに影響を与える可能性があります
 
概念的なそれぞれのインターフェースに対してリモートファイルサーバーを設計するときは、上位レベルモジュールが要求するサービスのレベル (必ずしも全てが要求されるわけではない)を良く考える必要があります。そして、どのようにリモートファイルサーバーの機能を実装するかだけでなく、アプリケーション内に既に存在するファイルサービス(ローカルファイル、既にあるクラウドクライアントなど)と新たしいリモートファイルサーバークライアントの間で整合を取るかについても同様に考える必要があります
 
必要なインターフェースの設計が完了したら、リモートファイルサーバークライアントはこれらのインターフェースを実装すべきである
 
また、既に存在するローカルファイルに対しての機能 (例えばファイル更新など)について制限を加えたい場合、同じ抽象インタフェースを提供するローカルまたは他の既存のリモートファイルアクセスモジュール用のアダプタを記述する必要があるかもしれませんない。また、コンピュータ上に構成されている利用可能なファイル互換システムを検索するために独自のファイルアクセス列挙子を記述しておく必要もあります
 
これらが完了すると、アプリケーションはドキュメントをローカルとリモートに透過的に保存する事が可能になります。さらに簡単に言うと、新しいファイルアクセスインターフェースを使用している上位レベルモジュールは使用の際にローカルとリモートファイルにアクセルするシナリオを意識する必要がなくなり、再利用性が向上しま
 
注意: 多くの OS がこの手の機能を実装し始めているため、新規実装のクライアントをこの既に存在している抽象モデルへ適用するのは控えた方が良いかもしれませんない
 
この例では、モジュールを抽象インターフェースのセットとして考え、このインターフェースのセットに他のモジュールを適合させることで、様々なファイルストレージシステムに対し、共通のインターフェースを提供する事ができます
 
=== Model View Controller ===
126行目:
[[ファイル:DIP_concrete_example.png|中央|Example of DIP]]
 
UI とアプリケーションレイヤーパッケージは主に具象クラスを含んでいて、コントローラーは抽象/インターフェース型を含んでいます。また UI は ICustomerHandler のインスタンスを保持し、全てのパッケージは物理的に分離されていて。アプリケーションレイヤーには Page クラスが使用する具象クラスの実装が存在しています。これらのインターフェースのインスタンスは (コントローラーと同じパッケージに存在するかもしれない)Factory によって動的に生成されます。具象タイプである Page と CustomerHandler はお互いに依存してはらなず、両方とも ICustomerHandler に依存しま
 
これらの直接的な効果は、UI が直接 ApplicatonLayer や、ICustomerHandler を実装したどの具象パッケージも参照する必要がない事である。コンクリートクラスはリフレクションを使用してロードされます。またどの時点であっても、具象実装は UI クラスに変更を及ぼさずに他の具象実装に差し替える事ができます。他の興味深い可能性は Page クラスが ICustomerHander のメソッドに引数として渡す事ができるインターフェース IPageViewer を実装していると言う事で、これによってt具象実装は具象的な依存なしに UI と通信する事ができます。何故なら両者はインターフェースでリンクされているからである
 
== 関連するパターン ==
依存性逆転の原則の適用はアダプターパターンの一例と見ることもできます。例えば、上位レベルクラスが自身が依存する抽象への固有のアダプターインターフェースを定義するような場合がそれに当たります。アダプティーの実装はまたアダプターインターフェスに依存しますが(もちろん、このインターフェースを実装しているので)独自の下位レベルモジュール内のコードを用いて実装を行うこともできます。上位レベルモジュールは、アダプティーとその下位レベルモジュールによって実装されたインターフェースへのポリモーフィックな関数を呼び出すことによってアダプターインターフェースを介して間接的に下位レベルモジュールを利用するため、上位レベルモジュールが下位レベルモジュールに依存するといったことはありませんない
 
Plugin, [[Service Locator パターン|Service Locator]], or [[依存性の注入|Dependency Injection]] などの様々なパターンは上位レベルコンポーネントに対する選択された下位レベルコンポーネントの "run-time provisioning" を容易にする目的で導入されます
 
== History ==