Template Methodパターンの事例
JUnitのTestCaseクラスに関する補足
今回の事例の中心は、TestCaseクラスでした。Template Methodパターンに関係する部分に焦点を当てて説明しました。そのため、関係のない部分の説明は割愛しています。
実際は図3-1を見てわかるように、もう少し複雑な構成で実装されています。
TestCaseクラスのテンプレートメソッドはrunBareメソッドです。図3-2を見てわかるようにrunBareメソッドは、setUpメソッド→runTestメソッド→tearDownメソッドの順に実行します。runTestメソッドで外部から指定されたテストメソッド(testCase1)を間接的に実行しているのがよくわかります。この工夫によって、複数のテストケースが実装できるようになりました。
今回、説明した実現方法では、テストを実施する際に1つのテストケースに1つのインスタンスを生成する必要がありました。これは、各単体テストはほかのすべての単体テストから切り離して実行したいというJUnitのコンセプトなのです。ほかの単体テストの結果や状態に左右されないための配慮です。しかし、テストケースが増えるにつれて、最初に挙げた「テスト実施の問題」が次第に大きくなります。
JUnitでは、その問題を解決するための手段としてTestSuiteクラスが用意されています。TestSuiteクラスはTestCaseクラスに実装されている"test"で始まるメソッドを内部検索します。そして、発見したメソッドを実行するためのTestCaseクラスのインスタンスを自動的に生成して保持します。
TestSuiteクラスは、Testインターフェースを用いて保持するすべてのTestCaseクラスをまとめて実行することができます。
public class xxxTest extends TestCase {
public void testCase1() { ... };
public void testCase2() { ... };
public void testCase3() { ... };
}
TestSuite suite = new TestSuite();
suite.addTest(xxxTest.class);
// testCase1~testCase3のテストケースをまとめて実行
suite.run(new TestResult());
このように実際のフレームワークは、それぞれの責務を持ったクラス同士がコラボレーションし、フレームワークの目的を果たしているのです。
Template Methodパターンはオブジェクト指向設計の基本中の基本
今回、紹介したTemplate Methodパターンはテンプレートという名前から想像できるように何かの型にはめるという意味がとても強いパターンです。プログラミングをしていると「処理はほとんど同じなんだけど、一部異なる」という場面によく遭遇します。
そんなときは、慌てないで実装をいったん止めてください。そして、処理の共通部分と固有部分をよく見極めます。そうすることで抽象クラスが次第に見えてくるハズです。そこでTemplate Methodパターンを適用するのです。
また、今回の事例のように、視点を変えて考えてみることはTemplate Methodパターンに限らず、すべてのデザインパターンに共通して言えることであり、非常に重要です。視点を変えることで、デザインパターンの適用の幅を広げることができるのです。
このほかにもTemplate Methodパターンは、そのパターンの性質上、アプリケーション開発のためのフレームワークの中でよく使われています。
次回は、引き続きJUnitを事例にObserverパターンを紹介します。それでは、次回をお楽しみに!
【参考文献】
Erich Gamma, Rechard Helm, Ralph Jonson, John Vlissides『オブジェクト指向における再利用のためのデザインパターン』ソフトバンククリエイティブ(発行年:1999)
結城 浩『Java言語で学ぶデザインパターン入門』ソフトバンクパブリッシング(発行年:2001)
Vincent Massol,Ted Husted『JUnitインアクション』ソフトバンクパブリッシング(発行年:2004)
「JUnit.org」(http://www.junit.org/) (アクセス:2009/04)