Как мы видели в предыдущей статье, шаблоны проектирования - это способ стандартизации реализации ресурсов в наших приложениях. Мы увидели, что если проблемы остаются неизменными, мы можем придерживаться того же подхода к их решению.

Сегодня мы рассмотрим шаблон Наблюдатель. Наблюдатель - это способ позволить объекту обратить внимание на состояние другого объекта и получать обновления при каждом изменении его состояния. Итак, мы работаем с двумя столпами: наблюдатель, который смотрит и ждет изменений, и наблюдаемое, которое будет в центре внимания.

Работа с ситуацией

Еще раз, давайте работать прямо над ситуацией. BloatStore - гигант электронной коммерции. На своем сайте клиент может подписаться на получение электронного письма каждый раз, когда появляется новая распродажа. Их ИТ-команда получила информацию о распродаже в Черную пятницу, и ей нужно было найти решение, чтобы уведомить клиентов о том, что распродажа началась.

Они решили использовать шаблон Наблюдатель, где наблюдателем будет класс Client, а наблюдаемым - класс Sale. Они заметили, что классу Sales потребуются две вещи: массив для приема наблюдателей и метод для их добавления в этот массив. Но в то же время здесь есть небольшая оговорка. Было бы лучше, если бы мы могли использовать здесь полиморфизм и позволить нам сделать любой класс способным быть наблюдателем, поскольку он реализует метод, который будет запускаться. Предположим, нужно было уведомить и поставщиков, и вы увидите, насколько полезным может быть полиморфизм. Как мы можем сделать это? Еще раз, используя интерфейсы. Начнем с объявления IObserver интерфейса.

Этот интерфейс гарантирует, что каждый класс, который его реализует, должен объявить метод sendEmail(), который является действием, которое мы ожидаем запуска, и которое будет реализовано всеми нашими наблюдателями.

Теперь мы можем приступить к работе с нашим классом Sale. В нем должен быть базовый аспект, он должен иметь атрибут: массив наблюдателей, метод добавления наблюдателей в этот массив и, тем не менее, метод отправки письма всем наблюдателям о том, что продажа началась.

Мы также могли бы добавить метод, например, для отмены подписки клиента из списка, но это сделало бы наш код больше, поэтому примите это как упражнение.

Обратите внимание, что метод addObserver просто помещает нового наблюдателя в массив, а notifyObservers выполняет итерацию по этому массиву, вызывая функцию sendEmail для каждого экземпляра.

Теперь нам нужно работать в классе наших клиентов. Он будет реализовывать интерфейс, который мы создали ранее, который будет заключать договор о том, что наш класс обязательно отправит письмо нашему клиенту. Тогда у нас есть:

Ничего особенного здесь нет, у нас есть простой конструктор, а затем метод sendEmail. Теперь мы можем протестировать наш код:

Запустив его, мы можем увидеть на консоли следующее:

Sending a mail to John.
Sending a mail to Jessica.
Sending a mail to George.

В этом фрагменте трое наших клиентов теперь являются наблюдателями и получат электронное письмо с сообщением о том, что продажа началась, как и делала команда вначале. Похоже, они теперь могут выпить кофе.

✉️ Подпишитесь на рассылку еженедельно Email Blast от CodeBurst 🐦 Подпишитесь на CodeBurst на Twitter , просмотрите 🗺️ Дорожная карта веб-разработчиков на 2018 год и 🕸️ Изучите веб-разработку с полным стеком .