Шаблон проектирования наблюдателя — это шаблон проектирования программного обеспечения, в котором объект, называемый субъектом, ведет список своих зависимых объектов, называемых наблюдателями, и автоматически уведомляет их о любых изменениях состояния, обычно вызывая один из их методов. Он в основном используется для реализации распределенных систем обработки событий.

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

В шаблоне наблюдателя субъект часто реализуется как простая структура данных, такая как список, в котором хранится список ссылок на объекты наблюдателя. Когда состояние субъекта изменяется, он отправляет уведомление всем зарегистрированным наблюдателям, которые затем могут обновлять свое состояние по мере необходимости.

Шаблон наблюдателя — это полезный шаблон проектирования, который можно использовать, когда вам нужно, чтобы один или несколько объектов получали уведомления при изменении состояния другого объекта, но вы не хотите, чтобы объекты были тесно связаны. Это может быть особенно полезно в ситуациях, когда вам нужно поддерживать согласованность между связанными объектами, но не хотите создавать и поддерживать явные связи между объектами.

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

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

В этом примере вы являетесь субъектом, а ваши друзья — наблюдателями. Субъект (вы) ведет список наблюдателей (ваших друзей) и отправляет им уведомление (сообщение в приложении) всякий раз, когда состояние субъекта (местоположение игры) изменяется. Наблюдатели (ваши друзья) могут обновлять свое состояние (свои планы на игру) по мере необходимости.

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

Что наблюдатель сказал субъекту, когда он чувствовал себя обделенным? — Не волнуйся, я всегда буду рядом, чтобы присматривать за тобой.

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

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

Вот простой пример того, как шаблон проектирования наблюдателя может быть реализован на C#:

Во-первых, мы определим интерфейс для наблюдателей:

public interface IObserver
{
    void Update(string message);
}

Далее мы определим класс для субъекта:

public class Subject
{
    private List<IObserver> observers = new List<IObserver>();

    public void Attach(IObserver observer)
    {
        observers.Add(observer);
    }

    public void Detach(IObserver observer)
    {
        observers.Remove(observer);
    }

    public void Notify(string message)
    {
        foreach (IObserver observer in observers)
        {
            observer.Update(message);
        }
    }
}

Субъект поддерживает список объектов-наблюдателей и предоставляет методы для добавления или удаления наблюдателей из списка. Он также имеет метод Notify, который отправляет уведомление всем зарегистрированным наблюдателям.

Наконец, мы определим класс для наблюдателей:

public class Observer : IObserver
{
    private string name;

    public Observer(string name)
    {
        this.name = name;
    }

    public void Update(string message)
    {
        Console.WriteLine($"{name} received message: {message}");
    }
}

Класс наблюдателя реализует интерфейс IObserver и предоставляет метод Update, который вызывается при получении уведомления от субъекта.

Чтобы использовать этот пример, вы должны сначала создать экземпляр класса Subject, а затем создать один или несколько экземпляров класса Observer. Затем вы должны зарегистрировать экземпляры наблюдателя с субъектом, используя метод Attach, и всякий раз, когда вы хотите отправить уведомление наблюдателям, вы должны вызвать метод Notify для субъекта.

Вот пример того, как это можно использовать в основной программе:

Subject subject = new Subject();
Observer observer1 = new Observer("Observer 1");
Observer observer2 = new Observer("Observer 2");

subject.Attach(observer1);
subject.Attach(observer2);

subject.Notify("The game has been rescheduled for 2pm.");

Это выведет на консоль следующее:

Observer 1 received message: The game has been rescheduled for 2pm.
Observer 2 received message: The game has been rescheduled for 2pm.

Что субъект сказал наблюдателю, когда наконец получил уведомление? "Пора! Я ждал, когда ты меня заметишь!»

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

В этом случае источники новостей могут быть реализованы как субъекты, а пользователи, подписавшиеся на источник, могут быть реализованы как наблюдатели. Субъект будет вести список своих наблюдателей и предоставлять метод для добавления или удаления наблюдателей из списка. Когда публикуется новая статья, субъект отправляет уведомление всем зарегистрированным наблюдателям, которые затем могут обновлять свое состояние (например, отображая уведомление пользователю или добавляя новую статью в список статей для чтения). .

Вот пример кода, иллюстрирующий, как это может быть реализовано на C#:

public interface INewsSource
{
    string Name { get; }
    void Attach(IUser user);
    void Detach(IUser user);
    void Notify(Article article);
}

public class NewsSource : INewsSource
{
    private string name;
    private List<IUser> users = new List<IUser>();

    public string Name => name;

    public NewsSource(string name)
    {
        this.name = name;
    }

