基本情報のデザインパターンは、名前を並べて覚えると似た用語が混ざりやすい分野です。最初は「何を変えたい設計なのか」に注目すると、生成・構造・振る舞いの3分類がつながります。
例えば、作るオブジェクトを変えるなら生成、既存部品の呼び出し方を合わせるなら構造、計算方法や通知の関係を変えるなら振る舞いです。この記事ではFactory Method・Adapter・Observer・Strategyを、設計上の困りごとと自作問題で整理します。
- 生成・構造・振る舞いを変更したい対象から見分ける
- Factory Methodと単なる生成用関数の違いを理解する
- Adapter・Observer・Strategyを自作問題で選び分ける
- MVCやフレームワークとの違いと使いすぎの注意を押さえる
基本情報のデザインパターンを3分類で整理

設計の問題と解決の型を結び付ける
デザインパターンは、繰り返し現れる設計上の問題に対して、クラスやオブジェクトの役割をどう分けるかを整理したものです。完成済みのプログラムそのものではなく、状況に合わせて実装する設計の知識と考えると分かりやすいですね。
例えば「料金の計算方式が増えるたびに、注文処理の長い条件分岐を修正する」という問題があります。このとき、計算方式を独立した部品として差し替える設計が候補になります。大切なのは名前を付けることより、変更の影響がどこまで及ぶかを考えることです。
IPAの基本情報技術者試験シラバスVer.9.2では、デザインパターンについて、主にオブジェクト指向設計で使うこと、3分類の特徴を踏まえて利点と留意事項を理解することが示されています。以下の代表例は、この理解を具体化するための学習例です。ここで扱う名前だけが出題される、という意味ではありません。
| 分類 | 主に着目する問題 | この記事の代表例 |
|---|---|---|
| 生成 | どのオブジェクトを、どこで生成するか | Factory Method |
| 構造 | 既存のクラスやオブジェクトをどう組み合わせるか | Adapter |
| 振る舞い | 処理をどう選び、オブジェクト同士をどう連携させるか | Observer・Strategy |
「生成」は作る場面、「構造」はつなぐ形、「振る舞い」は処理ややり取り、と短く言い換えてから、具体的な目的へ戻りましょう。ただし、どのパターンもクラスの組み合わせや処理に関わるため、プログラムに含まれる単語だけでは分類できません。設計で解決しようとしている中心の問題を見ます。
クラス・インスタンス・継承・多態性が曖昧なら、先に基本情報のオブジェクト指向と継承・多態性の違いを確認すると、以降の役割分担を読みやすくなります。
生成する種類を変えるFactory Method
Factory Methodは、オブジェクトを生成する操作を定め、具体的に何を生成するかをサブクラスで決められるようにするパターンです。生成したオブジェクトを使う共通処理と、具体的な生成の判断を分けたいときに検討します。
自作例として、集計結果をファイルへ出力するアプリを考えます。データを読み、集計し、出力部品へ結果を渡す流れは共通です。一方で、PDF用の出力部品を使うか、CSV用の出力部品を使うかは変えたいとします。
そこで、共通の出力処理を持つ親クラスに「出力部品を作る」という操作を用意します。PDF用の子クラスはPDF出力部品を返し、CSV用の子クラスはCSV出力部品を返します。共通処理は、返された部品が持つ共通の「書き出す」操作を呼び出します。生成される具体的な部品を、共通処理へ直接書き込まない点がポイントです。

