Шаблонът за проектиране на наблюдателя е модел за проектиране на софтуер, в който обект, наречен субект, поддържа списък на своите зависими, наречени наблюдатели, и ги уведомява автоматично за всякакви промени в състоянието, обикновено чрез извикване на един от техните методи. Използва се главно за внедряване на разпределени системи за обработка на събития.

Моделът на наблюдател е известен също като модел публикуване-абониране. Използва се, за да позволи слабо свързване между обекти, така че обектът не трябва да знае подробностите за това как се използват промените в състоянието му, но вместо това може да предостави прост метод за други обекти да регистрират интерес да бъдат уведомени за тези промени.

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

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

Представете си, че имате група приятели, които всички обичат да играят футбол. Решавате да създадете футболен клуб и каните всичките си приятели да се присъединят. Вие сте капитанът на клуба и отговаряте за организирането на игрите и за това всеки да знае кога и къде да играе.

Един ден решавате да промените мястото на следващата игра. Не искате да се обаждате или да изпращате текстови съобщения на всичките си приятели поотделно, за да ги уведомите за промяната, така че вместо това изпращате съобщение до целия клуб, като използвате специално приложение за съобщения, което всички използвате. Когато вашите приятели получат съобщението, те могат да проверят приложението, за да видят кога и къде ще се играе играта.

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

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

Какво каза наблюдателят на субекта, когато се чувстваше изоставен? „Не се притеснявай, винаги ще бъда тук, за да те държа под око.“

Един често срещан случай на използване на модела на наблюдател е при разработването на потребителски интерфейс, където субектът представлява модел или източник на данни, а наблюдателят представлява изглед, който показва данните. Когато данните в модела се променят, субектът може да изпрати известие до изгледа, който след това може да се актуализира, за да отрази новите данни. Това позволява на изгледа да остане в синхрон с модела, без да е необходимо изгледът постоянно да анкетира модела за актуализации.

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

Ето един прост пример за това как шаблонът за проектиране на наблюдателя може да бъде имплементиран в 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 на съответния източник на новини с новата статия като аргумент.

Шаблонът за проектиране на наблюдател се използва широко при разработването на pub-sub системи и много компании и организации го използват за прилагане на известия в реално време и други видове разпределени обработки на събития. Ето няколко примера за това как шаблонът за проектиране на наблюдателя може да се използва в pub-sub система:

  1. Известия в реално време: Един често срещан случай на използване на шаблона за проектиране на наблюдател в pub-sub системи е да се предоставят известия в реално време на потребители или други клиенти. Например платформа за социални медии може да използва шаблона за проектиране на наблюдател, за да изпраща известия до потребителите, когато някой хареса публикацията им или я коментира.
  2. Синхронизиране на данни: Шаблонът за проектиране на наблюдател може също да се използва за синхронизиране на данни между множество клиенти или устройства. Например услуга за съхранение в облак може да използва модела на наблюдател, за да изпраща актуализации на клиенти всеки път, когато файл се добавя, модифицира или изтрива в облака.
  3. Проследяване на събития: Шаблонът за проектиране на наблюдател може също да се използва за проследяване на събития и задействане на действия въз основа на тези събития. Например, платформа за електронна търговия може да използва модела на наблюдател, за да проследява покупките и да изпраща имейли до клиенти с персонализирани препоръки за продукти въз основа на тяхната история на покупки.
  4. Мрежова комуникация: Шаблонът за проектиране на наблюдател също често се използва за улесняване на комуникацията между различни части на мрежата. Например приложение за съобщения може да използва модела на наблюдател, за да изпраща съобщения между потребителите и да актуализира потребителския интерфейс с нови съобщения, когато бъдат получени.

Заключение

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

Има няколко предимства от използването на шаблона за проектиране на наблюдателя:

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

Като цяло шаблонът за проектиране на наблюдателя е полезен инструмент за внедряване на разпределени системи за обработка на събития и за поддържане на съгласуваност между свързани обекти по гъвкав и отделен начин.

Благодаря за четенето! Ако сте намерили статията за полезна, можете да ръкопляскате и да следвате. Така ще получавате известия за нови статии.

# препратка

Създаден е с помощта на ChatGPT AI.