プログラミングマガジン

プログラミングを中心にIT技術をできるだけわかりやすくまとめます。

  • ホーム
  • デザインパターン
  • 【デザインパターン】「Observer」パターン、実装方法
 
 
     
  • サーバー言語  
    • Python
    • Ruby
    • PHP
    • SQL
  •  
  • インフラ  
       
    • AWS
    •  
    • 基本
    • Git
  • Web
       
    • Web開発
    • JavaScript
    • Vue.js
    • React
  •  
  • 設計  
       
    • 実装設計
    • DB設計
  • 問い合わせ
  

【デザインパターン】「Observer」パターン、実装方法

08.29

  • miyabisan2
  • コメントを書く

この記事は3分で読めます

Observerパターンとは?

要は「通知が欲しいとき」のデザインパターンです。どこか1箇所のクラスで監視させておいて値が変わったら全ての依存するクラスに対して通知を行います。

「Observer:観察する側」と「Subject:観察される側」の役割を持たせてSubjectの状態変化に応じてObserverに通知されるデザインパターン。

硬い定義

あるオブジェクトが変更されたときに、依存するオブジェクト全てに自動的に通知されてそれらが自動的に更新されるようにすること。オブジェクトの「1:多」の依存関係のパターン。

このデザインパターンを使わない場合の問題点

Observerパターンを使わない場合の実装方式としてはTimerなどを常駐させておく方式でしょう。

例えば、メイン画面でタイマーを見に行き、サブ画面でもタイマーを見に行かせるような実装です。その場合以下のような問題点が発生します。

  • メイン画面とサブ画面でそれぞれタイマーを生成するのでインスタンスの数が増える。
  • メイン画面とサブ画面で別々に起動するのでどうしてもタイムラグができる。
  • できるだけラグを生まないようにインターバルを短くしたとしてもタイマーの負荷が増える。

役割

Subject(「Publish:発行」とも呼ばれる場合もある)

観察される側。値が変わったら通知します。「1:多」の「1側」になります。

observerを登録、削除する箱を持たせる。またobserverに通知するメソッド(状態が変化した際にObserverに通知するメソッド)も持たせる。(これはpush型と言われます。)

Observer(「Subsclibe:購読」とも呼ばれる場合もある。)

観察する側。値が変わったら教えられる側です。「1:多」の「多側」になります。

subjectの状態変化を監視する。各observerごとの処理を実装させる。

用途の例

  • 〜の処理が完了したらログに書き出す。
  • メイン画面の状態が変わったら、サブ画面(モーダルなど)の状態も変わって状態が反映されること。

実装方法

フタ通りありますが、基本的にどちらも「片方の状態が変わったらもう片方に通知して状態を変更する」といった処理を実装することになります。

delegateを使って実装する方法(主に「C#」になります。)

C#を使っているのであればこちらの方が実装は簡単です。その際は、片方を終了した際にもう片方への通知が行かなくなるようにdispose(破棄)するのを忘れないようにしましょう。

delegateとは?

クラスのインスタンスのメソッドを登録しておくことです。例えば、同じクラスの画面をかたどって複数インスタンスを作る場合にインスタンスのメソッドを渡しているだけなので、片方の画面にしか影響しないようにできます。

実装

イメージ図

基本的な仕組み

Subject(通知者)の方にObserverのインスタンス(購読者、Observer1、Observer2)を投げておいて、Subjectの方に通知してもらう形に実装します。

Subject

add

Observerをlistなどに追加します。

remove

Observerをlistから削除します。

notify

Observerに通知します。Observerインスタンスのupdateメソッドを呼びます。(for文で回して全てのObserverに対してupdateを実行します。)

なお、delegateなどを使っている場合は、invokeで一発でできます。

Subject側の実装方針

Subjectを抽象クラスにするか、staticクラスにするか。

staticクラス

シンプルに実装するのであればこれで問題ありません。

抽象クラス

テスト駆動の観点で言えば抽象クラスにした方がテストコードは書きやすくなります。staticクラスだと本当に動かさないといけないのでテストがしずらいです。

本来は実データを読み込みにいくが、フェイクデータを読み込みにいくような実装に変更したりします。

IObserver

ただ、1個1個インスタンスをSubjectから呼ぶようにするのはだるいですし、疎結合にしたいということで、Observerをインターフェース化しておいてSubject側からはそれを呼ぶようにします。

命名

「INotify」などと付けます。

Observerの実装クラス

Subjectはインスタンス変数で保持しておきます。(集約)

update

Subject側で通知時に呼ばれるメソッドです。実装クラスでは通知時に実行したい処理を実装しておきます。

インスタンス生成時

Subjectにインスタンスを追加します。(Subjectのaddを呼びます。)

インスタンス破棄時

Subjectからインスタンスを破棄します。(Subjectのremoveを呼びます。)

スポンサーリンク
  • 2021 08.29
  • miyabisan2
  • コメントを書く
  • デザインパターン
  • Tweets Twitter
  • このエントリーをはてなブックマークに追加
  • LINEで送る

関連記事

  1. 2018 04.22

    【デザインパターン】DAO/DTOパターン

  2. 2023 07.08

    【Python】シングルトンの実装

  3. 2018 05.12

    【GoFのデザインパターン】「Abstract Factory」ってどんなパターン?

  4. 2018 05.12

    【GoFのデザインパターン】「Singleton(シングルトン)」ってどんなパターン?、注意点なども。

  5. 2018 05.13

    【GoFのデザインパターン】「Facade(ファザード)」ってどんなパターン?、設計方針なども。

  6. 2018 04.22

    【Java】デザインパターンやクラス設計の基本

  • コメント ( 0 )
  • トラックバック ( 0 )
  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

返信をキャンセルする。

【リファクタリング】「クラスのよくある命名」

【プログラミング】「副作用」、フロントエンド開発でイミ…

RETURN TOP

著者プロフィール

エンジニア歴10年で過去に業務系、Webデザイン、インフラ系なども経験あります。現在はWeb系でフロントエンド開発中心です。

詳細なプロフィールはこちら

スポンサーリンク

カテゴリー

  • Android
  • AngularJS
  • API
  • AWS
  • C++
  • CSS
  • cursor
  • C言語
  • DDD
  • DevOps
  • Django
  • Docker
  • Figma
  • Git
  • GitLab
  • GraphQL
  • gRPC
  • Hasura
  • Java
  • JavaScript
  • Kubernetes
  • Laravel
  • linux
  • MySQL
  • Next.js
  • nginx
  • Node.js
  • NoSQL
  • Nuxt.js
  • Oracle
  • PHP
  • Python
  • React
  • Redux
  • Rspec
  • Ruby
  • Ruby on Rails
  • Sass
  • Spring Framework
  • SQL
  • TypeScript
  • Unity
  • Vue.js
  • Webサービス開発
  • Webデザイン
  • Web技術
  • インフラ
  • オブジェクト指向
  • システム開発
  • セキュリティ
  • その他
  • データベース
  • デザインパターン
  • テスト
  • ネットワーク
  • プログラミング全般
  • マイクロサービス
  • マイクロソフト系技術
  • マルチメディア
  • リファクタリング
  • 副業
  • 未分類
  • 業務知識
  • 生成AI
  • 設計
  • 関数型言語
RETURN TOP

Copyright ©  プログラミングマガジン | プライバシーポリシー