この設計では、別形式への対応を追加するとき、対応する生成操作を持つ子クラスを追加する形を取れます。ただし、共通の出力部品の約束自体を変えるなら、利用側の修正が必要になることもあります。「パターンを使えば今後どんな変更も局所化できる」とは考えないでください。
また、オブジェクトを返す関数を一つ作っただけで、すべてGoFのFactory Methodになるわけではありません。引数を見て条件分岐し、具体的なクラスを選ぶ生成用関数もあります。それは生成処理をまとめる方法ですが、ここで学ぶFactory Methodの見分けどころは、生成操作の具体化をサブクラスへ委ねることです。
この定義は、開発者向け教育資料のDouglas SchmidtによるDesign Patterns in Javaの公式説明でも確認できます。「生成」という分類と、サブクラスへ委ねる仕組みをセットで押さえましょう。
適用を考えるのは、共通処理の流れを残しながら、そこで扱う生成物の種類を拡張したい場面です。生成する種類が一つで、単純な初期化しかないなら、普通の生成処理のままの方が追いやすいこともあります。工場という言葉から、必ず専用クラスを大量に作る設計だと決めつける必要はありません。
呼び出し方を合わせるAdapter
Adapterは、既存の部品が持つインタフェースを、利用側が期待するインタフェースへ合わせるパターンです。ここでいうインタフェースは、画面の見た目ではなく、メソッド名・引数・戻り値など、部品を利用するための約束です。
自作例として、アプリ側は「温度を摂氏で取得する」という操作を呼びたいのに、既存の測定部品は「華氏の整数を返す」という操作しか持たない場合を考えます。既存部品を変更できず、アプリの各所へ華氏対応の処理を広げたくないとします。
この間にAdapterを置き、アプリからの摂氏取得の要求を受けて既存部品を呼び、必要な単位変換を行って返すようにします。アプリは摂氏を取得する約束で利用でき、既存部品側の呼び出し方法の違いはAdapterへ集められます。

MicrosoftのAdapterとFacadeの公式解説でも、既存クラスのインタフェースを別のインタフェースとして使えるようにする点が説明されています。Adapterは、すでにある部品との不一致を埋める、という目的から判断すると迷いにくくなります。
ただし、名前やデータ形式を変えれば意味まで一致するとは限りません。例えば、取得できるのが一時間前の温度だけなら、Adapterを置いても現在の温度を保証できません。値の範囲、単位、失敗時の振る舞いも含めて、利用側が求める約束を満たすか確認する必要があります。
「複雑な機能群を、簡単な窓口から使わせたい」という目的ならFacadeが候補です。一方、Adapterは「すでにある呼び出し方が合わない」という不一致が出発点です。同じように間へ部品を置く設計でも、何を解決するためかが違います。外側から包むという形だけで選ばないようにしましょう。
状態変化を伝えるObserver
Observerは、状態の変化などを、登録された複数の受け手へ通知する関係を作るパターンです。通知する側と、通知を受けて行う処理を分けて考えます。受け手の種類が増えても、通知元へ個別の処理を次々に書き足す設計を避けたいときに役立ちます。
自作例では、学習アプリの回答データが更新されたら、正答率の表示と学習履歴の表示を更新したいとします。回答データを管理する部品が、画面ごとの具体的な更新手順まで知っていると、表示を増やすたびに回答データ側へ手を入れることになります。
そこで、更新を知りたい表示部品を受け手として登録します。回答データ側は、状態が変わったら共通の通知方法で受け手へ知らせます。正答率の表示部品は率を再計算し、履歴の表示部品は一覧を更新します。同じ通知を受けても、何をするかは各受け手の役割です。

MicrosoftのObserverパターンの公式資料は、通知元と登録される受け手、および登録解除の仕組みを説明しています。学習では「変化の通知」と「受け手の登録」という関係に注目し、単に複数の関数を呼ぶという説明で止めないことが大切です。
設計時には、画面を閉じたあとも不要な受け手が登録されたままにならないか、受け手の処理が失敗したときどうするかも考えます。通知を受け取る順番に業務上の意味があるなら、その順番を別途定める必要があります。名前を付けるだけでは、通知の成功や実行順は保証されません。
また、Observerだから必ず別スレッドで実行されるわけではありません。通知元が受け手の処理を順に呼び出す実装もあります。メッセージ基盤を介して非同期に配信するPublisher-Subscriberと関連する考え方はありますが、通信の仕組みや配送の保証まで同じものとして扱わないでください。
処理の選択肢を替えるStrategy
Strategyは、複数のアルゴリズムを共通の約束で扱い、必要に応じて差し替えられるようにするパターンです。同じ目的を達成する方法が複数あり、利用する側へ各方式の細部を持ち込まずに選びたいときに検討します。
自作例では、商品一覧を「価格の低い順」「新着順」「名前順」で並べ替える機能を考えます。一覧を表示する部品に、すべての比較方法と追加される方式の条件分岐を集めると、並べ替え方法の変更と画面表示の変更が混ざりやすくなります。
そこで、並べ替えの比較方法を共通の約束で扱える部品に分けます。一覧の部品は、その約束に従って比較を依頼するだけです。使う比較部品を替えれば、表示処理の基本的な流れを保ちながら、並び順を変えられます。

