Part3では,もはやオブジェクト指向開発では欠かせない存在となったソフトウエア・パターンについて解説しましょう。デザインパターンに代表される様々なソフトウエア・パターンを活用して,熟練者の経験を盗み,オブジェクト指向開発を円滑に進める術を習得してください。

ソフトウエア・パターンの全貌

 皆さんは誰かが書いたプログラムを眺めていて,どこかで見たようなソフトウエア設計やコードに出くわしたことがありませんか?

 「このクラスの役割はどこかで見たことあるなあ」とか「このコードは何度も自分で書いたことがあるぞ」といった感覚です。そのような既視感は,そのコードを書いた人が,皆さんと似たような状況で,繰り返し発生する問題を抱えて,似たような設計/実装を行ったからかもしれません。

 ソフトウエア・パターン*1は,このような繰り返されるソフトウエア設計を集めたものです。それも単に集めたのではなく,様々なソフトウエア開発事例のうち,熟練者による類似の成功事例を集めて共通部分を抽象化し,名前を与えた指針です。名前を与えることで,「こうしました」という事例は「こうしましょう」という指針となり,他人に伝えられるようになります。

 ただし,いくら成功事例でも,万人にとって有効とは限りません。また,成功事例の背後には,扱う指針を得るに至った理由(自然法則,社会的制約,業務上の規則など)が潜んでいます。

 そこでソフトウエア・パターンは,扱う状況,問題,解決策をわかりやすく示すために,こういうときに(状況),こうしたかったら(問題),こうしましょう(解決),こうなります(結果),なぜならば(理由)という五つの部分に分けて構成されるようになりました(表1)。

表1●ソフトウエア・パターンの記述形式
表1●ソフトウエア・パターンの記述形式

ソフトウエア・パターンの三つの効果

 ソフトウエアに対する要求は主に「機能要求」と「非機能要求」の2種類に分けられます。

 “こういう機能が欲しい”という機能要求は,ソフトウエア開発の初心者でも整理することができるでしょう。しかし,非機能要求をまとめるには,ある程度の経験が必要です。非機能要求とは,変更への強さ(予測可能な仕様変更に対応するソフトウエア変更の小ささ),テストのしやすさ,わかりやすさといった要求を指すからです。

 熟練者は,機能要求を満たしながら同時に,トレードオフの関係にある様々な非機能要求をきれいに満たす“優れた”ソフトウエアを作成します。そのような優れたソフトウエアを生み出した熟練者の成功事例を集めて抽象化し,名前を与えたものがパターンです。

 パターンを上手に活用すると

(1)思考過程と成果を再利用できる
(2)意思疎通を促進できる
(3)優れたソフトウエアの解読を促進できる

という三つの効果が得られます。

 (1)は直感的に理解できますね。パターンを用いれば,熟練者の思考過程と成果を再利用して,新たな開発活動を成功に導くことができます。何かの問題に直面したとき,同じような問題に対応した解決策を用いたほうが成功の確率が高いと言えるからです。しかし見方を変えれば,同じような状況なら,同じような過ちを繰り返し犯す可能性も高くなります。そのような失敗事例の共通部分を取り出して回避策を加えた指針を,アンチ・パターンと呼びます。

 (2)は複数人で開発するときに得られるメリットです。 様々なパターンの名前をソフトウエア開発における語いとして知っておけば,複数の開発者と仕事をするときに,意思疎通をスムーズに行うことができます。例えばプログラマなら「クイックソート」と聞けば,「ああ,あれね」と(たとえプログラミング言語がなんであれ)ロジックを理解できます。このような典型的なアルゴリズムと同様に,状況や解決策などをいちいち説明するよりも,パターン名を一言伝えたほうが効率が良いというわけです。

 (3)は,様々なオープンソースのソフトウエアが流通する現代のソフトウエア開発では特に重要です。 優れたソフトウエアには多くの場合,既知のパターンを適用した結果が含まれているからです。他人の成果をライブラリとして再利用したり解読したりする際に,適用されているパターンを知っていれば,他人の思考過程を容易に推測できます。さらに,そのような推測を通じて,根底にあるソフトウエア開発技法(例えばオブジェクト指向設計の基本的な考え方)への理解が深まります。

パターンといってもたくさんある

 同一の問題領域において,状況や問題といった特徴によって整理された互いに関連するパターンの集合を「パターン・カタログ」と呼びます。パターンは状況や重視する理由によって有効であるかどうかが異なるため,様々なパターンの違いを見比べられると都合が良いからです。

 一方,カタログを発展させて,同一の文脈(ストーリー)上で適用する順序を明示したパターンの順序集合を「パターン・ランゲージ」と呼びます。例えば,Webアプリケーション開発というストーリー上で,アーキテクチャの設計にMVCパターン*2を使用し,続いてモデルとビューの間の依存関係の設計にはObserverパターン*3を使用するという順序集合は,二つのパターンを語いとしたパターン・ランゲージ(言語)を形成します。

 今日のソフトウエア開発では,開発作業全体を機械的に単純な複数の工程へ分割しています。これを一般的なオブジェクト指向開発プロセスとして,ソフトウエア・パターンがそのどの部分に対応するのかを表したのが図1です。ここではプロセス全体を,分析(ドメイン分析,要求分析,システム分析),アーキテクチャ設計,プログラム/クラス設計,実装,テスト,保守/改訂の六つの工程に分割しています。

