開発支援・コーディング

デザインパターンとは|支払い方法を1つ足すのに、3箇所直すか1箇所で済ませるか

デザインパターンは何のためにあるのかパターンを使うと具体的に何が変わるのかどこまで使えばよく、どこから使いすぎなのか

デザインパターンは、設計でくり返し出てくる問題への定型的な解き方をまとめたものです。ただ、名前と分類を覚えても「で、何が良くなるのか」が分かりにくいのが正直なところだと思います。

そこで今回は測りました。支払い方法を扱うコードを2通りで書いて、4種類目を追加するときに何箇所直す必要があるかを数えています。結果は3箇所と1箇所でした。

この記事の要点

  • パターンはそのまま貼れるコードではなく、解き方の見取り図。実装は状況に合わせて変わる
  • 効果は行数ではなく変更時に触る箇所の数に出る
  • 実測では、支払い方法の追加で条件分岐版が3箇所・Strategy版が1箇所だった
  • 使う合図は同じ条件分岐が複数の関数に現れたとき。先回りして入れない

デザインパターンは何のためにあるのか

設計でくり返し出てくる問題に、名前と解き方を与えたものです。そのまま貼れるコードではなく、状況に合わせて実装する見取り図にあたります。

デザインパターンは、設計でよく起きる問題に対する定型的な解き方をまとめたものです。あらかじめ用意された設計図のようなもので、自分のコードに合わせて形を変えて使います。

ここで重要なのは、パターンがコードそのものではないことです。ライブラリや既製の関数のように、見つけてきてコピーすれば動く、というものではありません。

アルゴリズムとの違い

パターンはアルゴリズムと混同されがちです。どちらも「よくある問題の典型的な解き方」を指すからです。ただ、アルゴリズムが具体的な手順を定めるのに対し、パターンはもっと上の階層にあります。

料理でたとえると、アルゴリズムはレシピです。手順どおりに進めれば同じものができます。一方パターンは設計図に近く、できあがりの姿は分かるが、作る順番は自分で決めるものです。同じパターンでも、プログラムが違えばコードは違います。

パターンの説明に含まれるもの

パターンの解説は、たいてい決まった形式で書かれています。何を解決するのか(目的)、なぜその解き方になるのか(動機)、部品どうしがどう関係するか(構造)、そして具体例のコードです。

この形式のおかげで、初めて見るパターンでも「どういう困りごとに効くのか」から読めるようになっています。名前から覚えようとすると難しく感じるので、困りごとの側から入るのがおすすめです。

余談 全部を覚えなくてよい

パターンは20種類以上ありますが、実際によく出会うのは数種類です。しかも名前を覚えることに価値はありません。名前は他の人と話すときの符丁として役に立つだけで、効果を生むのは使いどころの判断だと編集部は考えています。

出典Refactoring.Guru「What is a design pattern?」2026-08-17 確認
The pattern is not a specific piece of code, but a general concept for solving a particular problem.
原文Refactoring.Guru「What is a design pattern?」 この内容の有効期限2027-02-17

支払い方法を1つ足すのに、何箇所直すか数えてみた

条件分岐で書いた版とパターンで書いた版を用意して、4種類目を追加する作業を比べました。触る箇所は3箇所と1箇所でした。

デザインパターンの効果は、行数の増減では測れません。変更するときに何箇所触るかに出ます。そこで実際に数えました。

題材は支払い方法です。カード・銀行振込・コンビニ払いの3種類があり、それぞれ手数料の計算・画面の表示名・即時反映かどうかが違います。

条件分岐で書くと、知識が散らばる

素直に書くと、関数ごとに支払い方法の分岐が並びます。下のコードは読み飛ばして大丈夫です。見どころは、同じ3種類の分岐が3つの関数にくり返し現れることです。

javascript
function feeByIf(method, amount) {
  if (method === 'card') return Math.round(amount * 0.036);
  if (method === 'bank') return 220;
  if (method === 'conveni') return amount < 10000 ? 190 : 300;
}
function labelByIf(method) {
  if (method === 'card') return 'クレジットカード';
  if (method === 'bank') return '銀行振込';
  if (method === 'conveni') return 'コンビニ払い';
}
function isInstantByIf(method) {
  if (method === 'card') return true;
  if (method === 'bank') return false;
  if (method === 'conveni') return false;
}

種類ごとの知識を1箇所にまとめる

同じ内容を、支払い方法ごとに1つのまとまりとして書き直します。この形はStrategyパターンと呼ばれます。名前より、1つの支払い方法について知るべきことが1箇所に集まっている点を見てください。

javascript
const methods = {
  card:    { label: 'クレジットカード', instant: true,  fee: (a) => Math.round(a * 0.036) },
  bank:    { label: '銀行振込',        instant: false, fee: () => 220 },
  conveni: { label: 'コンビニ払い',    instant: false, fee: (a) => (a < 10000 ? 190 : 300) },
};
text
--- 既存3種類での手数料(12,000円の場合)---
  クレジットカード: 条件分岐版=432円 / Strategy版=432円
  銀行振込: 条件分岐版=220円 / Strategy版=220円
  コンビニ払い: 条件分岐版=300円 / Strategy版=300円
--- 4種類目「後払い」を追加するとき、修正が要る箇所を数える ---
  条件分岐版: 3箇所(feeByIf, labelByIf, isInstantByIf)
  Strategy版: 1箇所(methods に1件追加)
  追加後の動作確認: 後払い の手数料=350円

