残りは「ベースパターン」です。構成のうえでは最後になっているので、まるでオマケのようですが、実は場合ごとに分かれたこれまでのパターン群よりも汎用的で、より基礎になってくるのがこのペースパターン群です。
Separated Interface は保守性と拡張性がともに高いアーキテクチャ設計において、あらゆることの基本になる大事なパターンです。原則とさえ言えるかもしれません。
段階的に理解するために、まずは Registry パターンがフォーカスしている問題の方を、先に説明しておきましょう。
いくらオブジェクト指向をサポートするプログラミング言語を使っていても、大規模で複雑なオブジェクト構造を辿って目的のオブジェクトを取り出す必要がある作りになっていると、プログラミングはどんどん難しくなっていきます。よく使われるオブジェクトや設定値、状態変数にすぐにアクセスできる経路があると便利です。Registry は、どこからでも即座にアクセスでき、すぐに目的のオブジェクトが見つけてくれるサービスです。
Registry は便利ですが、それは本質的にグローバル変数です。グローバル変数は、いつ誰が変更するかわからない怖いものです。実行時に変更が起きないものなら安心かというと、まだそうとも言えません。大きなものに依存して、取り出したものを使い放題だと、それに依存しすぎるリスクを抱えています。依存関係が明示的でなく、コンパクトに閉じていない作りは、Registry 利用者の単体テストを困難にします。単体テストが困難だということは、さまざまな変更影響を受ける、安定度の低い部分になるということです。
システムサービスについての Registry は、よく知られた言葉で言うと、つまり「サービスロケーター」のことです。
Separated Interface は、実装クラスを持つパッケージより安定度のはるかに高いパッケージにそのインターフェースを設け、利用者はそのインターフェースだけに依存するようにするパターンです。こうしておくと、実装の有無にかかわらず、オブジェクトを利用するプログラムを書くことができます。実装もまた、この安定したインターフェースに依存するかたちになります。
より良く設計されたオブジェクト指向プログラムは、オブジェクトを取り出さなくても問題を解決できるように作られます。問題解決に必要な関連オブジェクトまで、委譲のバトンリレーをするのです。インターフェースにさえ依存していれば、後は Tell, Dont Ask スタイルだけで目的を果たせるのが理想です。
インターフェースの実装は、依存性注入の考え方で割り当てるのが適当です。Domain Model が Repository インターフェースの持つ、呼ぶだけでエンティティを得られるメソッドを使う様子 (実装は問わない) は、Separated Interface を物語るよい例です。
PoEAA のパターンが実践されていた当時は、まだサービスロケーターへの批判も、依存性注入という言葉もありませんでした。後にそれらを明文化したのは、PoEAA の著者、マーチン・ファウラーその人です。
実装と分離されたインターフェースという前提があれば、Plugin パターンによる拡張性の確保も可能です。リリース後に追加機能が求められても、インターフェースを満たす実装を後で足しさえすれば、本体システムの変更なしに拡張できるのが Plugin です。
Plugin は SOLID の開放閉鎖原則 (OCP) にうまくマッチします。拡張できる箇所が多い場合は、GoF デザインパターンの Observer パターンを有効活用できます。
システムがまだ完成していないときにも、分離されたインターフェースは役に立ちます。分業で開発している別のサービスがまだ実装されていなくても、そのインターフェースさえ決まっていれば、Service Stub で代用して、自分の作業分をテストすることができます。Service Stub はテスト用にだけ使える、中身のないダミーサービスを仮に作ってテストを進めるパターンです。
現在では、多くの単体テストツールに、スタブ(単なるダミー)やモック(正しく呼び出されたかを検証できるダミー)を作る機能を持っています。サービスがリモートコールだった場合は、Swagger によるスタブサーバーや Docker が利用できます。
こうしたアーキテクチャ設計の感覚を、概要説明だけで得られる人はまれです。前提となる感覚を持っておくのに、拙著「ちょうぜつソフトウェア設計入門」はたいへんオススメの一冊となっております。
宣伝っぽいですが、もしこれが他人の本でも、全く同じ内容だったら確定でオススメしています。なぜなら、イチから適切な洋書の約本を何冊も選び、買い揃え、読破するのは、費用面でも労力面でも、大変すぎるからです。