Рубрики

Наблюдатель Pattern | Комплект 1 (Введение)

Давайте сначала рассмотрим следующий сценарий, чтобы понять картину наблюдателя.

Сценарий :

Предположим, мы создаем приложение для игры в крикет, которое уведомляет зрителей о такой информации, как текущий счет, скорость бега и т. Д. Предположим, что мы создали два элемента отображения CurrentScoreDisplay и AverageScoreDisplay. CricketData имеет все данные (прогоны, миски и т. Д.), И при каждом изменении данных элементы отображения уведомляются с новыми данными, и они соответственно отображают последние данные.

Ниже приведена Java-реализация этого проекта.

// Java реализация вышеупомянутого дизайна для Cricket App.
// проблемы с этим дизайном обсуждаются ниже.

  
// Класс, который получает информацию со стадиона и уведомляет
// отображаем элементы, CurrentScoreDisplay и AverageScoreDisplay

class CricketData

{

    int runs, wickets;

    float overs;

    CurrentScoreDisplay currentScoreDisplay;

    AverageScoreDisplay averageScoreDisplay;

  

    // Конструктор

    public CricketData(CurrentScoreDisplay currentScoreDisplay,

                       AverageScoreDisplay averageScoreDisplay)

    {

        this.currentScoreDisplay = currentScoreDisplay;

        this.averageScoreDisplay = averageScoreDisplay;

    }

  

    // Получить последние пробеги со стадиона

    private int getLatestRuns()

    {

        // возвращаем 90 для простоты

        return 90;

    }

  

    // Получить последние калитки со стадиона

    private int getLatestWickets()

    {

        // возвращаем 2 для простоты

        return 2;

    }

  

    // Получить последние кадры со стадиона

    private float getLatestOvers()

    {

        // возвращаем 10.2 для простоты

        return (float)10.2;

    }

  

    // Этот метод используется обновление отображает при изменении данных

    public void dataChanged()

    {

        // получить последние данные

        runs = getLatestRuns();

        wickets = getLatestWickets();

        overs = getLatestOvers();

  

        currentScoreDisplay.update(runs,wickets,overs);

        averageScoreDisplay.update(runs,wickets,overs);

    }

}

  
// Класс для отображения среднего балла. Данные этого класса
// обновлено CricketData

class AverageScoreDisplay

{

    private float runRate;

    private int predictedScore;

  

    public void update(int runs, int wickets, float overs)

    {

        this.runRate = (float)runs/overs;

        this.predictedScore = (int) (this.runRate * 50);

        display();

    }

  

    public void display()

    {

        System.out.println("\nAverage Score Display:\n" +

                           "Run Rate: " + runRate +

                           "\nPredictedScore: " + predictedScore);

    }

}

  
// Класс для отображения счета. Данные этого класса
// обновлено CricketData

class CurrentScoreDisplay

{

    private int runs, wickets;

    private float overs;

  

    public void update(int runs,int wickets,float overs)

    {

        this.runs = runs;

        this.wickets = wickets;

        this.overs = overs;

        display();

    }

  

    public void display()

    {

        System.out.println("\nCurrent Score Display: \n" +

                           "Runs: " + runs +"\nWickets:"

                           + wickets + "\nOvers: " + overs );

    }

}

  
// Класс водителя

class Main

{

    public static void main(String args[])

    {

        // Создание объектов для тестирования

        AverageScoreDisplay averageScoreDisplay =

                                       new AverageScoreDisplay();

        CurrentScoreDisplay currentScoreDisplay =

                                       new CurrentScoreDisplay();

  

        // Передача дисплеев в данные по крикету

        CricketData cricketData = new CricketData(currentScoreDisplay,

                                                  averageScoreDisplay);

  

        // В реальном приложении у вас есть логика для вызова этого

        // функция при изменении данных

        cricketData.dataChanged();

    }

}

Выход:

 Отображение текущей оценки: 
Работает: 90
Калитки: 2
Overs: 10,2

Отображение среднего балла:
Скорость выполнения: 8,823529
ПрогнозируемоеScore: 441 