差が出ました。3箇所と1箇所です。既存3種類での計算結果はどちらも同じなので、動きは変わっていません。変わったのは追加のときの手間だけです。

条件分岐版で3箇所になるのは、支払い方法の知識が3つの関数に分かれているからです。1箇所でも直し忘れると、手数料は計算できるのに表示名が出ないといった状態になります。

支払い方法が増えるほど差が開く。条件分岐版は関数の数だけ修正箇所が増える。

単位: 箇所条件分岐で書いた版3箇所Strategyで書いた版1箇所−67%関数が3つの場合の実測値。扱う関数が5つに増えれば条件分岐版は5箇所になるが、Strategy版は1箇所のまま。
図1 ── 支払い方法を1種類追加するときに修正が必要な箇所の数

パターンの解説では、詳細に従って自分のプログラムの実情に合う形で実装することが勧められています。上のコードもクラスを使わないJavaScriptの書き方にしていて、教科書どおりの形ではありません。それで構いません。

出典Refactoring.Guru「What is a design pattern?」2026-08-17 確認
You can follow the pattern details and implement a solution that suits the realities of your own program.
原文Refactoring.Guru「What is a design pattern?」 この内容の有効期限2027-02-17

どこまで使えばよく、どこから使いすぎなのか

入れる合図は、同じ条件分岐が複数の関数に現れたときです。まだ現れていない変更を予想して先回りすると、手間だけが残ります。

デザインパターンで難しいのは、覚えることではなくいつ使うかの判断です。Fowlerも、解き方を知っているだけでなく、いつ使うか・どう育てていくかを理解することが必要だと述べています。

入れる合図は、重複した分岐

前の節の実験がそのまま合図になっています。同じ種類の条件分岐が、2箇所以上の関数に現れたときです。1箇所だけなら、まだ分岐のままで困りません。

  1. 同じ分岐が2箇所以上に現れている。1箇所だけならそのままでよい
  2. その分岐が「種類ごとの知識」を表している。単なる場合分けとは区別する
  3. 種類が今後も増える見込みがある。増えないなら分岐のままで足りる
  4. 直し忘れが実際に起きた。起きたなら合図としては十分に強い

先回りして入れると、手間だけが残る

逆に避けたいのは、まだ起きていない変更を見越してパターンを入れることです。間接的な構造が増えるぶん、読むときの負担は確実に増えます。その負担に見合う変更が来なければ、損をしただけになります。

判断に迷ったら、分岐のまま書いておいて構いません。2箇所目が現れた時点で書き直せば、そのときにはどう分けるべきかの情報も増えています。先に決めるより判断が正確になります。

設計の方向性についてはクリーンアーキテクチャの記事ドメイン駆動設計の記事でも扱っています。あちらは全体の構造の話で、こちらは局所的な書き方の話です。

余談 名前を言えることが目的ではない

パターン名を使って設計を説明できると、それらしく見えます。ただ実際に効いているのは変更したときに触る箇所が減っているかどうかだけです。名前が出てこなくても、変更が楽になっていればそれで足りると編集部は考えています。

出典Martin Fowler「Is Design Dead?」2026-08-17 確認
A good knowledge of patterns: not just the solutions but also appreciating when to use them and how to evolve into them.
原文Martin Fowler「Is Design Dead?」 この内容の有効期限2027-02-17

よくある質問

パターンを全部覚える必要がありますか?
ありません。よく出会うのは数種類で、それも名前より「どういう困りごとに効くか」を知っている方が役に立ちます。Fowlerも、解き方だけでなく、いつ使うか・どう育てるかを知ることが重要だと述べています。
コードが増えるので、かえって読みにくくなりませんか?
使いどころを外すとそうなります。パターンは変更しやすさと引き換えに間接的な構造を増やすため、変更が起きない箇所に入れると手間だけが残ります。困りごとが実際に出てから入れるのが安全です。
ライブラリを使うのとは何が違いますか?
ライブラリはそのまま組み込める部品ですが、パターンはコードそのものではありません。同じパターンでも、プログラムが違えばコードは変わります。料理でいえばレシピではなく設計図に近いものです。
個人開発でも使う意味はありますか?
あります。ただし目的は「きれいに書くこと」ではなく、後から変更するときの手間を減らすことです。変更する予定のない箇所には入れなくて構いません。

まとめ

  • パターンは解き方の見取り図であって、貼り付けるコードではない
  • 効果が出るのは行数ではなく変更時に触る箇所の数
  • 実測では支払い方法の追加が3箇所から1箇所になった
  • 入れる合図は同じ分岐が複数箇所に現れたとき。先回りしない

今日から始められること

  1. 同じ条件分岐が2箇所以上に現れているコードを探す
  2. その分岐が「種類ごとの知識」を表しているか確認する
  3. 種類ごとの知識を1箇所にまとめられるか検討する
  4. 変更予定のない箇所には入れないと決めておく

実務で組んだデザインパターンのワークフローには、値段が付きます

同じ課題を持つ会社にとって、動いている設定は「作る時間」を買えるということです。ServiceDockは自作のワークフローやテンプレートを出品できるマーケットプレイスです。手数料や出品の流れは出品者向けページにまとまっています。

出品の仕組みを見る