依存関係逆転の原則
依存関係逆転の原則とは
という原則です。
- 上位のモジュールは下位のモジュールに依存してはならない。どちらのモジュールも「抽象」に依存すべきである
- 「抽象」は実装の詳細に依存してはならない。実装の詳細が「抽象」に依存すべきである
まずはこのクラス図を見てください。
この図ではパッケージAとパッケージBが互いに依存していて二つのパッケージを分離することが出来ません。
1つ目の図のようにパッケージが互いに依存しているときはインターフェースを使うことによって依存関係を一方通行にすることが出来ます。
具体的にはDaoインターフェースをパッケージAに作ってやり、パッケージBでDaoインターフェースを実装してやればよいのです。
2つ目の図ではパッケージBからAへの依存関係残るもののパッケージAからBへの依存関係はなくなっています。
これでパッケージAだけを切り離すことが出来るようになりましたね。
インターフェースを使うことによりAパッケージとBパッケージの依存関係が逆転しました。これが「依存関係逆転の法則」の由来になっています。
では実際にどのように実装すればよいのでしょうか?
はじめに思いつくのは下記のようなコードだと思います。
public class HogeBusiness { public void invoke() { Dao dao = new DaoImple(); dao.findAll(); … …… } }
これではせっかくインターフェースを作ってもnewのところでパッケージBのクラスを参照してしまうのであまり意味がありません。
そこでSpringやSeasar2などのDIコンテナを使って依存性を注入するようにしてやればパッケージBのクラスを参照しなくてすみます。
コードは
public class HogeBusiness { private Dao dao = null; public void setDao(Dao dao) { this.dao = dao; } public void invoke() { dao.findAll(); … …… } }
となりあとはXML定義ファイルに依存関係を書いてやればOKです。
XML定義ファイルの書き方は各DIコンテナによって違うのでここでは割愛します。
DIコンテナについて興味のある方はSpringとかSeasar2で調べてみてください。
インターフェースを使って依存性をなくすことでクラスの再利用性が高まり、それがそのままパッケージの再利用性にもつながります。
DIのメリットもこの原則とセットで考えるとよく理解できるんじゃないかと思います。
それにしてもこの原則コロンブスの卵のような発想ですよね。考えた人は凄い。