Проблемы с вышеуказанным дизайном :

  • CricketData содержит ссылки на конкретные объекты отображаемого элемента, даже если для этого требуется вызвать только метод обновления этих объектов. Он имеет доступ к слишком большому количеству дополнительной информации, чем ему требуется.
  • Это утверждение «currentScoreDisplay.update (run, wickets, overs);» нарушает один из важнейших принципов проектирования «Программирование на интерфейсах, а не на реализациях». Поскольку мы используем конкретные объекты для обмена данными, а не абстрактные интерфейсы.
  • CricketData и элементы отображения тесно связаны между собой.
  • Если в будущем появится другое требование, и нам понадобится добавить еще один элемент отображения, нам нужно внести изменения в неизменяемую часть нашего кода (CricketData). Это определенно не очень хорошая практика проектирования, и приложение может не справиться с изменениями и не будет легко поддерживать.

Как избежать этих проблем?
Использовать шаблон наблюдателя

Образец наблюдателя

Чтобы понять структуру наблюдателя, сначала вам нужно понять объект и объекты наблюдателя.

Отношение между субъектом и наблюдателем может быть легко понято как аналогия с подпиской на журнал.

  • Издатель журнала (тема) занимается бизнесом и публикует журналы (данные).
  • Если вы (пользователь данных / обозреватель) интересуетесь журналом, на который вы подписываетесь (регистрируетесь), и если публикуется новое издание, оно доставляется вам.
  • Если вы отмените подписку (отмените регистрацию), вы перестанете получать новые версии.
  • Издатель не знает, кто вы и как вы используете журнал, он просто доставляет его вам, потому что вы подписчик (слабая связь).

Определение:

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

Объяснение:

  • Зависимость «один ко многим» существует между субъектом (один) и наблюдателем (многие).
  • Существует зависимость, поскольку сами наблюдатели не имеют доступа к данным. Они зависят от субъекта, чтобы предоставить им данные.

Диаграмма классов:

Источник изображения: Википедия

  • Здесь Observer и Subject являются интерфейсами (может быть любым абстрактным супертипом, не обязательно интерфейсом Java).
  • Все наблюдатели, которым нужны данные, должны реализовать интерфейс наблюдателей.
  • Метод notify () в интерфейсе наблюдателя определяет действие, которое должно быть выполнено, когда субъект предоставляет ему данные.
  • Субъект поддерживает набор наблюдателей, который представляет собой просто список зарегистрированных в настоящее время (подписанных) наблюдателей.
  • registerObserver (наблюдатель) и unregisterObserver (наблюдатель) являются методами для добавления и удаления наблюдателей соответственно.
  • notifyObservers () вызывается, когда данные изменяются, и наблюдателям необходимо предоставить новые данные.

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

Шаблон наблюдателя обеспечивает эту слабую связь как:

  • Субъект только знает, что наблюдатель реализует интерфейс Observer. Ничего более.
  • Нет необходимости изменять тему для добавления или удаления наблюдателей.
  • Мы можем повторно использовать предметные и наблюдательные классы независимо друг от друга.

Недостатки:

  • Утечки памяти, вызванные проблемой Lapsed listener из-за явного регистра и отмены регистрации наблюдателей.

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

Реальная жизнь использует:

  • Он широко используется в инструментарии GUI и слушателе событий. В Java кнопка (субъект) и onClickListener (наблюдатель) моделируются с помощью шаблона наблюдателя.
  • Социальные сети, RSS-каналы, подписка на электронную почту, в которой у вас есть возможность подписаться или подписаться, и вы получите последнее уведомление.
  • Все пользователи приложения в игровом магазине получают уведомление, если есть обновление.

Наблюдатель Pattern | Набор 2 (реализация)

Эта статья предоставлена Сулабх Кумар . Если вам нравится GeeksforGeeks и вы хотите внести свой вклад, вы также можете написать статью и отправить ее по почте на contrib@geeksforgeeks.org. Смотрите свою статью, появляющуюся на главной странице GeeksforGeeks, и помогите другим вундеркиндам.

Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой теме

Рекомендуемые посты:

Наблюдатель Pattern | Комплект 1 (Введение)

0.00 (0%) 0 votes