図1●オブジェクト指向開発のプロセスとそれに対応するソフトウエア・パターン
図1●オブジェクト指向開発のプロセスとそれに対応するソフトウエア・パターン
[画像のクリックで拡大表示]

 図1を見るとわかるように,各工程について成功事例をまとめたパターンが記述され,カタログとして利用できるようになっています。例えば,分析工程ではアナリシス・パターン,アーキテクチャ設計工程ではアーキテクチャ・パターン,プログラム/クラス設計工程では(本誌の皆さんにはおなじみの)デザインパターンといったカタログが,書籍やWeb上で公開されています。

 さらに,開発工程におけるパターン(プロダクト・パターンと呼びます)に加えて,最近では開発プロジェクトの管理に関するパターンも登場してきました。これを,マネジメント・パターン(組織パターンやプロセス・パターン)と呼びます。

 また,パターンは,特定の問題領域や実装技術/処理内容に特化したもの(特化型)と,汎用的なもの(汎用型)の2種に分けることができます。この二つの分類にしたがってオブジェクト指向開発における主なパターンをまとめてみると,表2のようになります。皆さんが想像している以上にたくさんのパターンがあるのではないでしょうか。しかし,すべてをマスターする必要はありません。

表2●ソフトウエア・パターンの種類。POSAとは書籍「ソフトウェアアーキテクチャ ソフトウェア開発のためのパターン体系」(近代科学社発行),PofEAAとは書籍「Patterns of Enterprise Application Architecture」(邦訳「エンタープライズ アプリケーションアーキテクチャパターン」)のこと
表2●ソフトウエア・パターンの種類。POSAとは書籍「ソフトウェアアーキテクチャ ソフトウェア開発のためのパターン体系」(近代科学社発行),PofEAAとは書籍「Patterns of Enterprise Application Architecture」(邦訳「エンタープライズ アプリケーションアーキテクチャパターン」)のこと
[画像のクリックで拡大表示]

 以降ではこれらの中から,分析パターン,アーキテクチャ・パターン,デザインパターン,イディオムの四つを取り上げて解説しましょう(「テスト・パターン」「保守/改訂におけるパターン」「マネジメント・パターン」の3種類についてはカコミ記事「その他のソフトウエア・パターン」を参照)。

その他のソフトウエア・パターン

 テスト・パターンは,テスト工程でテスト方法/計画の優れた指針を表すものです。Javaなどのオブジェクト指向プログラミング言語の特性(例えば動的束縛)を考慮して,テストの繰り返し実行/自動化,精度の高いテストを実現するための指針を与えます。書籍「Testing Object-Oriented Systems Models Patterns, and Tools」(Addison-Wesley発行)で紹介しているオブジェクト指向テストパターン,書籍「Patterns in Java, Volume 2」(John Wiley&Sons発行)のJavaテスティング・パターンなどが挙げられます。特に前者は実践的なテスト・パターンをほぼ網羅しているので,オブジェクト指向テストを極めたい方は必読でしょう。

 保守/改訂におけるパターンとして有名なのは,書籍「リファクタリング:プログラムの体質改善テクニック」(ピアソン・エデュケーション発行)や「Refactoring to Patterns」(Addison-Wesley発行)で紹介されているリファクタリングでしょう。「Object-Oriented Reengineering Patterns」(Morgan Kaufmann発行)のオブジェクト指向リエンジニアリング・パターンなども利用できます。

 リファクタリングとは,プログラムの外部への振る舞いを保ったままで,読みやすさやテストのしやすさの向上のために内部構造を変更する改訂手順を表すパターンです。例えば,重複するプログラム・コードを一つのメソッドにまとめる「Extract Method(メソッドの抽出)」などがあります。ひょっとしたら「リファクタリングはパターンとは違うのでは?」と思われる方がいるかもしれませんが,筆者はリファクタリングも一種のソフトウエア・パターンと解釈して構わないと考えています。

 開発プロジェクトの管理にかかわるマネジメント・パターンには,組織構造(チーム編成)最適化の指針を表す組織パターンと,生産性の高い開発プロセスに共通する優れたプロセスを表すプロセス・パターンの2種類があります。両者は密接に関係しているため,しばしば一つにまとめて公開されます。例えば,書籍「プログラムデザインのためのパターン言語―Pattern Languages of Program Design選集」(ソフトバンクパブリッシング発行)では,「開発工程の生成的パターン言語」と題するパターン・ランゲージにまとめられています。