    public void Attach(IUser user)
    {
        users.Add(user);
    }

    public void Detach(IUser user)
    {
        users.Remove(user);
    }

    public void Notify(Article article)
    {
        foreach (IUser user in users)
        {
            user.Update(article);
        }
    }
}

public interface IUser
{
    string Name { get; }
    void Update(Article article);
}

public class User : IUser
{
    private string name;

    public string Name => name;

    public User(string name)
    {
        this.name = name;
    }

    public void Update(Article article)
    {
        Console.WriteLine($"{name} received notification of new article: {article.Title}");
    }
}

Чтобы использовать этот пример, вы должны сначала создать экземпляры класса NewsSource для каждого источника новостей, который вы хотите предложить (например, «CNN», «BBC» и т. д.), а затем создать экземпляры класса User для каждого пользователя, который хочет подписаться на один или несколько источников. Затем вы должны регистрировать пользователей с интересующими их источниками, используя метод Attach, и всякий раз, когда публикуется новая статья, вы должны вызывать метод Notify для соответствующего источника новостей с новой статьей в качестве аргумента.

Шаблон проектирования Observer широко используется при разработке систем pub-sub, и многие компании и организации используют его для реализации уведомлений в реальном времени и других типов распределенной обработки событий. Вот несколько примеров того, как шаблон проектирования Observer можно использовать в системе pub-sub:

  1. Уведомления в режиме реального времени. Одним из распространенных вариантов использования шаблона проектирования наблюдателя в системах pub-sub является предоставление уведомлений в режиме реального времени пользователям или другим клиентам. Например, платформа социальных сетей может использовать шаблон проектирования наблюдателя для отправки уведомлений пользователям, когда кому-то нравится их сообщение или кто-то комментирует его.
  2. Синхронизация данных. Шаблон проектирования наблюдателя также можно использовать для синхронизации данных между несколькими клиентами или устройствами. Например, служба облачного хранилища может использовать шаблон наблюдателя для отправки обновлений клиентам при каждом добавлении, изменении или удалении файла в облаке.
  3. Отслеживание событий. Шаблон проектирования наблюдателя также можно использовать для отслеживания событий и инициирования действий на основе этих событий. Например, платформа электронной коммерции может использовать шаблон наблюдателя для отслеживания покупок и отправки клиентам электронных писем с персонализированными рекомендациями по продуктам на основе их истории покупок.
  4. Сетевое взаимодействие. Шаблон проектирования наблюдателя также часто используется для облегчения взаимодействия между различными частями сети. Например, приложение для обмена сообщениями может использовать шаблон наблюдателя для отправки сообщений между пользователями и обновления пользовательского интерфейса новыми сообщениями по мере их получения.

Заключение

Шаблон проектирования наблюдателя — это шаблон проектирования программного обеспечения, который позволяет объекту, называемому субъектом, вести список своих зависимых объектов, называемых наблюдателями, и автоматически уведомлять их о любых изменениях состояния. Основная цель шаблона наблюдателя — разрешить слабую связь между объектами, чтобы объекту не нужно было знать подробности того, как используются изменения его состояния, но вместо этого он мог предоставить простой метод для других объектов, чтобы зарегистрировать интерес к уведомлению. тех изменений.

Существует несколько преимуществ использования шаблона проектирования Observer:

  1. Развязка. Одно из основных преимуществ шаблона наблюдателя заключается в том, что он позволяет отделить объекты, за которыми наблюдают, от объектов, которые их наблюдают. Это означает, что наблюдаемым объектам не нужно ничего знать об объектах-наблюдателях, и наоборот. Это может упростить изменение или модификацию объектов-наблюдателей, не затрагивая наблюдаемые объекты, и наоборот.
  2. Повторное использование. Шаблон наблюдателя также может упростить повторное использование кода, поскольку объекты наблюдателя можно использовать в нескольких контекстах без тесной связи с наблюдаемыми объектами.
  3. Гибкость. Шаблон наблюдателя также позволяет динамически добавлять или удалять объекты наблюдателя, что может быть полезно, если вам нужно изменить поведение вашей системы во время выполнения.
  4. Расширяемость. Шаблон наблюдателя также упрощает расширение вашей системы, поскольку вы можете добавлять новые объекты-наблюдатели, не изменяя наблюдаемые объекты.

В целом, шаблон проектирования наблюдателя является полезным инструментом для реализации распределенных систем обработки событий и для поддержания согласованности между связанными объектами гибким и несвязанным образом.

Спасибо за прочтение! Если статья показалась вам полезной, вы можете похлопать и подписаться. Так вы будете получать уведомления о новых статьях.

# Ссылка

Он был создан с помощью ChatGPT AI.