Observerパターンとは | GoFデザインパターン

記事内に広告が含まれています。

Observerパターンは、GoFデザインパターンの一つで、オブジェクト間の依存関係を管理するための手法です。

状態の変化を通知する仕組みとして、イベント駆動型のシステムや、リアルタイム更新が必要な場面で多用されています。

本記事では、Observerパターンの概要、使い方、そしてJava、C++、C#、VB.NETでの実装例を解説します。

Observerパターンとは

Observerパターンは、あるオブジェクト(Subject)の状態が変化した際に、他のオブジェクト(Observer)に自動的に通知するデザインパターンです。

これにより、SubjectはObserverに対して直接的な依存関係を持たずに状態を伝えることができます。

Observerパターンの使い方

Observerパターンの主な使い道としては、GUIアプリケーションにおけるイベント通知や、データの変更をリアルタイムで反映させるシステムがあります。

Subjectが複数のObserverを持つことができ、Observerは自分の関心のあるSubjectからの通知のみを受け取ることが可能です。

Observerパターン実装サンプル

JavaでのObserverパターン実装

以下はJavaでのObserverパターンの実装サンプルです。


        // Subjectクラス
        import java.util.ArrayList;
        import java.util.List;

        class Subject {
            private List observers = new ArrayList<>();
            private int state;

            public int getState() {
                return state;
            }

            public void setState(int state) {
                this.state = state;
                notifyAllObservers();
            }

            public void attach(Observer observer) {
                observers.add(observer);
            }

            public void notifyAllObservers() {
                for (Observer observer : observers) {
                    observer.update();
                }
            }
        }

        // Observerインターフェース
        abstract class Observer {
            protected Subject subject;
            public abstract void update();
        }

        // ConcreteObserverクラス
        class ConcreteObserver extends Observer {
            public ConcreteObserver(Subject subject) {
                this.subject = subject;
                this.subject.attach(this);
            }

            @Override
            public void update() {
                System.out.println("State updated to: " + subject.getState());
            }
        }

        // メインクラス
        public class ObserverPatternDemo {
            public static void main(String[] args) {
                Subject subject = new Subject();

                new ConcreteObserver(subject);

                System.out.println("First state change: 15");
                subject.setState(15);
            }
        }
    

C++でのObserverパターン実装

以下はC++でのObserverパターンの実装サンプルです。


        #include 
        #include 

        class Observer;

        class Subject {
        private:
            std::vector observers;
            int state;
        public:
            int getState() {
                return state;
            }

            void setState(int state) {
                this->state = state;
                notifyAllObservers();
            }

            void attach(Observer* observer) {
                observers.push_back(observer);
            }

            void notifyAllObservers();
        };

        class Observer {
        protected:
            Subject* subject;
        public:
            virtual void update() = 0;
        };

        class ConcreteObserver : public Observer {
        public:
            ConcreteObserver(Subject* subject) {
                this->subject = subject;
                this->subject->attach(this);
            }

            void update() override {
                std::cout << "State updated to: " << subject->getState() << std::endl;
            }
        };

        void Subject::notifyAllObservers() {
            for (Observer* observer : observers) {
                observer->update();
            }
        }

        int main() {
            Subject subject;

            ConcreteObserver observer(&subject);

            std::cout << "First state change: 15" << std::endl;
            subject.setState(15);

            return 0;
        }
    

C#でのObserverパターン実装

以下はC#でのObserverパターンの実装サンプルです。


        using System;
        using System.Collections.Generic;

        class Subject {
            private List observers = new List();
            private int state;

            public int GetState() {
                return state;
            }

            public void SetState(int state) {
                this.state = state;
                NotifyAllObservers();
            }

            public void Attach(Observer observer) {
                observers.Add(observer);
            }

            public void NotifyAllObservers() {
                foreach (Observer observer in observers) {
                    observer.Update();
                }
            }
        }

        abstract class Observer {
            protected Subject subject;
            public abstract void Update();
        }

        class ConcreteObserver : Observer {
            public ConcreteObserver(Subject subject) {
                this.subject = subject;
                this.subject.Attach(this);
            }

            public override void Update() {
                Console.WriteLine("State updated to: " + subject.GetState());
            }
        }

        class Program {
            static void Main(string[] args) {
                Subject subject = new Subject();

                new ConcreteObserver(subject);

                Console.WriteLine("First state change: 15");
                subject.SetState(15);
            }
        }

VB.NETでのObserverパターン実装

以下はVB.NETでのObserverパターンの実装サンプルです。


        Imports System.Collections.Generic

        Public Class Subject
            Private observers As New List(Of Observer)()
            Private state As Integer

            Public Function GetState() As Integer
                Return state
            End Function

            Public Sub SetState(ByVal value As Integer)
                state = value
                NotifyAllObservers()
            End Sub

            Public Sub Attach(ByVal observer As Observer)
                observers.Add(observer)
            End Sub

            Private Sub NotifyAllObservers()
                For Each observer As Observer In observers
                    observer.Update()
                Next
            End Sub
        End Class

        Public MustInherit Class Observer
            Protected subject As Subject
            Public MustOverride Sub Update()
        End Class

        Public Class ConcreteObserver
            Inherits Observer

            Public Sub New(ByVal subject As Subject)
                Me.subject = subject
                Me.subject.Attach(Me)
            End Sub

            Public Overrides Sub Update()
                Console.WriteLine("State updated to: " & subject.GetState())
            End Sub
        End Class

        Module Program
            Sub Main()
                Dim subject As New Subject()

                Dim observer As New ConcreteObserver(subject)

                Console.WriteLine("First state change: 15")
                subject.SetState(15)
            End Sub
        End Module
    

まとめ

Observerパターンは、オブジェクト間の依存関係を効果的に管理し、リアルタイムの状態変化を他のオブジェクトに伝える強力な手法です。

本記事では、Java、C++、C#、VB.NETの実装例を通じて、その仕組みを具体的に解説しました。

様々なプログラミング言語で活用されるObserverパターンは、特にイベント駆動型のシステムや、リアルタイム性が求められる場面で役立つデザインパターンです。

オブジェクト指向プログラミングにおけるGoFの23のデザインパターン
デザインパターンは、ソフトウェア設計の問題を効果的に解決するための再利用可能な解決策です。本記事では、GoF(Gang ...
タイトルとURLをコピーしました