Спостерігач (Behavior)


Аналогія

Хороший приклад: люди, які шукають роботу, підписуються на публікації на сайтах вакансій та отримують повідомлення, коли з'являються вакансії, які підходять за параметрами.

Стисло

Шаблон визначає залежність між об'єктами, щоб за зміни стану одного з них його «підлеглі» дізнавалися про це.

Вікіпедія

У шаблоні «Спостерігач» є об'єкт («суб'єкт»), що веде список своїх «підлеглих» («спостерігачів») і автоматично повідомляє їх про будь-яку зміну свого стану, як правило, за допомогою виклику одного з їх методів .

Приклад

Спочатку реалізуємо людей, які шукають роботу, яких потрібно повідомляти про появу вакансій.

class JobPost
{
    protected $title;

    public function __construct(string $title)
    {
        $this->title = $title;
    }

    public function getTitle()
    {
        return $this->title;
    }
}

class JobSeeker implements Observer
{
    protected $name;

    public function __construct(string $name)
    {
        $this->name = $name;
    }

    public function onJobPosted(JobPost $job)
    {
        // Do something with the job posting
        echo 'Hi'. $this->name . '! New job posted: '. $job->getTitle();
    }
}

Тепер реалізуємо публікації вакансій, на які люди будуть підписуватись.

class JobPostings implements Observable
{
    protected $observers = [];

    protected function notify(JobPost $jobPosting)
    {
        foreach ($this->observers as $observer) {
            $observer->onJobPosted($jobPosting);
        }
    }

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

    public function addJob(JobPost $jobPosting)
    {
        $this->notify($jobPosting);
    }
}

Використання:

// Створюємо передплатників
$johnDoe = новий JobSeeker('John Doe');
$janeDoe = новий JobSeeker('Jane Doe');

// Створюємо публікатора та прикріплюємо передплатників
$jobPostings = New JobPostings();
$jobPostings->attach($johnDoe);
$jobPostings->attach($janeDoe);

// Додаємо нову вакансію та дивуємося, чи будуть повідомлені передплатники
$jobPostings->addJob(new JobPost('Software Engineer'));

// Output
// Hi John Doe! New job posted: Software Engineer
// Hi Jane Doe! New job posted: Software Engineer