Паттерн Спостерігач (Observer) в PHP

Мітки: patterns, php, observer

Паттерн Наблюдатель (Observer) в PHP Паттерн Наблюдатель (Observer) в PHP
Observer pattern in PHP Observer pattern in PHP

Зовсім недавно я просто закохався в шаблон проектування observer. Ви можете з легкістю побудувати повний додаток, використовуючи неймовірну міць програмування управлінь подіями. Що саме представляє з себе паттерн спостерігач? Вся теорія доступна на Вікіпедії. Говорячи простою мовою, у нас є об'єкт, за яким ми хочемо моніторити (спостерігати) на предмет якихось змін. Більшість часу цей об'єкт просто звільняє події і ми хочемо прослуховувати їх. Ми можемо мати багато об'єктів прослуховуючих один або багато інших об'єктів, простіше кажучи, це може бути відносини багато до багатьох. Класичний приклад у світі баз даних це тригери. Наприклад, коли таблиця була оновлена, тригер, що прослуховує, звільняється. У віконних додатках, коли користувач натискає на кнопку, події звільняються і ті що прослуховують повідомляються для керування подією. У наступному прикладі ми маємо об'єкт валідатору, який перевіряє валідність e-mail адреси, звільняються два типи подій, які б ми хотіли прослуховувати. Ці типи, ясна річ, дійсний / не дійсний e-mail адресу. Ми також оголосимо двох слухачів, по одному на кожний з типів подій, слухаючих валідатор. Перший буде просто деяким логгером помилок, записувати невірні спроби введення, і другий буде записувати коректний e-mail адрес в базу даних або інше місце. Ми почнемо з опису нашого інтерфейсу для об’єкту спостереження. Ми просто хочемо додати спостерігачів та звільнити події. Також ми хочемо мати можливість прослуховувати тільки певні типи подій, значить, у нас немає необхідності сповіщати спостерігачів не слухати подію, яка тільки що звільнилася.
Прибрати підсвітку коду
1
2
3
4
5
6
<?php
interface IObservable
{
  public function addObserver( IObserver $objObserver, $strEventType );
  public function fireEvent( $strEventType );
}

Отже, будь-який об'єкт, який ми хочемо спостерігати, повинен описувати інтерфейс IObservable. Давайте опишемо, як має виглядати спостерігач. По простому, спостерігачеві необхідно лише знати, що об'єкт звільнив подію і тип цієї події, значить, вона може бути оброблена.
Прибрати підсвітку коду
1
2
3
4
5
<?php
interface IObserver
{
  public function notify( IObservable $objSource, $objArguments );
}

Зараз ми зробимо наш e-mail валідатора, який описує інтерфейс IObservable і визначає два типи подій.
Прибрати підсвітку коду
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?php
class EmailValidator implements IObservable
{
  const EVENT_EMAIL_VALID = 1;
  const EVENT_EMAIL_INVALID = 2;
 
  protected $strEmailAddress;
 
  protected $aryObserversArray;
 
  public function __construct( $strEmailAddress )
  {
    $this->strEmailAddress = $strEmailAddress;
    $this->aryObserversArray = array( array() );
  }
 
  public function setEmailAddress( $strEmailAddress )
  {
    $this->strEmailAddress = $strEmailAddress;
  }
 
  public function getEmailAddress()
  {
    return $this->strEmailAddress;
  }
 
  public function validate()
  {
    if( preg_match( '/^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@'.
'[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$/',
        $this->strEmailAddress ) )
    {
      $this->fireEvent( EmailValidator::EVENT_EMAIL_VALID );
    }
    else
    {
      $this->fireEvent( EmailValidator::EVENT_EMAIL_INVALID );
    }
  }
 
  public function addObserver( IObserver $objObserver, $strEventType )
  {
    $this->aryObserversArray[$strEventType][] = $objObserver;
  }
 
  public function fireEvent( $strEventType )
  {
    if( is_array( $this->aryObserversArray[$strEventType] ) )
    {
      foreach ( $this->aryObserversArray[$strEventType] as $objObserver )
      {
        $objObserver->notify( $this, $strEventType );
      }
    }
  }
}