MicrosoftのStrategyの公式解説では、アルゴリズムの振る舞いを実行時に選べる点が説明されています。ただし、Strategyを使ったら必ず利用中に切り替えなければならないわけではありません。起動時などに一度選び、以後その方式を使う設計も考えられます。
Factory MethodもStrategyも、結果として使う具体的な部品が変わるように見えます。違いは、Factory Methodが「生成する種類をどう決めるか」、Strategyが「使う処理方式をどう差し替えるか」に着目している点です。問題文に「切り替える」とあっても、その一語だけでStrategyを選ばないようにしましょう。
比較条件が一つしかなく、将来の変更も具体化していないなら、小さな関数で十分な場合があります。Strategyで方式を分けるほど、選択する処理、部品間の約束、確認すべき組み合わせも増えます。選択肢を独立させる利益が、その負担を上回るかを考えるのが適用条件です。
基本情報のデザインパターンを設計例で判断

自作問題で変更の目的を読み取る
ここからは用語の説明を隠したつもりで、次の四つの状況を読みましょう。いずれも理解を確認するための自作問題であり、IPAが公開した過去問題の転載ではありません。選択肢に近そうな単語を探すより、困りごとを一文で言い直すのがコツです。
| 自作問題 | 選ぶ候補 | 判断の理由 |
|---|---|---|
| 共通のファイル出力処理を保ち、生成する出力部品の種類を子クラスに決めさせたい | Factory Method | 変えたいのは生成する具体的な型 |
| 呼び出し方の異なる既存の測定部品を、アプリが期待する約束で利用したい | Adapter | 変えたいのは既存部品と利用側の接続方法 |
| 回答データの更新を、登録された複数の表示部品へ伝えたい | Observer | 変えたいのは状態変化の通知と受け手の関係 |
| 商品一覧を利用側の処理を大きく変えず、異なる比較方式で並べたい | Strategy | 変えたいのは差し替え可能な処理方式 |
一問目では、単にPDFとCSVという複数の選択肢があるから生成に分類するのではありません。「生成操作を子クラスに委ねる」という条件が決め手です。もし既に用意された二つの処理部品を選んで使うだけなら、主題はStrategyに近づきます。
三問目は、受け手を一つ選んで処理を依頼する話ではなく、登録された受け手へ変化を知らせる話です。ObserverとStrategyを迷ったら、「複数へ通知したいのか」「一つの方式を選んで使いたいのか」を比べてみてください。
もう一つ、判定できない例も考えておきましょう。「出力機能を便利にしたい」という一文だけでは、適切なパターンは決まりません。生成方法、既存部品との接続、処理方式、変更通知のうち、どれに問題があるかを補う必要があります。説明にない条件を勝手に足して解答する癖を避ける練習にもなります。
MVCやフレームワークと分ける
MVCは、Model・View・Controllerに役割を分けてアプリケーションを構成する考え方です。Modelはデータや業務上の処理、Viewは表示、Controllerは入力を受けた制御などを担います。細部の分担は実装によって異なりますが、全体の責務をどう分けるかに注目します。
先に挙げたIPAシラバスでは、MVCモデルはアーキテクチャパターンの用語例として記載されています。デザインパターンの3分類に「MVC」を第四の種類として追加する読み方はしません。アプリ全体の役割分担と、個々のクラスやオブジェクト間の設計上の問題を、階層を意識して整理します。

例えば、MVCで分けた学習アプリでも、Model側の状態変化をView側へ伝える部分にObserverを使う設計は考えられます。また、Model側で学習問題を選ぶ方式を差し替える部分にはStrategyを検討できます。一つのシステムの中で複数の考え方が併存しても、分類が矛盾するわけではありません。これは役割分担を示すための設計例です。
フレームワークは、アプリケーションを作るための土台となるコードや仕組みを提供します。デザインパターンは、その土台やアプリの設計を説明する知識です。フレームワークの内部や拡張方法にパターンが使われることはありますが、パターン名を一つ覚えただけで特定のフレームワークを使えるわけではありません。
試験の学習では、「役割分担の考え方」「繰り返す設計問題への解決の型」「実際に利用するコードの土台」を区別すると整理しやすくなります。さらに、UMLはそれらの関係を図として表現するための記法です。設計の型と図の記法も、同じものとして扱わないようにしましょう。
利点と過剰設計の負担を考える
デザインパターンを学ぶ利点は、似た問題を一から検討し直す負担を減らし、設計意図を共有しやすくすることです。例えば「通知先の追加を回答データ側へ持ち込まないためにObserverを使う」と説明できれば、何を守りたい設計なのかを話し合えます。
ただし、名前だけでは十分ではありません。同じObserverという言葉を使っていても、通知のタイミング、失敗時の扱い、登録解除の責任が決まっていなければ、認識はずれます。パターン名に加えて「何が変わり、どこは共通にするか」を説明することが大切です。
負担になるのは、小さな処理にも一律にパターンを適用し、役割やクラスを細かく分けすぎるケースです。一つの処理を理解するために多くの部品を行き来したり、現実には使わない拡張のために複雑な約束を維持したりすると、変更しやすくする目的から離れてしまいます。

