Реализация паттерна "Слушатель" (observer listener) с использованием интерфейса SplObserver

20.03.2018

Допустим есть курс, на нем есть один лектор/профессор (observer) и множество слушателей / студентов (listener)

Observable.php (Download)

 <?php

  error_reporting(E_ALL);
  ini_set('display_errors', 'On');

  // Основные классы

  /**
  * Абстрактный класс "Наблюдаемый"
  */
  abstract class Observable implements SplSubject
  {
    /**
    * 
    * @var array Наблюдатели
    * 
    */
    protected $_aObservers = [];

    /**
    * Добавление наблюдателя
    * 
    * @param object SplObserver $oObserver
    * 
    * @return object $this
    */
    public function attach(SplObserver $oObserver)
    {
      $id = spl_object_hash($oObserver);
      $this->_aObserver[$id] = $oObserver;
      return $this;
    }

    /**
    * Исключить наблюдателя
    * 
    * @param object SplObserver $oObserver
    * 
    * @return object $this
    */
    public function detach(SplObserver $oObserver)
    {
      $id = spl_object_hash($oObserver);

      if (isset($this->_aObserver[$id]))
      {
        unset($this->_aObserver[$id]);
      }

      return $this;
    }

    /**
    * Оповестить всех наблюдателей
    * 
    * @return object $this
    */
    public function notify()
    {
      foreach ($this->_aObserver as $oObserver)
      {
        $oObserver->update($this);
      }
      
      return $this;
    }
  }


  /**
  * Абстрактный класс "Наблюдатель"
  */
  abstract class Observer implements SplObserver
  {

  }

  //////////////////////////////////////////////////////////////
  
  // Классы примеров
  
  /**
  * Профессор
  */
  class Professor extends Observable
  {
    private $_sString = '';
    
    public function say($sString) 
    {
      $this->_sString = $sString;
      $this->notify();
    }

    public function getString() 
    {
      return $this->_sString;
    }
  }

  /**
  * Студент
  */
  class Student extends Observer
  {
    private $_sName = '';
    
    public function setName($sName) 
    {
      $this->_sName = $sName;
    }
    
    public function update(SplSubject $oProfessor)
    {
      echo '<b>'.$this->_sName.'</b> услышал: "'.$oProfessor->getString().'"<br />';
    }
  }


  $oProfessor = new Professor();
  
  $oStudent1 = new Student();
  $oStudent1->setName('Alex');
  $oProfessor->attach($oStudent1);

  $oStudent2 = new Student();
  $oStudent2->setName('Ivan');
  $oProfessor->attach($oStudent2);

  $oStudent3 = new Student();
  $oStudent3->setName('Sky');
  $oProfessor->attach($oStudent3);


  $oProfessor->say('Тема лекции: ...');



Категории: PHP
Яндекс.Метрика