Метод, який виконує всю роботу - це validate(). Він просто перевіряє отриманий e-mail та звільняє валідну або невалідну подію.
Це все, про решту піклуються спостерігачі. Давайте зробимо двох спостерігачів, кожен з яких буде слухати різні типи подій. Це спостерігач ErrorLogger, який буде сповіщені кожен раз, коли e-mail, що перевіряється, не дійсний. Він може писати щось в лог або просто попереджувати користувача.
Прибрати підсвітку коду
1
2
3
4
5
6
7
8
9
10
11
12
<?php
class ErrorLogger implements IObserver
{
  public function notify( IObservable $objSource, $strEventType )
  {
    if( $strEventType == EmailValidator::EVENT_EMAIL_INVALID && $objSource instanceof EmailValidator )
    {
      printf( 'Помилка:% s невалідний email',
             $objSource->getEmailAddress() );
    }
  }
}

Просто, чи не так. ErrorLogger тільки описує метод notify () і перевіряє чи подія являється EmailValidator і тип цієї події EVENT_EMAIL_INVALID, а потім пише повідомлення про помилку. Спостерігач для EVENT_EMAIL_VALID виглядає дуже схоже.
Прибрати підсвітку коду
1
2
3
4
5
6
7
8
9
10
11
12
<?php
class DatabaseWriter implements IObserver
{
  public function notify( IObservable $objSource, $strEventType )
  {
    if( $strEventType == EmailValidator::EVENT_EMAIL_VALID && $objSource instanceof EmailValidator )
    {
      printf('Email адреса %s дійсна і була записана до бази даних',
             $objSource->getEmailAddress() );
    }
  }
}

Це воно. Тепер нам всього лише необхідно створити наш об'єкт EmailValidator, додати деяких спостерігачів і дати їм кілька e-mail адрес на перевірку.
Прибрати підсвітку коду
1
2
3
4
5
6
7
8
<?php
$objValidator = new EmailValidator( 'valid@email.com' );
$objValidator->addObserver( new ErrorLogger(), EmailValidator::EVENT_EMAIL_INVALID );
$objValidator->addObserver( new DatabaseWriter(), EmailValidator::EVENT_EMAIL_VALID );
$objValidator->validate();
 
$objValidator->setEmailAddress( 'not_a_valid_address' );
$objValidator->validate();

Виконавши ці приклади, повинен вийти приблизно такий результат:
Прибрати підсвітку коду
1
2
Помилка: not_a_valid_address невалідний email. 
Email адреса valid@email.com Дійсний і було записано в базу даних

Це був лише простий приклад, що демонструє міць паттерну спостерігач. Я впевнений, що ви знайдете багато застосувань для нього.

Оригінал: Observer pattern in PHP

Рейтинг: 12345   << Ви можете поставити оцінку цій статті


Подібні статті:
   Паттерн кешування для моделей
   Робота з форматами стиснення RAR, LZF і Bz2 в PHP
   MVC в невеликих web-додатках


Обговорення статті:

 
GrAndSE [2009-08-26]
Чудова стаття. Нажаль, дуже мало php-програмістів користуються патернами проектування :(


Ігор [2010-11-28]
Дякую. Стаття сподобалась!


SET [2011-06-15]
Статьи по программированию на украинском выглядят так "дыбильно"


Вася [2014-08-07]
SET ты дыбильно даже правильно написать не можешь поєтому ты как раз дебильно и выглядишь..


Вася [2014-08-07]
SET ты дыбильно даже правильно написать не можешь поєтому ты как раз дебильно и выглядишь..


Вася [2014-08-07]
SET ты дыбильно даже правильно написать не можешь поєтому ты как раз дебильно и выглядишь..


Вася [2014-08-07]
А где копирайт статьи? Єто перевод статьи с сайта зенда..


Сергей [2014-08-07]
Вася, ну вот кому какое дело до этого? Мне лично вообще все равно


Ponchikzef [2015-09-20]
Здравствуйте!
binary option signals
два стохастика в бинарных опционах
рейтинг торговых платформ бинарных опционов
графики бинарных опционов

http://mirkupon.ru/chto-luchshe-binarnye-opcio ny-ili-foreks.php
http://tvtmz.ru/binarnye-opciony-stati.php
http://finmobile.ru/tehnicheskoe-rezume-binarn yh-opcionov.php


Antonyzef [2015-10-10]
Здравствуйте!

прайс экшен бинарные опционы
бинарные опционы юрий орлов отзывы
математическая стратегия бинарных опционов

http://mustachestudio.ru/luchshie-brokery-bina rnyh-opcionov-v-rossii.php
http://mustachestudio.ru/analitiki-binarnyh-op cionov.php

100 бинарные опционы

http://sablinov.ru/binarnye-opciony-torgovlya- akciyami.html


Slava [2016-01-03]
Дякую за переклад! дуже приємно читати на українській, кацапська гавном смердить


 

Залишити коментар:

Ім'я


E-mail


Повідомлення