- 同じ種類の変更が、現在どこで繰り返し起きているか
- 分離すると、修正・確認が必要な範囲はどう変わるか
- 増える部品や依存関係を、担当者が説明できるか
- 普通の関数や既存の仕組みでも十分に対応できないか
ここで注意したい代表例がSingletonです。これは、あるクラスのインスタンスを一つに制限し、アクセスする窓口を提供するパターンです。しかし、「一つにした方がいつでも便利」という結論にはなりません。複数の処理が共有の状態を書き換えると、影響を追いにくくなることがあります。
例えば、自作の練習アプリで採点条件を共有状態として持たせると、ある練習の設定変更が別の練習へ影響する設計になり得ます。独立した条件を渡す方が目的に合うなら、その方法を検討します。また、単一のプロセス内で一つという設計から、複数サーバを含むシステム全体でも一つだとは言えません。必要な範囲を確認してください。
このように、パターンの適用は保守性を自動的に保証するものではありません。部品間の依存関係を評価する考え方は、モジュール結合度・凝集度の違いと評価の基準と合わせて学ぶと、どこを改善したいかを具体的に説明しやすくなります。
クラス図は役割と依存先から読む
パターンの構造をクラス図で示されたら、最初から図の形を丸ごと覚えようとせず、利用する側・共通の約束・具体的な実装を探しましょう。誰が何を呼び出し、どの部分を替えられるのかをたどると、名称を知らなくても目的を整理できます。
Factory Methodの例なら、共通処理を持つ側に生成操作があり、子クラスでその操作が具体化される関係を確認します。Strategyなら、処理を利用する側が、共通の約束を通して別の部品へ仕事を依頼しているかを見ます。継承がある、インタフェースがある、という一箇所だけで決めないことが大切です。
Adapterでは、利用側の期待する約束と、既存部品の約束がどこで変換されるかを確認します。Observerでは、通知元と受け手がどのように登録され、どの方向へ通知されるかを追います。図だけで通知順や非同期実行が示されていなければ、そこまで読み足してはいけません。
継承・実装・関連などの線の意味が曖昧な場合は、基本情報で扱うUML図の読み分けで記法を復習してから戻ると、パターンの目的へ集中しやすくなります。
復習時は、クラス名を隠して「この部品は何の責任を持つか」を説明してみてください。正しい名称を答えられても役割を説明できなければ、具体的な条件が変わったときに迷いやすくなります。反対に、責任と変えたい部分を説明できれば、知らない名前が出ても選択肢を比較する手掛かりを持てます。
基本情報のデザインパターンのまとめ
基本情報のデザインパターンは、生成・構造・振る舞いの3分類を出発点にし、解決したい問題から代表例を結び付けましょう。Factory Methodは生成操作をサブクラスで具体化し、Adapterは既存部品とのインタフェースの不一致を埋めます。Observerは登録された受け手へ変化を知らせ、Strategyは処理方式を差し替えます。
覚えるときは「名前・分類・困りごと・解決方法・注意点」の順で短く説明します。例えばAdapterなら「構造、既存部品の呼び出し方が合わない、間で変換する、意味や制約まで一致するか確認する」という形です。23個の名前を一度に並べるより、一つの条件から選べるかを確かめる方が理解の穴を見つけやすくなります。
MVCやフレームワーク、UMLとの違いも押さえたら、自作問題の条件を一つ変えて理由を説明してみましょう。知識全体の定着は、基本情報の科目A・科目Bに取り組める演習アプリも使い、解答後に選んだ理由を言葉にする練習へつなげてください。


コメント