レベルエンター山本大のブログ

面白いプログラミング教育を若い人たちに

BLOCKVROCKリファレンス目次はこちら

DIxAOP時代のデザインパターンの検討

DIxAOP時代のDesign Patternについて記事のためにアイデアを絞っている。

その中で浮かんだパターンの1つ
「Implicit Interface Injection」パターンというのをご紹介。

対象とする問題

DIコンテナを使う場合「インターフェイスベースのプログラミングを行う」ことは1つの原則のようになっている。
インターフェイスベースプログラミングによって疎結合なモデルになる。これにより、再利用性と拡張性が向上する。
しかし、部品の再利用が主目的ではない企業システムの開発では、インターフェイスベースにすることのメリットよりも、開発の効率低下や、コードの追跡のしやすさの面でのデメリットの方が大きいと感じることが多い。

Implicit Interface Injection(暗黙のインターフェイスへの注入)パターンによる解決策

「Implicit Interface Injection」パターンとは、DIがインジェクトする対象として主に具象オブジェクトを使い、インターフェイスをあまり使わずにアプリケーションを構築することだ。
リファクタリングすることで、必要なときに必要な分だけインターフェイスを抽出する。

暗黙のインターフェイスという考え方

暗黙のインターフェイスという考え方は、マーティンファウラー氏の考え方を借りている。
それは「オブジェクトは全て暗黙的なインターフェイスを実装している」という考え方だ。

■暗黙的インタフェースの実装
http://capsctrl.que.jp/kdmsnr/wiki/bliki/?ImplicitInterfaceImplementation

JavaC#も純粋なインタフェース型というものを用意している。純粋なインタフェースはinterface Mailableのように宣言し、 Javaの場合だとclass Customer implements Mailableのようにして実装する。ひとつのクラスは複数のインタフェースを実装することができる。

このモデルが考慮していないのは、クラスには必ず暗黙的なインタフェース(implicit interface)があるという点である。 Customerの暗黙的なインタフェースは、Customerで宣言されたすべてのpublicなメンバである(この暗黙的なインタフェースは、今まで私が見てきたどのOO言語にも存在する)。

つまり、このパターンは
「初めのうちは暗黙的なインターフェイスを使って実装し、後々必要に応じて純粋なインターフェイスを抽出する」
のだと言うことができる。


例えば、DIのサンプルとしてよく使われる次のようなモデルでは、

  • Service+ServiceImpl
  • Dependency+DependencyImpl

のようにインターフェイスと具象クラスのペアを用意する。

Implicit Interface Injectionパターンでは「Service具象クラス」と「Dependency具象クラス」のみでアプリケーションを構成する。

つまり、この具象オブジェクトにはすでに暗黙のインターフェイスが定義されており、この暗黙のインターフェイス(つまり具象オブジェクト)を使ったとしてもDIのすべてのメリットは享受できるというものだ。


DIコンテナを使っていれば、具象クラスからインターフェイスを抽出するというリファクタリングは簡単だ。
ServiceクラスとDependencyクラスをそれぞれインターフェイスに変換し、その実装をServiceImplおよびDependencyImplクラスに移すだけでよい。
要求元(クライアント)コードにも影響を与えずにリファクタリングできる。


パターンと呼べるかどうかがポイントか。。。
また、考え方が回りくどいところも。。。