はじめに - 結城浩

iii
はじめに
こんにちは、結城浩です。
『Java言語で学ぶデザインパターン入門』へようこそ。
プログラミングを行っていると、以前と同じことを繰り返しているなあ、と気づくとき
があります。経験が増すにつれ、そのような「パターン」が自分の心の中に数多く蓄積さ
れます。そして、その「パターン」を次の開発に当てはめていくことができるようになり
ます。
Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides の4人が、そのような開発者
の「経験」や「内的な蓄積」としてのパターンを
「デザインパターン」
ギャング・オブ・フォア
ゴフ
という形に整理しました。この4人は、the Gang of Four、あるいはGoF と呼ばれています。
GoF は、よく使われる 23個のデザインパターンに「名前」を与え、「カタログ」として
整理し、1冊の本にまとめました。この本が『オブジェクト指向における再利用のための
デザインパターン』
(付録D[GoF]参照)です。
たくさんのモジュールが関連して動作するとき、そのインタフェースが重要なのはみな
さんご存知でしょう。これは、コンピュータの中だけに当てはまるのではありません。た
くさんの開発者が共同して作業するときには、人間のインタフェースが重要になるのです。
そして、そのインタフェースの基となるのは「言葉」です。特に、コードの詳細を離れて、
プログラムの大きな構造について議論するときには、言葉や図式が重要になってきます。
あの開発者が主張している改善案は、私の改善案と同じなのか違うのか? 大枠としては
同じだが、細部で異なるのか? 無限の時間と忍耐力があれば、議論を繰り返して、それ
らの疑問に答えることができるでしょう。しかし、デザインパターンの用語を借りれば、
もっと容易に互いのアイディアを比較し、論じ合うことができるのです。
デザインパターンは、開発者たちに、有益で豊かな語彙を与え、互いの意思疎通を容易
にしてくれるのです。
本書はデザインパターンの入門書です。本書は GoF がまとめた 23 個のデザインパター
ンを1つずつ取り上げて、オブジェクト指向の初心者にもできるだけわかりやすいように
まとめたものです。単なる理屈や理論を示すのではなく、そのパターンを使った具体的な
プログラムを Java言語で書き、実際に動作させています。デザインパターンは遠い将来の
ために学ぶものではありません。デザインパターンは、私たちが日々書いているプログラ
ムを新しい観点から見直し、再利用しやすく、機能拡張しやすいソフトウェアを作るため
の有益な技法なのです。
iv
本書の特徴
本書は次のような特徴を持ちます。
Java言語による実際に動くプログラム
GoF の23 個のデザインパターンすべてについて、Java言語による具体的なサンプルプロ
グラムを示します。すぐに読みとおせるように、ほとんどのサンプルプログラムは 100 行
程度の非常に小さなものになっています。しかも、そのサンプルプログラムには「以下省
略」という部分がなく、実際に自分でコンパイルして実行することができます(C D ROMに収録)。
パターン名の解説
デザインパターンの「名前」はもともと日本語ではなく主に英語です。日本の開発者が
みんな英語に堪能なわけではありませんので、各パターンの名前から正確なイメージを想
起できるとは限りません。本書では、パターンの名前がどのような意味を持つのか、日本
語で表現するとどうなるのかについても説明します。これによって英語が苦手な人であっ
ても、パターンの恩恵を受けることができます。
パターン間の関連と練習問題
デザインパターンはカタログを丸暗記するためにあるのではありません。そのパターン
を身につけ、プログラムを読んでパターンを見抜き、プログラムを書くときにパターンを
当てはめる練習を行う必要があります。そのためには、パターン相互の関連について学び、
また具体的な問題にパターンを適用する練習を行う必要があります。本書では、パターン
を学ぶための練習問題と解答を用意します。
Java言語の関連情報
本書では、デザインパターンの解説だけではなく、Java言語を深く知るための情報も示
します。
マークのあるところはJava言語に関連した情報です。
パターンのイラスト
言葉だけでパターンを覚えるのは難しいものです。本書では、各章の扉にパターンを直
感的に表現したイラストを置きました。これによってパターンを覚えやすくしています。
v
本書の読者
本書は、以下の読者を対象としています。
・オブジェクト指向に興味を持つ人
・デザインパターンに興味を持つ人
(特に、GoFの本に目を通して難しいなあと感じた人)
・Javaプログラマ全般
(特に、抽象クラスやインタフェースの理解に不安がある人)
本書を読むためには、Java 言語に関する基本的な知識が必要です。具体的には、クラス
やインスタンス、フィールドとメソッドについてある程度理解しており、与えられた Java
言語のソースを自分でコンパイルして実行できる程度の知識が必要です。
本書はデザインパターンの本ですが、必要に応じて Java 言語の機能についての補足的な
解説も行っていますので、読み進むうちに Javaの理解も深まると思います。特に、抽象ク
ラスやインタフェースの目的がはっきり理解できていない読者には、おおいに参考になる
と思います。
また、Java言語の知識がなくとも、 C++ 言語を知っていれば比較的容易に理解できると
思います。
Java 言語をゼロから理解したい方は、本書の前に、拙著『Java言語プログラミングレッ
スン』
(付録D[Yuki]参照)から学び始めることをお勧めします。
本書の構成
本書は次のような構成になっています。本書の各章は GoFのデザインパターンに対応し
ています。ただし、GoFの分類とは異なる観点からパターンを分類し、それをパートごと
に分けています。GoFの分類については付録Cを参照してください。
●第1部『デザインパターンに慣れる』では、理解しやすいパターンを使ってデザインパ
ターンに慣れてみましょう。
第1章『Iterator − 1つ1つ数え上げる』では、複数の要素が集まっている中から要素
イテレータ
を1つ1つ取り出していくIterator パターンについて学びます。
第2章『Adapter − 一皮かぶせて再利用』では、異なるインタフェース(API)を持
アダプター
つクラスの間をつなげるAdapter パターンについて学びます。
vi
●第2部『サブクラスにまかせる』では、クラスの継承に関連したデザインパターンにつ
いて学びます。
第3章『Template Method − 具体的な処理をサブクラスにまかせる』では、スーパー
テンプレート・メソッド
クラスで処理の骨組みを定め、具体的な処理をサブクラスで行う Template Method パタ
ーンについて学びます。
第4章『Factory Method −インスタンス作成をサブクラスにまかせる』では、スーパ
ークラスでインスタンスの作り方の骨組みを定め、具体的な作成そのものはサブクラス
ファクトリー・メソッド
で行うFactory Method パターンについて学びます。
●第3部『インスタンスを作る』では、インスタンスの作成に関するデザインパターンに
ついて学びます。
第5章『Singleton − たった1つのインスタンス』では、インスタンスが1つしか存在
シングルトン
しないSingleton パターンについて学びます。
第6章『Prototype − コピーしてインスタンスを作る』では、ひな型となるインスタ
プロトタイプ
ンスをコピーしてインスタンスを作るPrototype パターンについて学びます。
第7章『Builder − 複雑なインスタンスを組み立てる』では、複雑なものを段階を踏
ビルダー
んで組み立てていくBuilder パターンについて学びます。
第8章『Abstract Factory − 関連する部品を組み合わせて製品を作る』では、工場の
アブストラクト・ファクトリー
ように部品を組み合わせてインスタンス生成を行う Abstract Factory パターンについて
学びます。
●第4部『分けて考える』では、ごちゃごちゃになりがちなプログラムを分けて考えるデ
ザインパターンについて学びます。
第9章『Bridge − 機能の階層と実装の階層を分ける』では、2種類の拡張が混在する
ブリッジ
プログラムを機能の階層と実装の階層に分け、その間に橋渡しを行う Bridge パターンに
ついて学びます。
第 10章『Strategy − アルゴリズムをごっそり切り替える』では、アルゴリズムをご
ストラテジー
っそり切り替えて改良をしやすいようにするStrategy パターンについて学びます。
●第5部『同一視』では、一見異なるものを統一的に操作できるようにしたり、取り扱い
方法を変えずに機能を追加するパターンを学びます。また「委譲」についても学びます。
第 11 章『Composite − 容器と中身の同一視』では、容器と中身を同一視して、再帰
コンポジット
的な構造を構築するComposite パターンについて学びます。
第 12 章『Decorator − 飾り枠と中身の同一視』では、飾り枠と中身を同一視して、
デコレータ
飾り枠を何重にも重ねるDecorator パターンについて学びます。
vii
●第6部『構造を渡り歩く』では、構造を渡り歩くパターンについて学びます。
第 13章『Visitor − 構造を渡り歩きながら仕事をする』では、構造を渡り歩きながら
ビジター
同じ操作を繰り返し適用するVisitor パターンについて学びます。
第14 章『Chain of Responsibility − 責任のたらい回し』では、複数のものが連なって
チェーン・オブ・レスポンシビリティ
いる中の、どこかで仕事を行うというChain of Responsibility パターンについて学びます。
●第7部『シンプルにする』では、クラスたちが複雑に関係しているときに、それをシン
プルにするパターンについて学びます。
第 15 章『Facade − シンプルな窓口』では、複雑にからんだクラスを個別に制御す
るのではなく、窓口役のクラスを1つ配置することでシステム全体の操作性をよくする
ファサード
Facade パターンについて学びます。
第 16 章『Mediator − 相手は相談役1人だけ』では、複数のクラスが互いに相談しあ
うのではなく、相談役のクラスを1つ用意し、その相談役とだけやりとりすることでプ
メディエイター
ログラムをシンプルにするMediator パターンについて学びます。
●第8部『状態を管理する』では、状態に関連したパターンを学びます。
第 17章『Observer − 状態の変化を通知する』では、状態が変化するクラスと、その
オブザーバ
変化を通知してもらうクラスを分けて考えるObserver パターンについて学びます。
第18 章『Memento − 状態を保存する』では、現在の状態を保存し、必要に応じて復
メメント
帰させ、アンドゥを行えるようにするMemento パターンについて学びます。
第 19 章『State − 状態をクラスとして表現する』では、状態をクラスで表現し、状
ステート
態に応じた switch 文を減らすState パターンについて学びます。
●第9部『無駄をなくす』では、無駄をなくして効率的な処理を行うパターンについて学
びます。
第20 章『Flyweight − 同じものを共有して無駄をなくす』では、複数箇所で同じもの
フライウエイト
が登場するときに、それらを共有して無駄をなくす Flyweight パターンについて学びま
す。
第 21 章『Proxy − 必要になってから作る』では、本当に目的のものが必要になるま
プロキシー
では代理人を使って処理を進めるProxy パターンについて学びます。
●第 10 部『クラスで表現する』では、意外なものをクラスで表現するパターンを学びま
す。
第 22 章『Command − 命令をクラスにする』では、要求や命令を形にしてクラスで
コマンド
表現するCommand パターンについて学びます。
viii
第 23章『Interpreter − 文法規則をクラスで表現する』では、文法規則をクラスで表
インタプリタ
現するInterpreter パターンについて学びます。
本書のサンプルプログラム
サンプルプログラムの入手方法
本書のサンプルプログラムは以下からダウンロードすることができます。
http://www.hyuki.com/dp/
また、本書の付属CD -ROMにも収録しています。
詳しくは、付録B(p.467)をご覧ください。
サンプルプログラムはMainクラスから起動
Javaでは、
public static void main(String[])
というメソッドを持っているクラスなら、任意のクラスを動作の起点とすることができま
す。しかし、本書では読者の理解を助けるため、サンプルプログラムを動作させる起点は、
必ず Main というクラスにしてあります。
本書で使う用語上の注意
インタフェースとAPI
インタフェースという用語は複数の意味を持ちます。
一般に、「あるクラスのインタフェース」といったとき、通常はそのクラスが持ってい
るメソッドの集まりを意味します。そのクラスに対して何らかの操作や処理を行うときに
は、そのメソッドを通じて行うのです。
ところで Java では、「キーワード interface を使って宣言されるもの」もインタフェー
スと呼んでいます。
この2つのインタフェースという用語はその意味するところは似ていますが、文章の中
ix
で用いるとき、混乱を招く場合があります。そこで本書では、
・インタフェース(API)…… 一般的な意味(APIはapplication interfaceの略)
・インタフェース …………… interface を使って宣言されるもの
と区別することにします。
パターンとクラスと「役」
パターンという用語はデザインパターンの意味で用います。例えば、「GoF の本に登場
するパターンは 23 個ある」は「 GoFの本に登場するデザインパターンは 23 個ある」とい
う意味です。また、「Memento という名前のデザインパターン」のことを単に「 Memento
パターン」と呼びます。
クラスは Javaでいうクラスであり、キーワード class を使ってプログラムで定義される
もののことをいいます。例えば、「このプログラムで定義しているのは Gamer クラスであ
る」などと表現します。「M e m e n t o クラス」といったら、それはプログラム上で c l a s s
Memento { ... }として定義してあるもののことを指します。
やく
「役 」というのは本書だけで用いている表現です。これは、パターン(デザインパター
ン)の中に登場するクラスやインタフェースあるいはインスタンスで、パターンの中で特
定の役回りを果たすものを指します。例えば、「Gamer クラスはOriginator 役である」など
と表現します。必ずしも役の名前がクラスやインタフェースの名前と一致するとは限りま
せん。
細かいことをいうようですが、本文を読んでいくと、ここでいっている意味はよくわか
ると思います。
謝辞
まず何より、デザインパターンをまとめた Erich Gamma, Richard Helm, Ralph Johnson,
John Vlissidesの4人に感謝します。
筆者の書籍・雑誌連載・メールマガジンの読者の方々に感謝します。筆者の Web ペー
ジに集う友人たちや、いつも筆者のために祈ってくれているクリスチャンの友人たちに感
謝します。
本書の原稿、プログラム、それに図は、執筆と並行してインターネット上でレビューが
行われました。レビューを行う方々は、年齢・国籍・性別・住所・職業の区別なくインタ
ーネットで公募され、すべてのやりとりは電子メールと Web を使って行われました。本
x
書のレビューに参加してくださった方々に感謝します。貴重な意見、改善案、バグ報告、
励ましの言葉を送ってくださった、以下の各氏に感謝します(五十音順)。
新真千恵さん、池田史子さん、石井勝さん、石田浩二さん、井芹義博さん、宇田川勝
俊さん、川
昌博さん、榊原知香子さん、砂生貴光さん、佐藤貴行さん、鈴木健司さ
ん、鈴木しのぶさん、竹井章さん、藤森知郎さん、前田恭男さん、前原正英さん、三
宅喜義さん、谷内上智春さん、山城俊介さん。
また、この他にも多くの方からレビュー報告をいただきました。感謝します。
筆者の活動を常に支援してくださるソフトバンク パブリッシング株式会社の野沢喜美
男書籍総編集長、第1書籍編集部の松本香織氏に感謝します。本書の企画をお話したとき
に「それはいい本になります」といってくださったのは、大きな励ましでした。
最愛の妻と2人の息子たちに感謝します。そして、いつも筆者を元気いっぱい応援して
くれる義母に本書を捧げます。
2001年3月 武蔵野にて
結城 浩