AdapterパターンとFactory Methodパターンの事例
デザインパターンでフレームワークをラップする
前回はObserverパターンの事例を紹介しました。Observerパターンは、オブジェクトの状態の変化に応じてほかのオブジェクトに何らかの通知を行うパターンです。また、何らかの通知によってオブジェクト同士が強く依存してしまうことを避けたい場合や、通知するオブジェクトを1つに特定したくない場合に有効です。
今回はcommons logging 1.1.1(http://commons.apache.org/logging/)を事例に、GoFのデザインパターンであるAdapterパターンとFactory Methodパターンを取り上げます。
Adapterパターン(図1-1)は構造に分類されるパターンです。Adapterとは「適合させるもの」という意味です。互換性のないさまざまなインターフェースを持つクラス(Adaptee役)に修正を加えることなく、利用者が望むインターフェース(Target役)で利用できるようにAdapter役が変換します。Adaptee役を包み込むような形になることからラッパー(Wrapper)と呼ぶこともあります。Adapterパターンは、「継承」と「委譲」の2種類の実現方法がありますが、今回は「委譲」で説明します。
Factory Methodパターン(図1-2)は生成に分類されるパターンです。Factoryとは「工場」という意味ですので、何かを作ったり加工したりすることを連想するかもしれませんが、このパターンはCreator役のクラスのcreateメソッド(ファクトリーメソッド)からProduct役のインスタンスを生成することを定めます。ただし、具体的なインスタンス生成はCreator役のサブクラスであるConcreteCreator役のクラスに委ねます。
このパターンはインスタンスを生成するための仕組みとインスタンスを決定するための仕組みを分けて考えることができます。ちなみにCreator役のクラスのファクトリーメソッドは、第1回(http://thinkit.co.jp/article/925/1/)で紹介したTemplate Methodパターンを応用することが多いです。
commons loggingは、AdapterパターンとFactory Methodパターンによってlog4jのAPIやJDK 1.4以降のLogging API(以降、JDK Logging APIと略す)などの異なるロギングフレームワークを簡単に切り替えて使うことができる、汎用的なロギングAPIです。
今回はcommons loggingの中で、どのようにパターンが適用されているのか、どのような効果があるのかを分析して理解を深めていきましょう。
ログ出力を行うソースコードはロギングフレームワークに依存する
ロギングフレームワークの中ではThe Apache Software Foundationのlog4jが有名ですが、ほかにもいくつか存在しています。ロギングフレームワークはファイルやネットワークなどに対してログを出力する仕組みを提供してくれます。利用するフレームワークによって異なりますが、出力先や出力するログレベルを設定ファイルで細かく操作することができます。
システム開発では、運用やデバッグの目的でログ出力を行う必要が出てきます。ログ出力を行うソースコードはロギングフレームワークに依存します。何らかの理由でlog4jからJDK Logging APIに切り替える場合、ソースコードに手を加える必要があります。
また、プレゼンテーションレイヤーや永続化レイヤーの汎用的なフレームワークを開発する場合では、利用するロギングフレームワークをあらかじめ決めたくはありません。なぜなら、そのフレームワークの利用者がロギングフレームワークを選択できなくなるからです。
もっとも良いのは、ロギングフレームワークを自由に変更できるようにすることです。そのためにはロギングフレームワークに依存しないログ出力のプログラミングを行う必要があります。