結局、参照しないと呼べないのではないか?
図1を見てみると、I/Fにより各モジュールは分割できているように見えるが、結局、ControllerがServiceを読んでいることに変わりはなく。参照が存在するのだ。
しかしながら、図2のようにエントリーポイントという上位世界を導入し、さらにDIを行えば、問題なく分離できるのである。
エントリーポイントとは、Javaでいうmainメソッド、WSGIでいうところのルーティングファイルまたはコントローラーを指す。
エントリーポイントはOSからExecutionを行うという世界と同じ領域であり、モジュール参照構造の外側に位置するものである。
これにより、Controllerは実行時までServiceの参照を保持しないのである。
DI(注入)の要点が知りたい方は「なぜ依存を注入するのか DIの原理・原則とパターン」をご購読ください。
でも、結局ControllerからServiceを呼んでるじゃないか
これは目的観の違いである。まったくその通りであるが、それはコードリーディングの観点であり、アーキテクトの観点ではない。
SOLIDでいうところの、単一責任の原則(テスト容易性)、オープン・クローズドの原則(修正容易性)の達成の観点からいうと合格なのである。
エントリーポイント外、つまりモジュール単位では完全に独立しており、旧モジュールを保持したまま新モジュールを作成でき、各モジュールは単独でテスト可能である。
ただし、用意周到なインターフェース設計が必要であることに違いはなく、難易度を感じるというのは当然だが、一言「ただの置換じゃない。リファクタリングすればいいじゃない」。
デグレードが怖い?「単体テストがあれば怖くないじゃない」。