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

システムアーキテクト 2025年 午前2 問05


問題文

デザインパターンの一つである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 情報処理技術者試験対策アプリ

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