Java言語で学ぶデザインパターン入門
結城浩 (ソフトバンクパブリッシング)
傑作(30点) 2011年7月8日 ひっちぃ
オブジェクト指向開発を効率的に行おうとしたときによく現れる設計としてまとめられた「デザインパターン」を、Java言語による実例を示しながら平易に解説した技術本。
2001年に書かれてからロングセラーとなっている本。ようやくデスマーチを抜けてきたばかりの先輩が目を輝かせながらこのシリーズの本を買って読もうとしていたのを見たのが確か2005年ぐらいで、その後この先輩が引っ張っていたプロジェクトは億の赤字を出して辞めてしまったのだが、最近会社の本棚を覗いてみたら見覚えのあるこの本が目に入ったのでようやく自分も読んでみた。
プログラムコードを再利用するための一番代表的な方法は、ライブラリという形である程度汎用性を持たせて共通コードとしてまとめて利用することなのだけど、あくまでも末端処理の集まりに過ぎないので大きな構造を共通化することができなかった。その後、フレームワークといった形で大きな構造を共通化する手法も生まれたが、思ったほど使い勝手が良くなくて、ちょっと標準的な使い方とは違ったことをやろうとすると困難だったり、なんだかんだでたびたび修正が必要になったりすることが多かった。そこで、ガッチリとコードを固定するのはあきらめて、設計のパターンだけ標準化すればいいんじゃないかということで、ギャング・オブ・フォーと呼ばれる四人組が23個のパターンとしてまとめたのが「デザインパターン」なのだそうだ。私はてっきり方法論みたいなものかと思っていたのだけど、はっきりと具体的に23個のパターンが示されているのだ。
そしてもう一つ重要な点は、この手法がオブジェクト指向開発を前提としているということだ。つまり、デザインパターンとは「クラス設計の方法」なのだ。だから、オブジェクト指向ではない言語ではこの手法は使えない。
じゃあ具体的にどういったものがデザインパターンなのか。分かりやすい例としてCompositeパターン(容器と中身の同一視)を挙げる。ファイルシステムは複数のフォルダ(ディレクトリ)とファイルで構成されていて、この二つは別のものだけど名前を持つなどの共通点がある。だから、共通の抽象クラスを作って「名前」や「置かれている場所」なんかの部分を共通化し、ここから継承してそれぞれフォルダとファイルのクラスを作って固有のコードを持たせたほうがメンテナンスしやすくなる。
Visitorパターンは「構造を渡り歩きながら仕事をする」と説明されており、たとえば前述のファイルシステムのようなツリー構造を持ったデータだけでなく、データ構造に依存せずにさまざまな構造を持ったデータに対して網羅的に同じ処理を施すような処理を設計するときに使う。
ちょっとこの説明だと分かりにくいかもしれないので、一番最初に紹介されているIteratorパターンを例にして解説しよう。このパターンは単にデータ型に依存せずに繰り返し処理を行うときの設計パターンだ。つまり、
1. 以下の処理を列挙型データaの各個の要素に対して行え。
1-1. <処理A>
これの1の部分だけをパターンとして抜き出している。オブジェクト指向が流行る前に一般的だった構造化プログラミングだと、あくまで1-1の<処理A>だけが共通化の対象だった。デザインパターンでは、この1にあたる部分を共通化というか標準化しようとしている。列挙型データaは配列だろうとリストだろうと、リストが双方向だろうと単一方向だろうと、中のデータ型がどんなものであろうと関係ない。
とまあデザインパターンの説明のほうに力が入ってしまった。この解説本は、決して易しい内容ではないけれど、たぶん誰が書いてもこれ以上分かりやすく書くのは難しいのではないかと思えるぐらい分かりやすいと思う。特に、Java言語によるコードを具体例としてつけたのは、本書の題にもなっているようにとても重要で決め手となっている。やっぱり実際にコードがあるほうが理解しやすい。
妙に文章が格調高くて独特の雰囲気がある。丁寧な文体なのに、作者から教え込まれるような感覚になる。プロフィール見ると作者はクリスチャンだとあるので、ひょっとしてこういうところからきているんだろうかと邪推してしまう。
システムを設計するときに、ここはこのパターンで設計しよう、みたいな感じで共通言語的に使われると開発がスムーズに行くと最初に書いている。なるほどそのとおりだと思った。ちょっと分野は違うけれど、脚本家の首藤剛志が多人数で映像作品を作るときに「ここは○○○○の△△△△のシーンみたいに」と名作映画の具体的なシーンがみんなの共通言語になっていると書いていたのを思い出した。
一方で私はこの本を読んで、オブジェクト指向の限界のようなものが見えたような気がした。ちょっと無理をさせているように思えるパターンがいくつかあった。
そもそもオブジェクト指向とは、データを操作するためのコードを、データそれ自体に付随させてオブジェクトという一つのものでまとめるという考え方だ。別にオブジェクト一つにまとめなくてもコードは書ける。たとえば先のIteratorパターンの場合、<処理A>を「関数へのポインタ」「コールバック」「デリゲート」みたいな形で渡す共通処理を用意しても実現できる。Iteratorパターンみたいな汎用性のある操作なら、列挙型データの各クラスにIterableみたいな共通処理を用意したほうがいいかもしれないけれど、Visitorパターンみたいな場合はややこしいことをせずにそのまま<処理A>を受け取って処理したほうが早いんじゃないかと思う。
まあ私のこのような指摘が見当違いだとしても、デザインパターンがオブジェクト指向の上に成り立っている事実には変わりないため、プログラミングの哲学が変わるとデザインパターンは使えなくなってしまう。メニィコアの時代はいつ来るのか知らないけれど、並列が当たり前になったらどうなるだろう。本書はマルチスレッドまでは想定しているけれど、並列によるプログラミング手法の変化にまでは対応していない。一生ものの知識としては使えないだろう。
でもしばらくはこの知識が役に立つと思う。正直、Java言語の流行がひと段落した今ですら、オブジェクト指向に則った開発が定着しているとは言いがたい。たぶんあと二十年ぐらいは無駄にならないような気がする。この本はちょっと高いけれど、読んだことのない人は読んでおくといいと思う。
(最終更新日: 2023年12月16日 by ひっちぃ)
|