第3部: GoFデザインパターン¶
デザインパターンは、繰り返し現れる設計問題への定型解のカタログです。GoF(Gang of Four: Gamma, Helm, Johnson, Vlissides)の23パターンが古典として整理されています。
パターンを学ぶ目的(重要)¶
パターン名を暗記することではなく、「この問題には、どんな選択肢があり、なぜこの構造を選ぶのか」を判断できるようになることが目的です。各ページは必ず「パターンなしの実装 → 問題点 → 適用 → 失うもの → 使わない場面」の順で書かれています。「使わない場面」まで読んで1ページです。
- パターンは発明ではなく発見: 優れたコードに繰り返し現れた形に名前を付けたもの。名前は会話の道具(「ここObserverでいいよね」)として最も価値があります。
- パターンは絶対規則ではない: 適用すること自体に価値はなく、問題がないところに適用すればただの複雑化です。
- 言語で形は変わる: GoF本はC++/Smalltalk時代のもの。C++20ではラムダや
std::function、テンプレートで簡潔になるパターンが多く、各ページで現代的な形も示します。
3分類¶
| 分類 | 何を扱うか | 直感 |
|---|---|---|
| 生成 (Creational) | オブジェクトを「誰が・どうやって」作るか | new を直接書くと生成方法に結合する。生成の柔軟性が欲しいときの道具 |
| 構造 (Structural) | クラス・オブジェクトを「どう組み合わせて」大きな構造を作るか | 包む・繋ぐ・まとめる。既存のものを変えずに形を合わせる道具 |
| 振る舞い (Behavioral) | オブジェクト間の「責任分担と通信」をどうするか | 誰が何を決め、どう伝えるか。アルゴリズムと通知の道具 |
生成パターン¶
| パターン | 一言で | ゲームでの典型 |
|---|---|---|
| Factory Method | 生成をサブクラス/関数に任せる | 敵の生成をステージ毎に変える |
| Abstract Factory | 関連する一族をまとめて生成 | プラットフォーム別UI部品一式 |
| Builder | 複雑な構築を段階的に | キャラクターメイキング、レベル構築 |
| Prototype | 見本のコピーで生成 | 配置済み敵の複製(UnityのPrefabの思想) |
| Singleton | 唯一のインスタンス+全域アクセス | 各種Manager(乱用注意の筆頭) |
構造パターン¶
| パターン | 一言で | ゲームでの典型 |
|---|---|---|
| Adapter | インターフェースを変換して繋ぐ | 外部SDKを自作インターフェースに合わせる |
| Bridge | 抽象と実装の2軸を分離 | 武器の種類×プラットフォーム描画 |
| Composite | 個と集合を同一視 | シーングラフ、UIツリー |
| Decorator | 包んで機能を足す | バフでダメージ計算を装飾 |
| Facade | 複雑な下位系に窓口を1つ | サウンド再生の一枚窓口 |
| Flyweight | 共有できるデータを共有 | 弾・木・タイルの共通データ |
| Proxy | 代理を挟んで制御 | アセットの遅延ロード |
振る舞いパターン¶
| パターン | 一言で | ゲームでの典型 |
|---|---|---|
| Chain of Responsibility | 処理者の連鎖に流す | ダメージ軽減の段階処理、UIイベント伝播 |
| Command | 操作をオブジェクト化 | 入力のリバインド、Undo、リプレイ |
| Interpreter | 文法を持つ言語を解釈 | スキルスクリプト、数式パーサ |
| Iterator | 走査を抽象化 | コンテナ走査(C++ではイテレータとして言語に溶けている) |
| Mediator | 多対多の通信を仲介役に集約 | UI画面内の部品間調整 |
| Memento | 状態のスナップショットを保存 | セーブ、Undo、リプレイの基準点 |
| Observer | 変化を購読者に通知 | イベント通知全般(C#のevent) |
| State | 状態ごとの振る舞いをオブジェクト化 | キャラの状態遷移、AI |
| Strategy | アルゴリズムを差し替え可能に | 移動アルゴリズム、AI難易度 |
| Template Method | 骨格を親、詳細を子に | ゲームモードの共通フロー |
| Visitor | 構造側を変えずに操作を追加 | シーンツリーへの操作追加(使用は稀) |
演習 で総仕上げをしてください。
どう選ぶか(逆引き)¶
- 生成方法を差し替えたい・生成に条件がある → Factory Method / Abstract Factory
- 「if種類分岐」が増え続ける → State / Strategy / ポリモーフィズム全般
- 通知したいが相手を知りたくない → Observer(即時)/ Event Queue(遅延)
- 操作を記録・取消・再生したい → Command (+ Memento)
- 既存コードを変えずに機能追加 → Decorator / Proxy / Adapter
- 大量の同種オブジェクトでメモリが苦しい → Flyweight (+ Object Pool)
- 詳しくは 判断ガイド: デザインパターンを使うべきか
全体目次 | 次: Factory Method