ZF2(ZendFramework2)を勉強する際、DI(DependencyInjection)とServiceLocatorを混同してしまっていたため、整理するために2つについてまとめてみました。
DIとServiceLocatorの共通点
DIとServiceLocatorは両方とも密結合なメソッドの結合度を緩和するために用いられるデザインパターンです。
密結合とは
この記事内において密結合とはメソッド同士の依存度が高い状態を指します。具体的には、インスタンスの生成から利用まで
直接他のクラスに依存している状態です。密結合にはデメリットがあり、依存先のクラスに変更があった際に影響が大きく、依存元クラスの再利用性は低くなってしまいます。
DIとは
**呼び出し元に使用する
依存オブジェクトを用意してもらい、
それを注入してもらうことです。**クラス間で直接インスタンスを生成するのではなく、メソッドの呼び出し元で依存先のインスタンスを生成し、メソッドにそのインスタンスを引き渡します。DIのメリットとしては依存度を緩和することができ、またテストしやすいメソッドを生成できるといったことが挙げられます。
ServiceLocatorとは
**オブジェクトのインスタンス
生成方法を管理するデザインパターンです。**ServiceLocatorを呼び出して依存先のインスタンスを取得する際、ServiceLocatorはあらかじめ登録された生成方法でインスタンスを生成し、これを呼び出し元へ返却します。これにより、クラス間の直接的な依存関係を緩和することができます。(ZF2のMVCにおいてはServiceManagerがServiceLocatorの役割をしています。)
ServiceLocatorにはデメリットもあります。ServiceLocatorを使うことで確かにクラス間の直接的な依存関係は緩和されるのですが、代わりにServiceLocatorへの依存度が高くなってしまいます。もしServiceLocatorに依存したメソッドを再利用しようとした時、移植先で同様のServiceLocatorを用意しなくてはならなくなるといった事態が発生してしまいます。
まとめ
DIとServiceLocatorは両方とも密結合の結合度を緩和するために用いられます。密結合へのアプローチとしてはテストのしやすさの面で個人的にはDIを推していますが、こちらは適材適所で使えればいいと思います。
突っ込みたくなるところがありましたら是非ともご指摘お願いします。