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パターンは、特にイベント駆動型のシステムや、リアルタイム性が求められる場面で役立つデザインパターンです。
