PHP design pattern|Observer pattern (Observer) analysis and application

【Structure of Observer Mode】

concept

(Observer), first there must be a role to be observed, but ta is [the only]. Although there is only one "performer", there are many "audiences", a group of "people" watching one "person". Since there are countless observers, then we need to know who are there. So we need a "container" to record these "people", a container similar to an array to store all observers.

An "actor" (observed), a group of "audiences" (observers), a "camera" (recording container)

★[ My php advanced learning exchange community "click" ] Manage prepared community-specific information: BAT and other first-line companies advanced knowledge system (related learning materials and written interview questions) and not limited to: distributed architecture, high Scalable, high performance, high concurrency, server performance tuning, TP6, laravel, YII2, Redis, Swoole, Swoft, Kafka, Mysql optimization, shell script, Docker, microservices, Nginx and other knowledge points, advanced advanced dry goods

[Main role in the observer mode]

  1. Abstract subject (Subject) role: The subject role stores all references to observer objects in a collection, and each subject can have any number of observers. Abstract themes provide an interface for adding and deleting observer objects.
  2. Abstract observer (Observer) role: define an interface for all specific observers, update themselves when the subject of observation changes.
  3. Concrete Subject (ConcreteSubject) role: Store the relevant state to the specific observer object, when the internal state of the specific subject changes, notify all registered observers. Specific theme roles are usually implemented by a specific subclass.
  4. Concrete observer (ConcretedObserver) role: store a specific subject object, store related state, and implement the update interface required by the abstract observer role, so that its own state is consistent with the state of the subject.

【scenes to be used】

Suppose that the project manager asked us to write a login interface, and it is finished.

  • The next day, let’s add the number of login counts, and then add the code behind
  • On the third day, let us determine the landing area and add the code at the back
  • On the fourth day, let us push the activity after the user logs in, and then add the code later
  • On day N, this interface is so messy that no one wants to maintain it

We need to keep the project with high cohesion and low coupling, and then we can use the observer mode (not necessary, see requirements)

[Observer mode and other modes]

1. [Mediator mode] (Mediator): By encapsulating complex update semantics, ChangeManager acts as a mediator between the target and the observer.
2. [Singleton mode] (singleton mode): ChangeManager can use Singleton mode to ensure that it is unique and globally accessible.

Code example

  • Interface example
// 主题接口
interface Subject{
    public function register(Observer $observer);
    public function notify();
}
// 观察者接口
interface Observer{
    public function watch();
}

Subject is the observed, Observer is the audience, which is the observer

Observed

// 被观察者
class Action implements Subject{
     public $_observers=array();
     public function register(Observer $observer){
         $this->_observers[]=$observer;
     }
 
     public function notify(){
         foreach ($this->_observers as $observer) {
             $observer->watch();
         }
 
     }
 }

Action implements the Observer interface, he is now the Observer, and then defines a $_observers array, he is the container for recording the audience.

First implement the register method, use it to pass in an observer, then stuff it into the array, and then implement the notify() method, which will traverse the container array and execute the watch() method of each observer.

Observer

// 观察者
class Cat implements Observer{
     public function watch(){
         echo "Cat watches TV<hr/>";
     }
 }
 class Dog implements Observer{
     public function watch(){
         echo "Dog watches TV<hr/>";
     }
 }
 class People implements Observer{
     public function watch(){
         echo "People watches TV<hr/>";
     }
 }

Three observers are defined here, all of which implement the Observer interface. The previous Subject will cyclically call the watch() method of each observer, so we need to implement the watch() method of each observer.

transfer

// 应用实例
$action=new Action();
$action->register(new Cat());
$action->register(new People());
$action->register(new Dog());
$action->notify();

First, the new observed object executes its register() method, puts each observer into the container array, and finally executes the notify() method to notify all observers to execute their own methods.

PHP's native observer mode

PHP has its own observer mode

  • splsubject interface-Observed

  • Observer interface-observer

  • SplObjectStorage object-container

First we have a user login class

class user{

  public function login()
  {
      echo '登录完毕'
  }

Let him implement the splsubject interface to become the observed.

  • First of all, in the constructor, let him new SplObjectStorag () object and assign it to the property to facilitate subsequent calls

  • Implement the attach() method to register observers

  • Implement the detach() method to delete the observer

  • Implement the notify() method to traverse the container and call the update method of each observer (must be update)

  • The rewind method is to reset the container pointer to the very beginning, the valid method detects whether the traversal of the container is completed and returns a boolean, the current method is to obtain the current observer, and the next method is to move the pointer back one place

  • Modify the login() method, call notify() inside to notify the observer that the event is complete

class user implements splsubject{

    protected $observer = null;

    public function __construct()
    {
        $this->observer = new SplObjectStorage();
    }

    public function login()
    {
        $this->notify();
        echo '登录完毕';
    }

    public function attach(SplObserver $observer)
    {
        $this->observer->attach($observer);
    }

    public function detach(SplObserver $observer)
    {
        $this->observer->detach($observer);
    }

    public function notify()
    {
        $this->observer->rewind();
        while ($this->observer->valid())
        {
            $observer = $this->observer->current();
            $observer->update($this);
            $this->observer->next();
        }
    }
}

Observer

Each observer implements the SplObserver interface and implements the update() method

class cat implements SplObserver {

    public function update(SplSubject $subject)
    {
        echo '小猫叫一下';
    }
}
class dog implements SplObserver {
    public function update(SplSubject $subject)
    {
        echo '小狗吼一声';
    }
}

application

// 实时观察
$user = new user();
$user->attach(new cat());
$user->attach(new dog());
$user->login();

PHP Internet Architect 50K Growth Guide + Industry Problem Solving Guide (Continuous Update)

Interview with 10 companies, get 9 offers, PHP interview questions in 2020

★If you like my article and want to communicate and learn with more senior developers, get more technical consultation and guidance related to interviews with major companies. Welcome to join our group-click here .

Guess you like

Origin blog.csdn.net/weixin_43814458/article/details/108089183