Наблюдатель (observer). Шаблоны проектирования.

Шаблоны проектирования
https://www.youtube.com/watch?v=CQa6mvz-2oY

Шаблон "Наблюдатель" определяет отношение "один-ко-многим" между объектам таким образом, что при изменении состояния одного объекта происходит автоматическое оповещение и обновление всех зависимых (оповещаемых) объектов.

name = $name;
        $this->damage = $damage;
    }

    /**
     * @inheritDoc
     */
    public function update(SubjectInterface $subject): void
    {
        $subject->takeDamage($this->damage);

        echo $this->name . ' нанес урон в размере ' . $this->damage . PHP_EOL;
    }
}

/**
 * Игрок.
 *
 * @package ITReview
 */
final class Gamer implements SubjectInterface
{
    /**
     * @var string $name Имя.
     */
    private string $name;
    /**
     * @var ObserverInterface[] $observers Наблюдатели.
     */
    private array $observers;
    /**
     * @var int $health Уровень здоровья.
     */
    private int $health;

    /**
     * Конструктор.
     *
     * @param  string  $name  Имя.
     */
    public function __construct(string $name)
    {
        $this->name = $name;

        $this->health = 100;
        $this->observers = [];
    }

    /**
     * @inheritDoc
     */
    public function addObserver(ObserverInterface $observer): void
    {
        array_push($this->observers, $observer);
    }

    /**
     * @inheritDoc
     */
    public function removeObserver(ObserverInterface $observer): void
    {
        foreach ($this->observers as $key => $currentEnemy) {
            if ($currentEnemy == $observer) {
                unset($this->observers[$key]);
                return;
            }
        }
    }

    /**
     * @inheritDoc
     */
    public function notifyObservers(): void
    {
        foreach ($this->observers as $enemy) {
            $enemy->update($this);
        }
    }

    /**
     * Получение урона.
     *
     * @param  int  $damage  Урон.
     */
    public function takeDamage(int $damage): void
    {
        $this->health -= $damage;
    }
}

$gamer = new Gamer('Игрок');

$enemyFirst = new Enemy('Враг 1', 1);
$enemySecond = new Enemy('Враг 2', 2);
$enemyThird = new Enemy('Враг 3', 3);

$gamer->addObserver($enemyFirst);
$gamer->addObserver($enemySecond);
$gamer->addObserver($enemyThird);

$camera = new Camera();
$gamer->addObserver($camera);

$gamer->notifyObservers();

print_r($gamer);

Полезные ссылки


Комментарии (0)

Войдите, чтобы оставить комментарий.