プログラミングの設計を学ぼうとして、このような解説に遭遇したことはないでしょうか。
- 「Strategyパターンは、アルゴリズムをカプセル化して切り替えるためのものです」
- 「OCP(開放閉鎖原則)とは、拡張に対して開いており、修正に対して閉じていることを指します」
…実のところ、これだけを読んで「明日からの実装に活かせる」と感じる方は、決して多くないはずです。
なぜ、これまでの解説は難しく感じられたのでしょうか
それには明確な理由があると考えています。
- 「何(What)」の説明が中心で、「誰が(Who)」という役割の説明が不足している。
- 「仕組み」は語られていても、現場での「運用のしやすさ」に結びついていない。
- 「専門用語」という言葉の壁が、理解を妨げるノイズになっている。
本記事では、これまでの抽象的なアプローチとは一線を画します。
専門用語を一度脇に置き、「役割」と「責任の委任」という視点だけで、設計を捉え直してみたいと思います。
結論:設計とは「判断の責務を適切に分散させること」
OCPやポリモーフィズムの本質は、決して複雑なものではありません。私たちが目指すべきことは、極めてシンプルです。
「自分ですべてを判断しようとせず、適切な担当者に任せる仕組みを作ること」
- OCP:自分(店長)は業務の流れ(台本)を書き換えない。新しい業務が増えた際は、新しい担当者に「自分の仕事」を完結させるよう依頼する。
- ポリモーフィズム:依頼を受けた担当者たちが、それぞれの専門性に基づいて自律的に動く。
この関係性が構築できれば、複雑な if 文や switch 文をコードから排除することが可能になります。
レストランの店長の視点で考える「責務の委任」
皆様がレストランの店長であると想像してみてください。
ここでは、システムの根幹となる「支払い処理」の設計を例に挙げます。
【課題の多い設計】店長がすべての判断を抱え込む(OCP違反)
// 店長が「誰が何をするか」をすべて把握し、その都度判断を下している状態
function pay(type) {
if (type === 'credit') {
// Aさんの連絡先を確認し、個別に指示を出す
} else if (type === 'paypay') {
// Bさんの連絡先を確認し、個別に指示を出す
} else if (type === 'apple_pay') {
// Cさんの連絡先を確認し、個別に指示を出す
}
}
この設計における問題点:
新しい支払い方法が追加されるたびに、店長(メインの処理フロー)が毎回判断ロジックを書き換え、再テストを行わなければなりません。
これでは、規模が拡大するにつれて店長の負担は増大し、修正によるミスが発生するリスクも高まってしまいます。
【理想的な設計】「受付係」に判断を委ねる(OCP準拠)
店長は、次のように振る舞いを変えてみます。
「受付係(Registry)さん、お客様が選択された方法に応じて、適切な担当者(Processor)を呼んでください。あとの実務は、その方にお任せします」
// 店長は「誰が実務を行うか」の詳細を知る必要はありません。
function pay(type) {
const processor = registry.get(type); // 受付係に担当者の選定を依頼する
processor.execute(); // 担当者がそれぞれの専門知識で動く(ポリモーフィズム)
}
店長はこの処理フローを二度と修正する必要がありません。
新しい支払い方法が増えたとしても、店長は現在の業務を変えることなく、平穏を保つことができるのです。
専門用語を「現場の役割」に置き換えて理解する
現場でスムーズに活用できるよう、カタカナ語を「役割名」に変換してみましょう。
| 専門用語 | 現場での役割 | 役割の詳細 |
|---|---|---|
| Strategy | 業務の手順書 | 「カード決済」「QR決済」といった、個別のマニュアルです。 |
| Processor | 現場の担当者 | 手順書を理解し、実務を遂行する人です。「1人1手順書」が原則です。 |
| Provider | 提携先の企業 | 決済を代行する「Stripe社」等の外部機関です。担当者の連絡先となります。 |
| Channel | お客様の選択肢 | 画面上に表示される「支払い手段」です。これが増えると担当者も増えます。 |
| Payload | 担当者専用の備品 | 担当者ごとに必要な情報(トークン等)を収める器です。他者とは共有しません。 |
| Registry | 振り分けの受付係 | 「この手段なら、担当者はあの方だ」と判断する人です。判断の責任をここに集約します。 |
| Polymorphism | 指示の共通化 | 「誰に対しても『お願いします』の一言で実務が始まる」便利な仕組みです。 |
| OCP | フローの固定化 | 「メインの処理の流れは変えず、担当者の追加だけで対応する」という方針です。 |
この設計がもたらす「真のメリット」とは
「拡張性」や「保守性」という抽象的な言葉を超えて、開発現場にどのような恩恵をもたらすのかを整理します。
- 「既存機能を壊す」リスクの低減
メインの処理フロー(店長の動き)を一切変更せずに機能を追加できるため、意図しないバグ(デグレード)の発生を物理的に防げます。 - テスト効率の大幅な向上
新機能を追加する際は、新しい担当者のコードだけをテストすれば済みます。既存の安定したコードまでテストし直す必要はありません。 - レビューコストの削減
レビュアーは「新しく追加された担当者のコード」だけに集中できます。システム全体の整合性を一から確認する手間が省けます。
まとめ:これだけ答えられれば合格です
もし後輩から「なぜ、これほどまでに if 文を避ける必要があるのですか?」と尋ねられたら、ぜひこう答えてあげてください。
「
if文を増やすということは、その都度『全体の流れ』を書き換えるというリスクを負うことになります。 誰が実務を担うかは『受付係』にお任せして、店長は『お客様にサービスを提供する』という本来の目的だけに集中すべきではないでしょうか」
関連記事のご案内
本記事の内容をより具体的に理解したい方は、以下の記事もあわせてご覧ください。
専門用語という言葉に惑わされないでください。 大切なのは、「誰がどの判断に責任を持っているか」を見極めることなのです。


コメント