コンテンツにスキップ

第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