本文へスキップ
BecomeCoder
ブログ一覧Wikiコース一覧

デザインパターンとは|初心者に必要か・GoFのどれから覚えるか

#デザインパターン#GoF#オブジェクト指向#設計#初心者

結論:デザインパターンとは「多くの人が繰り返しぶつかってきた設計問題と、その定番の解き方に付いた名前」です。初心者が23個を暗記する必要はまったくなく、まず Strategy・Factory・Observer・Singleton の4つを、実際に動くコードで理解すれば十分です。 そしてパターンは「先に使う」ものではなく、同じような変更を何度も強いられて痛みを感じてから導入するものです。

この記事は「オブジェクト指向を一通りやった次に何をするか」という位置づけです。クラスとインスタンスがまだ曖昧なら、先に オブジェクト指向がわからない人へ を読んでください。

デザインパターンとは何か ― 「名前」であることが本質

デザインパターンは、1990年代に4人の著者(通称GoF)が、当時のオブジェクト指向プログラムに繰り返し現れる設計を23種類に整理したものです。ただ、初心者が受け取るべき本質は「23種類」ではありません。

大事なのは、パターンは発明ではなく発見だということです。誰もが自然にたどり着く解き方に名前を付けただけなので、経験を積んだ人は「これはStrategyだね」と言うだけで、次のことがすべて伝わります。

つまりパターンはチームの共通語彙です。設計の議論を「あの、条件分岐をクラスに切り出して外から渡すやつ」ではなく一語で済ませられる。これが実務での最大の価値です。用語としての整理は デザインパターン にもまとめてあります。

初心者に必要か ― 答えは「OOPの次に、少しだけ」

結論から言うと、プログラミングを始めて最初の数か月に手を出す必要はありません。理由は明確で、パターンはすべて「インターフェース」「継承」「ポリモーフィズム」で書かれているからです。この土台が無い状態でパターン本を読むと、コードが呪文にしか見えません。

前提として最低限これだけは押さえてください。

いずれも C# オブジェクト指向コース の回で、ブラウザ上でそのままC#を実行しながら確認できます(無料・環境構築なし)。特に最後の2つ、SOLID原則のOとDは、実はほとんどのパターンの中身そのものです。ここが腹に落ちていれば、パターンは半分理解できたようなものです。

一方で、実務1〜2年目でコードレビューを受ける立場になったら、パターンは早めに触れておいたほうが得です。レビューで飛んでくる指摘の多くはパターンの名前で語られるからです。

最初に効く4つのパターン

23個を順番になぞるのは効率が悪いので、登場頻度と効き目が高い順に絞ります。

1. Strategy ― 巨大なif/switchを差し替え可能にする

「会員なら1割引、セール中は2割引、通常はそのまま」のような分岐が、料金計算のあちこちに散らばる。これが典型的な痛みです。Strategyはアルゴリズムそのものをオブジェクトにして、外から渡すことで、条件分岐を消します。

新しい割引を追加するときに既存のクラスを一切触らなくて済む、というのが効果です。まさに開放閉鎖の原則の具体形。振る舞い①:Strategy / State では、割引の実装を差し替えて出力が変わるところをブラウザ上で実行できます。Javaで見たい人は Strategy ― アルゴリズムを丸ごと差し替える にも同じ題材があります。

最初にこれを選ぶ理由は、Strategyがわかると他の振る舞い系パターンの理解が一気に進むからです。

2. Factory ― 「どれを作るか」を1か所に閉じ込める

new があちこちに散らばると、クラスを差し替えたいときに全箇所を直すことになります。Factoryは生成の責任を1か所に集めるパターンです。

「設定ファイルの値によって実装を選ぶ」「テスト時だけ偽物を使う」といった要件が出た瞬間に効きます。生成①:Factory Method / Abstract Factory、Javaなら Factory Method ― 「作る処理」を1か所にまとめる を実行してみてください。

3. Observer ― 変化を知りたい相手に知らせる

「データが変わったら画面も更新したい」「注文が確定したらメール送信と在庫引き当てを走らせたい」。呼び出し元が全員を直接知っていると、相手が増えるたびに書き換えが発生します。Observerは、「変化を知りたい人」が自分から登録しに行く形にして、発信側を相手から切り離します。

UIフレームワーク、イベント、通知機構の土台になっている考え方です。振る舞い②:Observer / Mediator、Observer ― 変化を関係者全員に知らせる で動かせます。

4. Singleton ― ただし「危険も込みで」覚える

インスタンスを1つだけに保証するパターンです。設定やログのように「全体で1つ」が自然な対象には使えます。

ただしSingletonは初心者が最も乱用しやすく、最も後悔されやすいパターンでもあります。どこからでも触れるグローバル変数と実質同じになり、テスト時に差し替えられず、依存関係が見えなくなるからです。だから「作り方」だけでなく「なぜ避けられるか」までセットで理解してください。生成④:Singleton と Singleton ― インスタンスをただ1つに保証する がそれぞれあります。

余力があれば:Adapter・Decorator・Builder

使いすぎるとどうなるか

パターンは「使えば良くなる魔法」ではありません。必要ないのに導入すると、確実に複雑さだけが増えます。

よくある失敗はこの3つです。

  1. 過剰設計(YAGNI違反)。 「将来こう変わるかもしれない」と先回りしてインターフェースを切りまくる。結果、実装が1つしかない抽象と、それを追うための遠回りだけが残ります。
  2. 黄金のハンマー。 覚えたてのパターンを何にでも当てはめる。2行で済む処理が5クラスになります。
  3. 名前だけの適用。 中身はただのif文なのにクラス名に Strategy と付ける。読み手を誤解させる分、コメントより有害です。

判断基準はシンプルで、「同じ理由で、同じ場所を、3回目に書き換えている」と気づいたときが導入のタイミングです。1回目は直書き、2回目は我慢、3回目でパターンを検討する、くらいでちょうどいい。

避けるべき設計そのものは アンチパターンと設計の指針(神クラス・スパゲッティコード・マジックナンバーなど)に整理されています。この回は読み物形式ですが、レビューで指摘される内容がそのまま並んでいるので目を通す価値があります。パターンの分類と使い分けの地図は パターンの実践と使い分け にあります。

現代のコードでは形が変わっているものもある

パターンは「クラスで書く前提」で整理されたものが多く、言語機能の進化によって、より短く書けるようになったものがあります。たとえばStrategyは、関数を値として渡せる言語ならインターフェースとクラスを作らずラムダ1行で表現できます。Javaでの例は 関数インタフェース + ラムダ ― Strategyを1行にする にあります(読み物)。

だからといってパターンの学習が無駄になるわけではありません。「何を差し替え可能にしたいのか」という意図はまったく同じで、書き方だけが短くなっただけだからです。意図を理解していれば、言語が変わっても応用が利きます。

次のステップ ― パターンの先にあるもの

パターンを一通り触ったら、その先は「アプリ全体をどう組むか」に進みます。多くの現場で前提になっているのが依存性注入(DI)とレイヤ分割です。

これらが使えるようになると、テストが書きやすい構造とは何か、疎結合 とは具体的に何を指すのかが実感として分かってきます。逆に、パターンを知らないまま書き続けたコードがどう固まっていくかは 技術的負債 と リファクタリング の話につながります。

次に読む・次に動かす

← ブログ一覧に戻る