Home > Backend Development > PHP Tutorial > Understanding the Observer Pattern

Understanding the Observer Pattern

Jennifer Aniston
Release: 2025-02-28 09:14:19
Original
987 people have browsed it

Understanding the Observer Pattern

Core points

  • Observer pattern is a behavioral design pattern that establishes a one-to-many relationship between objects. When an object changes its state, all dependent objects will be automatically notified and updated.
  • This mode contains a topic (or publisher) and observer (or subscriber). The subject informs the observer of any change in status and the observer can act accordingly. This mode promotes loose coupling, making the system more flexible and easier to modify or expand.
  • The Observer class provides a
  • method that the subject calls to inform its state changes. The main methods of defining topic classes: update(), attach(), detach(), and setState() are used to manage observers and notify them of status changes. notify()
  • Observer mode is suitable for situations where changes to one object require changes to other objects, especially if the number of objects to be changed is unknown. It can be used to maintain consistency between related objects without tightly coupling them. For example, it is used to link the portal's authentication mechanism with forum software, allowing users to log in to both with a single login.
I was recently asked to integrate third-party forum software into my existing web portal. The problem is that both applications have their own independent authentication mechanisms. From the user's perspective, ideally, users can log in to the portal without having to log in to the forum separately. In this case, I don't want to modify the forum code unnecessarily as this creates maintenance nightmare-I have to merge any subsequent updates and bug fixes from the vendor and be careful to avoid overwriting my own modifications. This is where the Observer mode is very convenient for me. In this article, I will show you how to implement the observer pattern. You will learn how various classes in the pattern are related to each other as topics and observers, how topics inform the observer of changes in their state, and how to identify scenarios suitable for using the observer pattern in your own code.

Observer mode

Observer pattern (also known as publish-subscribe pattern) is a behavioral design pattern that defines one-to-many relationships between objects so that when an object changes its state, all dependent objects are automatically notified and updated. In my case, I used this mode to link the authentication mechanism of the portal with the forum software. The behavior of logging into the portal will also automatically trigger the user to log into the forum. Objects that have a one-to-many relationship with other objects interested in their own state are called

topic or Publisher . Its dependency object is called the observer or the subscriber. Whenever the state of the subject changes, the observer is notified and can act accordingly. A topic can have any number of dependent observers that will send notifications to those observers, and any number of observers can subscribe to the topic to receive such notifications.

Observer categoryThe Observer class provides a

method that the subject will call to inform its state changes. In this example, I have defined the update() method as a specific method. If you want, you can define the method as an abstract method here and then provide a concrete implementation for it in the observer's subclass. update()

<?php
abstract class Observer
{
    public function __construct($subject = null) {
        if (is_object($subject) && $subject instanceof Subject) {
            $subject->attach($this);
        }
    }

    public function update($subject) {
        // 查找具有状态名称的观察者方法
        if (method_exists($this, $subject->getState())) {
            call_user_func_array(array($this, $subject->getState()), array($subject));
        }
    }
}
Copy after login
Copy after login

Method accepts instances of observable topics and attaches itself to the topic—I will talk about it later. The __construct() method retrieves the current state of the topic and uses it to invoke a subclassed observer method with the same state name. So in my specific case, I need to make the existing Auth class of the portal as an observable topic and create a concrete observer subclass to connect to the authentication code of the forum. My subclass also needs to implement the method using the state of the topic. update()

Theme category The subject class is also an abstract class, which defines four main methods:

,

, attach(), detach() and setState(). For convenience, I also added the notify() and getState() methods here. getObservers()

<?php
abstract class Subject
{
    protected $observers;
    protected $state;

    public function __construct() {
        $this->observers = array();
        $this->state = null;
    }

    public function attach(Observer $observer) {
        $i = array_search($observer, $this->observers);
        if ($i === false) {
            $this->observers[] = $observer;
        }
    }

    public function detach(Observer $observer) {
        if (!empty($this->observers)) {
            $i = array_search($observer, $this->observers);
            if ($i !== false) {
                unset($this->observers[$i]);
            }
        }
    }

    public function getState() {
        return $this->state;
    }

    public function setState($state) {
        $this->state = $state;
        $this->notify();
    }

    public function notify() {
        if (!empty($this->observers)) {
            foreach ($this->observers as $observer) {
                $observer->update($this);
            }
        }
    }


    public function getObservers() {
        return $this->observers;
    }
}
Copy after login

Method subscribes the observer to a topic so that any state changes can be communicated to it. The attach() method unsubscribes the observer from the topic so that it no longer observes the state changes of the topic. The detach() method sets the current state of the topic and calls setState() to update the observer, that is, to issue a notification to each observer. The notify() methods update each subscribed object by iterating through the internal list and calling the notify() method of each member in turn. The update() and getState() methods are just helper functions that return the status of the current topic and the observer list. getObservers()

Add carefully...integrate together

Now with the abstract base class for observers and topics, I was able to integrate the forum software into my existing web portal. I need to set the Auth class of the portal to be observable topic and set its observable state when the user logs in or logs out of the portal.

<?php
class Auth extends Subject
{
    function login() {
        // 执行登录身份验证的现有代码
        // ...

        // 向任何观察者发出信号,表明用户已登录
        $this->setState("login");
    }

    function logout() {
        // 执行用户注销时执行某些操作的现有代码
        // 例如销毁会话等...

        // 向任何观察者发出信号,表明用户已注销
        $this->setState("logout");
    }
}
Copy after login
I extended the Subject class so that Auth can be observable, and then added a call to

in the login() and logout() methods. To subclass the observer, I created an Auth_ForumHook class that is responsible for calling the forum's API login and logout functions. setState()

<?php
class Auth_ForumHook extends Observer
{
    function login($subject) {
        // 调用论坛的 API 函数以登录用户
        // ...
    }

    function logout($subject) {
        // 调用论坛的 API 函数以注销用户
        // ...
    }
}
Copy after login
Others in the code base, where the Auth class in the portal is instantiated, I attach the Auth_ForumHook instance to it so that the observer will be notified of any state changes in Auth.

<?php
abstract class Observer
{
    public function __construct($subject = null) {
        if (is_object($subject) && $subject instanceof Subject) {
            $subject->attach($this);
        }
    }

    public function update($subject) {
        // 查找具有状态名称的观察者方法
        if (method_exists($this, $subject->getState())) {
            call_user_func_array(array($this, $subject->getState()), array($subject));
        }
    }
}
Copy after login
Copy after login

This is all my extra coding needs besides preparing abstract Observer and Subject classes. Any state changes triggered by Auth's login() and logout() methods will notify the Auth_ForumHook observer and automatically log in or log out of the user in the forum. To add a new observer, for example, to log in to the tracker to record when a user logs in or logs out of the portal, simply provide a specific Observer class and attach it to the Auth topic without further modifying the login() and logout() methods of the existing Auth object.

Summary

If you have multiple objects that depend on another object and need to perform operations when the state of that object changes, or one object needs to notify other objects without knowing who or how many they are, then Observer pattern is a suitable and applicable design pattern. In this article, I show you the basic topic-observer pattern and provide concrete examples of how to easily extend the functionality of an existing class using this behavior pattern without tightly coupling any new requirements. This pattern allows you to achieve a higher level of consistency between related and dependent objects without sacrificing the reusability of your code.

Pictures from JPF / Shutterstock

(The subsequent FAQs section has been omitted due to the length of the article. The core content has been reorganized and polished on it.)

The above is the detailed content of Understanding the Observer Pattern. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template