Wzorzec projektowy Observer

Page Title Shape 1
Page Title Shape 2
Page Title Shape 3

Wydaje mi się, że jeden z prostrzych wzorców projektowych, który potrafi przyjść z pomocą, gdy w systemie musimy zaimplementować coś na wzór akcja – reakcja.

Observer wyróżnia dwa podstawowe pojęcia:

  1. Wydawca (eng. publisher), którego zadaniem jest:
    • rejestracja wszystkich obserwatorów, które chcą nasłuchiwać na zdarzenia
    • wyrejestrowanie obserwatorów, którzy nie chcą już nasłuchiwać
    • powiadamianie obserwatorów o zdarzeniach
  2. Obserwator (eng. observer), którego zadaniem jest nasłuchiwanie na zdarzenia z Publishera i podejmowanie konkretnych akcji w ramach tego eventu

Case study

Najłatwiej jak zawsze na przykładzie. Załóżmy, że w systemie opracowujemy system rejestracji użytkownika. Po zarejestrowaniu nowego konta chcemy utworzyć w bazie danych fake’owe dane DEMO. Będą one niezbędne do prezentacji systemu po pierwszym zalogowaniu użytkownika.

Jak to zrobić?

Potrzebujemy do tego celu dwie klasy:

  1. User – będzie odpowiedzialna za tworzenie użytkownika w bazie danych oraz będzie pełniła funkcję Publishera
  2. DemoDataObserver – będzie to nasz Observer

Implementacja w JavaScript

class Publisher {
  constructor(){
    this.observers = [];
  }
  register(observer) {
    this.observers.push(observer);
  }
  unregister(observer) {
    this.obversers = this.observers.filter( registeredObserver => registeredObserver !== observer );
  }
  notify(data, action){
    this.observers.forEach( observer => observer[action](data) );
  }
}

class User extends Publisher {
  create(data){
    console.log('This is create action in User class', data);
    this.notify(data, 'create');
  }
}

class DemoDataObserver {
  create(data){
    console.log('This is create action in DemoDataObserver', data);
  }
}

class OtherObserver {
  create(data){
    console.log('This is create action in OtherObserver', data);
  }
}

const user = new User();
user.register(new DemoDataObserver());
// user.register(new OtherObserver());
user.create({ login: 'email' });

Implementacja w PHP

<?php

class Publisher {
    private $observers = [];
    private $content;
    public function attach($observer) {
        $this->observers[] = $observer;
    }
    public function detach($observer) {
        $key = array_search($observer,$this->observers, true);
        if($key){
            unset($this->observers[$key]);
        }
    }
    public function notify($data, $action) {
        foreach ($this->observers as $value) {
            $value->{$action}($data);
        }
    }
}

class User extends Publisher {
    public function create($data){
        print_r('=== User create action ===');
        print_r($data);
        print_r('=== User create action ===');
        $this->notify($data, 'create');
    }
}

class DemoDataObserver {
    public function create($data){
        print_r('==== DemoDataObserver create action ====');
        print_r($data);
        print_r('==== DemoDataObserver create action ====');
    }
}

class OtherObserver {
    public function create($data){
        print_r('==== OtherObserver create action ====');
        print_r($data);
        print_r('==== OtherObserver create action ====');
    }
}

$user = new User();
$user->attach(new DemoDataObserver());
// $user->attach(new OtherObserver());

$user->create([ 'login' => 'email' ]);
Previous Post
Newer Post

Brak produktów w koszyku.

X