バックエンド

PHPデザインパターン:Observerパターンの解説と実装例

PHPで開発を行っていると、オブジェクト同士の依存関係を効率的に管理する必要が出てくることがあります。Observer(オブザーバー)パターンは、そのようなシナリオで役立つデザインパターンの一つです。本記事では、Observerパターンの概要、実際のコード例、そしてその適用シーンについて解説します。

Observerパターンとは?

Observerパターンは「行動に応じた通知」を効率的に行うデザインパターンです。一つのオブジェクト(Subject)が状態を更新すると、それに依存する他のオブジェクト(Observers)に通知が送られます。この仕組みは、新聞の購読モデルになぞらえると理解しやすいです。

特徴:

  • 一対多の依存関係を管理。
  • 状態変更を観測して通知を送信。
  • ソフトウェアの柔軟性を高める。

実装例

以下に、シンプルなObserverパターンの実装例を示します。

1. インターフェースの定義

まず、ObserverとSubjectのインターフェースを定義します。

interface Observer {
    public function update(string $message): void;
}

interface Subject {
    public function attach(Observer $observer): void;
    public function detach(Observer $observer): void;
    public function notify(): void;
}

2. Subjectクラスの実装

Subjectは、Observerを登録・削除し、状態が変わったときに通知を送る役割を持ちます。

class NewsPublisher implements Subject {
    private array $observers = [];
    private string $latestNews;

    public function attach(Observer $observer): void {
        $this->observers[] = $observer;
    }

    public function detach(Observer $observer): void {
        $this->observers = array_filter(
            $this->observers,
            fn($o) => $o !== $observer
        );
    }

    public function notify(): void {
        foreach ($this->observers as $observer) {
            $observer->update($this->latestNews);
        }
    }

    public function publishNews(string $news): void {
        $this->latestNews = $news;
        $this->notify();
    }
}

3. Observerクラスの実装

Observerは通知を受け取ったときに特定のアクションを実行します。

class EmailSubscriber implements Observer {
    private string $email;

    public function __construct(string $email) {
        $this->email = $email;
    }

    public function update(string $message): void {
        echo "Sending email to {$this->email}: {$message}\n";
    }
}

class SMSSubscriber implements Observer {
    private string $phoneNumber;

    public function __construct(string $phoneNumber) {
        $this->phoneNumber = $phoneNumber;
    }

    public function update(string $message): void {
        echo "Sending SMS to {$this->phoneNumber}: {$message}\n";
    }
}

4. 使用例

実際に動かしてみましょう。

$newsPublisher = new NewsPublisher();

$emailSubscriber = new EmailSubscriber("example@example.com");
smsSubscriber = new SMSSubscriber("123-456-7890");

$newsPublisher->attach($emailSubscriber);
$newsPublisher->attach($smsSubscriber);

$newsPublisher->publishNews("Observerパターンについての記事が公開されました!");

実行結果

Sending email to example@example.com: Observerパターンについての記事が公開されました!
Sending SMS to 123-456-7890: Observerパターンについての記事が公開されました!

Observerパターンを使うべきケース

Observerパターンは、以下のようなケースで有効です。

  • イベント駆動型のアプリケーション: 状態変更をトリガーにした処理が必要な場合。
  • 通知機能: メールやプッシュ通知などを柔軟に管理したい場合。
  • モジュール間の独立性を高めたい場合: 依存関係を疎結合にしたいとき。

注意点とベストプラクティス

  • Observerの数に注意: 多すぎるとパフォーマンスに影響を及ぼす可能性があります。
  • 責務の分離: SubjectとObserverの役割を明確にすることで、コードの保守性を向上させましょう。
  • ユニットテスト: 各クラスが期待どおりに動作するか確認するテストを書くことをお勧めします。

まとめ

Observerパターンは、オブジェクト間の依存関係を効率的に管理し、システムの柔軟性を向上させる強力な手段です。本記事の内容を参考に、実際のプロジェクトで活用してみてください。

-バックエンド
-,