The observer pattern is a well known behaviour pattern where the subject i.e. an object, has a collection of coupled subscribers, also known as observers, the object notifies the subscribers of any changes to the object state. The pattern was popularised 1994. For this review, I’ve used the notion of a pseudo newswire updating new stories to various news readers, these being the observers. We can see objects being notified when state changes in the subject. Source code below.

Implementation Code


/**
 * Observer (pub/sub) Pattern Implementation
 */
require_once '../vendor/FigStandards/autoload.php';

//Load Dependencies 
$loader = new figStandards\Psr4AutoloaderClass;
$loader->register();
$loader->addNamespace('newsWire', 'newsWire');

class Client {

    public function __construct() {
        
        $newsWire = new newsWire\newsWire();

        //instantiate the readers
        $reader1 = new newsWire\reader($newsWire);
        $reader2 = new newsWire\reader($newsWire);
        
   
        //attach the readers to the newsWire
        $newsWire->attach($reader1);
        $newsWire->attach($reader2);
               
        echo "

Observer / Subject state to deterine caching.

"; //create some stories for the wire $newsWire->create(new newsWire\story('1', 'My first webpage served entirely on IPFS in no time', 'https://codesnippetsandtutorials.com/2022/09/22/my-first-webpage-served-entirely-on-ipfs-in-no-time/', date('d-m-Y'))); $reader1->display(); $newsWire->create(new newsWire\story('2', 'Creating a Gmail Desktop App in Air and Javascript', 'https://codesnippetsandtutorials.com/2022/09/22/creating-a-gmail-desktop-app-in-air-and-javascript/', date('d-m-Y'))); $reader1->display(); $reader1->display(); $reader2->display(); $reader2->display(); } } new Client();

Story -> Newswire



/**
 * Observer Pattern Implementation Example.
 * 
 */

namespace newsWire;

class story {

    private $id;
    private $headline;
    private $url;
    private $date;

    public function __construct($id, $headline, $url, $date) {
        $this->id = $id;
        $this->headline = $headline;
        $this->url = $url;
        $this->date = $date;
    }

}


NewsWire -> Subject




/**
 * Observer Pattern Implementation Example.
 */

namespace newsWire;

class newsWire extends \newsWire\subject {

    private $newswire = array();

    public function create($story) {
        $this->newswire[] = $story;
        $this->state++;
    }

    public function remove($id) {
        unset($this->newswire[$id]);
    }
    
    public function getHeadlines() { 
        return $this->newswire;
    }

}



Abstract Subject




/**
 * Observer Pattern Implementation Example.
 */

namespace newsWire;

abstract class subject {

    protected $state = 0;
    private $observers = array();

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

    public function detach() {
        
    }

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

}


DataType Abstract Class



namespace bridge;

abstract class DataType {

     protected $data;
    
    /**
     * Implementation specific contents assignment to object
     * 
     * @param type $contents
     */
    abstract protected function __construct(string $contents);

    /**
     * Implementation specific Heuristic specific parser
     */
    protected function sanitise(): Array {
        preg_match_all("/(\w+)/", $this->data, $matches);
        return $matches[0];
    }
}

NewsReader Class



/**
 * Observer Pattern Implementation Example.
 * 
 */

namespace newsWire;

class reader {

    private $cache;
    private $lastState = 0;
    private $subject;

    /**
     * 
     * @param type $subject
     */
    public function __construct($subject) {

        //assign the subject to the observer
        $this->assignState($subject);
    }

    /**
     * Display the relevant headlines 
     */
    public function display() {

        echo $this->subject->getState() . '
'; echo $this->lastState . '
'; if ($this->checkstate()) { echo "

Get's Cached Headlines

"; print_r($this->getCache()); } else { echo "

Get's Live Headlines

"; print_r($this->getLatest()); } } /** * Check Status Conditional * @return bool */ public function checkstate(): bool { return ($this->subject->getState() <= $this->lastState); } /** * * @param type $subject */ public function assignState($subject) { $this->subject = $subject; } /** * * @return type */ public function currentState() { return $this->subject->getState(); } /** * */ public function getLatest() { $this->updateCount(); $this->updateCache(); return $this->subject->getHeadlines(); } /** * */ public function updateCount() { $this->lastState = $this->subject->getState(); } /** * */ public function updateCache() { $this->cache = $this->subject->getHeadlines(); } /** * */ public function getCache() { return $this->cache; } }