PHP面向对象的设计模式-观察者模式

2023-04-28 16:19:59 浏览数 (1)

一、概述

观察者模式是一种行为设计模式,它定义了对象之间的一种一对多的依赖关系,当一个对象状态发生改变时,所有依赖它的对象都将得到通知并自动更新。这种模式也叫做发布-订阅模式,它能够解决对象之间的耦合关系。

观察者模式有三个角色:Subject(主题)、Observer(观察者)和ConcreteObserver(具体观察者)。Subject是被观察的对象,当它的状态发生改变时,会通知所有观察它的对象。Observer是观察者,它定义了接收通知的接口,所有观察者都实现这个接口。ConcreteObserver是具体的观察者,它实现了Observer接口,当Subject的状态发生改变时,它会接收到通知并作出相应的处理。

观察者模式的优点是可以实现松耦合,即Subject和Observer之间的耦合度很低,它们可以独立地改变而不会影响到对方。此外,观察者模式还支持广播通信,即Subject可以同时通知多个Observer。

二、示例

下面是一个使用观察者模式的示例。假设有一个天气主题,它会随着天气的变化通知所有的观察者。观察者可以是显示天气的页面或者是发送短信的手机应用程序。

定义Subject接口

首先,我们需要定义Subject接口,它定义了注册、移除和通知观察者的方法:

代码语言:javascript复制
interface Subject
{
    public function registerObserver(Observer $observer);
    public function removeObserver(Observer $observer);
    public function notifyObservers();
}

定义Observer接口

接下来,我们定义Observer接口,它定义了接收通知的方法:

代码语言:javascript复制
interface Observer
{
    public function update($temperature, $humidity, $pressure);
}

实现具体的Subject

然后,我们实现具体的Subject类,它维护了一个观察者列表,当它的状态发生改变时,会通知所有观察者::

代码语言:javascript复制
class WeatherData implements Subject
{
    private $observers;
    private $temperature;
    private $humidity;
    private $pressure;
    
    public function __construct()
    {
        $this->observers = array();
    }
    
    public function registerObserver(Observer $observer)
    {
        $this->observers[] = $observer;
    }
    
    public function removeObserver(Observer $observer)
    {
        $key = array_search($observer, $this->observers, true);
        if ($key !== false) {
            unset($this->observers[$key]);
        }
    }
    
    public function notifyObservers()
    {
        foreach ($this->observers as $observer) {
            $observer->update($this->temperature, $this->humidity, $this->pressure);
        }
    }
    
    public function measurementsChanged()
    {
        $this->notifyObservers();
    }
    
    public function setMeasurements($temperature, $humidity, $pressure)
    {
        $this->temperature = $temperature;
        $this->humidity = $humidity;
        $this->pressure = $pressure;
        $this->measurementsChanged();
    }
}

实现具体的Observer

最后,我们实现具体的Observer类,它实现了Observer接口的update方法,当它接收到通知时,会更新自己的状态:

代码语言:javascript复制
class CurrentConditionsDisplay implements Observer
{
    private $temperature;
    private $humidity;
    private $pressure;
    private $weatherData;
    
    public function __construct(Subject $weatherData)
    {
        $this->weatherData = $weatherData;
        $this->weatherData->registerObserver($this);
    }
    
    public function update($temperature, $humidity, $pressure)
    {
        $this->temperature = $temperature;
        $this->humidity = $humidity;
        $this->pressure = $pressure;
        $this->display();
    }
    
    public function display()
    {
        echo "Current conditions: " . $this->temperature . "F degrees and " . $this->humidity . "% humidityn";
    }
}

在这个示例中,WeatherData类是Subject,它维护了一个观察者列表,并实现了注册、移除和通知观察者的方法。CurrentConditionsDisplay类是具体的观察者,它实现了Observer接口的update方法,当它接收到通知时,会更新自己的状态并调用display方法显示当前的天气信息。

使用观察者模式的主要步骤如下:

  1. 定义Subject接口,其中包含注册、移除和通知观察者的方法。
  2. 定义Observer接口,其中包含接收通知的方法。
  3. 实现具体的Subject类,维护观察者列表,并实现注册、移除和通知观察者的方法。
  4. 实现具体的Observer类,实现接收通知的方法并更新自己的状态。
  5. 在主程序中,创建具体的Subject和Observer对象,将Observer对象注册到Subject对象中,当Subject的状态发生改变时,通知所有注册的Observer对象。
php

0 人点赞