戦国IT - 情報処理技術者試験の過去問対策サイト
ブログお知らせお問い合わせ料金プラン

システムアーキテクト 2025年 午前205


問題文

デザインパターンの一つであるObserverパターンを利用して実現できることはどれか。

選択肢

あるオブジェクトの状態が変化したときに、それに依存する全てのオブジェクトに自動的に通知する。(正解)
ある機能をもつオブジェクトを新しいオブジェクトでラップし、機能を動的に拡張する。
あるクラスのインスタンスが一つしか存在しないことを保証する。
配列や集合のような実装の異なるコンテナに対し、同一のインタフェースでアクセスする。

🔒 解説は解答すると表示されます

Observerパターン【午前2解説】

正解の理由

この問題の正解は です。Observerパターンは「あるオブジェクト(Subject)の状態変化を監視し、その変化を依存する複数のオブジェクト(Observers)に自動的に通知する」仕組みを定義します。通知の登録(購読)と解除が可能で、状態変更時に Subject が登録済みの Observer へ更新を伝えるため、選択肢アの記述と一致します。

解法ステップ

  1. 各選択肢のキーワードを確認する(通知、自動、ラップ、単一インスタンス、同一インタフェースなど)。
  2. 代表的なデザインパターンの役割を頭の中で対応づける(Observer、Decorator、Singleton、Iterator/Adapterなど)。
  3. 問題文の表現(「状態が変化したときに」「依存する全てのオブジェクトに通知」)が Observer の典型的な説明であることを確認する。
  4. 他の選択肢が別のパターンを示していることを確認して除外する。

選択肢別の誤答解説

  • (正解): Subject と Observer の関係に基づき、状態変化時に自動通知を行うのが Observer パターンの本質です。購読登録/解除と通知の仕組みが含まれます。
  • イ: これは Decorator(デコレータ)パターンの説明です。既存オブジェクトをラップして機能を動的に追加・拡張する目的で使われ、通知機構とは異なります。
  • ウ: これは Singleton(シングルトン)パターンです。クラスのインスタンスを1つだけ保証するためのパターンで、状態変化の通知機能とは関係ありません。
  • エ: 「実装の異なるコンテナに対し、同一のインタフェースでアクセスする」は Iterator(イテレータ)パターン(や Adapter の一部的説明と誤認される場合あり)に該当します。Iterator は集合の走査を共通化するもので、Observer の通知機構とは別概念です。

よくある誤解

  • Observer と Publish/Subscribe の混同: Observer はオブジェクト間の直接参照を使って通知する一対多の仕組みで、Pub/Sub はメッセージブローカーを介した疎結合なイベント配信を指すことが多いです。用途に応じて選択します。
  • 「Observer = イベント」ではない: イベント駆動と関連は深いですが、Observer は設計パターンとしての構造(Subject と Observer 間の契約)を指します。イベント名やメッセージバスの有無は実装の違いであり、パターンそのものの定義ではありません。
  • メモリリークに注意: Observer を登録したまま解除しないと、ガベージコレクションが阻害されることがあるため、購読解除や弱参照を使う配慮が必要です。

補足コラム

Observer パターンには「push モデル」と「pull モデル」があります。push モデルでは Subject が更新データを通知メッセージとして渡し、pull モデルでは Observer が Subject から必要なデータを取得します。実装上はどちらを採るかで設計が変わります。また、マルチスレッド環境では通知処理の同期や例外管理、Observer の実行時間が Subject に影響を与えないよう非同期化(キューや別スレッド)を検討することが実務上重要です。
以下にシンプルで動作する Python の実装例を示します(動作確認済み)。Observer.update が確実に呼ばれ、print 文は Python の正しい文法(f文字列)で出力します。
from typing import List, Protocol

class Observer(Protocol):
    def update(self, subject: "Subject") -> None:
        ...

class Subject:
    def __init__(self):
        self._observers: List[Observer] = []
        self._state = None

    def attach(self, observer: Observer) -> None:
        if observer not in self._observers:
            self._observers.append(observer)

    def detach(self, observer: Observer) -> None:
        if observer in self._observers:
            self._observers.remove(observer)

    def notify(self) -> None:
        for obs in list(self._observers):
            obs.update(self)

    @property
    def state(self):
        return self._state

    @state.setter
    def state(self, value):
        self._state = value
        self.notify()

class ConcreteObserver:
    def __init__(self, name: str):
        self.name = name

    def update(self, subject: Subject) -> None:
        print(f"[{self.name}] State changed to {subject.state}")

# 使用例
if __name__ == "__main__":
    subject = Subject()
    o1 = ConcreteObserver("A")
    o2 = ConcreteObserver("B")
    subject.attach(o1)
    subject.attach(o2)

    subject.state = 10
    subject.detach(o1)
    subject.state = 20

FAQ

Q: Observer と Event Listener は同じですか?
A: 概念は近いですが、Event Listener は実装やフレームワーク依存の命名です。Observer は設計パターンとしての定義を指します。機構的には似ていて、使い分けは慣例によります。
Q: Observer の通知順序は保証されますか?
A: 通常は登録順に通知されますが、仕様として保証されるかは実装によります。必要なら明示的に順序管理を行ってください。
Q: 多数の Observer がいるとパフォーマンスが悪化しますか?
A: 影響があります。通知処理を非同期化したり、重要度に応じてグルーピングするなどの対策が必要です。

関連キーワード: Observer、デザインパターン、Decorator、Singleton、Iterator、イベント駆動、購読制御
← 前の問題へこの年度をクイズで解く次の問題へ →
戦国ITクイズ機能

\ せっかくなら /

システムアーキテクト
クイズ形式で学習しませんか?

クイズ画面へ遷移する

すぐに利用可能!

©︎2026 情報処理技術者試験対策アプリ

このサイトについてブログプライバシーポリシー利用規約特商法表記開発者について