ディスパッチテーブルというデザインパターン

ディスパッチテーブルというデザインパターンを紹介します。 https://qiita.com/hirokidaichi/items/c9a76191216f3cc6c4b2#%E3%83%87%E3%82%A3%E3%82%B9%E3%83%91%E3%83%83%E3%83%81%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB

これを覚えれば、if文やswitch文を書かずに条件分岐を表現できるのでコードの見通しを良くすることができます。

現場で役立つシステム設計の原則という本の2章で紹介されているMap(連想配列)やenum(列挙型)を使った例がまさにこれに該当します。

これはポリモーフィズムととても相性が良く、具体的なデザパタではPolicy/SpecificatioinやStrategy/Stateパターンとの相性が良いです。

ある条件を引数に与えて、その条件に沿ったインスタンスを取得するという性質は(広義の)Factoryパターンに近いです。

Factoryパターンを使えば『ある条件に該当するクラスのインスタンスを得る』という部分は同じように実現できます。

しかし、Springを使ったアプリケーションの場合そうもいきません。

AOPで提供される様々な便利機能を利用するためにどうしてもDIコンテナからインスタンスを取得する必要性があるためです。

Factoryメソッド内で新規にインスタンスをnewしてしまうとDIコンテナの管理対象外のためAOPが動作しないので@Transactionalなどの便利なアノテーションが使えなくなってしまいます。

Factoryパターンを使う場合、FactoryメソッドがDIコンテナから取得したインスタンスを返せればよいのですが、一般的にはfactoryメソッドはstaticであることが多く、staticな場合だと特別な工夫をしないとDIコンテナから取得したインスタンスを返させることはできませんし、出来たとしても直感に反します。

IDDD本で紹介されているDomainRegistryパターンを使えばstaticメソッド経由ではDIコンテナ内のBeanを取得できないという問題も克服できますが、 世の中に広く浸透しているデザパタではないところが少し利用を躊躇わせます。

単純にあるクラスのインスタンスのバリエーションを全てinjectionしてしまうとメソッド内でif文かswitch文でどのインスタンスを使うのか選択する必要がありますが、ディスパッチテーブルを使えば、それをせずに済みます。

ちなみにこれもデザインパターンの一種だと認識していますが、名前が有名ではないようでググっても全然サンプルコードが出てきません。 名前がついていても良さそうなもんですけどねぇ。