Использование паттерна Observer 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Использование паттерна Observer



1. Проведение различия между основной (или независимой) и дополнительной (или зависимой) функциональностями.

2. Моделирование "независимую" функциональность с помощью абстракции "субъект".

3. Моделирование "зависимую" функциональность с помощью иерархии "наблюдатель".

4. Класс Subject связан только c базовым классом Observer.

5. Клиент настраивает количество и типы наблюдателей.

6. Наблюдатели регистрируются у субъекта.

7. Subject извещает всех зарегистрированных наблюдателей.

8. Subject может "протолкнуть" информацию в наблюдателей, или наблюдатели могут "вытянуть" необходимую им информацию от объекта Subject.

 

 

#include <iostream> #include <vector> using namespace std; // 1. "Независимая" функциональность class Subject { // 3. Связь только с базовым классом Observer vector < class Observer * > views; int value; public: void attach(Observer *obs) { views.push_back(obs); } void setVal(int val) { value = val; notify(); } int getVal() { return value; } void notify(); }; // 2. " Зависимая " функциональность class Observer { Subject *model; int denom; public: Observer(Subject *mod, int div) { model = mod; denom = div; // 4. Наблюдатели регистрируются у субъекта model->attach(this); } virtual void update() = 0; protected: Subject *getSubject() { return model; } int getDivisor() { return denom; } }; void Subject::notify() { // 5. Извещение наблюдателей for (int i = 0; i < views.size(); i++) views[i]->update(); } class DivObserver: public Observer { public: DivObserver(Subject *mod, int div): Observer(mod, div){} void update() { // 6. " Вытягивание " интересующей информации int v = getSubject()->getVal(), d = getDivisor(); cout << v << " div " << d << " is " << v/d << '\n'; } }; class ModObserver: public Observer { public: ModObserver(Subject *mod, int div): Observer(mod, div){} void update() { int v = getSubject()->getVal(), d = getDivisor(); cout << v << " mod " << d << " is " << v%d << '\n'; } }; int main() { Subject subj; DivObserver divObs1(&subj, 4); // 7. Клиент настраивает число DivObserver divObs 2(& subj, 3); // и типы наблюдателей ModObserver modObs3(&subj, 3); subj.setVal(14); }

Вывод программы:

  14 div 4 is 3 14 div 3 is 4 14 mod 3 is 2

#include <iostream>

#include <string>

#include <list>

using namespace std;

class Supervised String;

Class IObserver

{

public:

virtual void handleEvent(const SupervisedString&) = 0;

};

Class SupervisedString // Observable class

{

string _str;

list<IObserver* const> _observers;

void _Notify()

{

   for(auto iter: _observers)

   {

       iter->handleEvent(*this);

   }

}

public:

void add(IObserver& ref)

{

   _observers.push_back(&ref);

}

void remove(IObserver& ref)

{

   _observers.remove(&ref);

}

const string& get() const

{

   return _str;

}

void reset(string str)

{

   _str = str;

   _Notify();

}

};

class Reflector: public IObserver // Prints the observed string into cout

{

public:

virtual void handleEvent(const SupervisedString& ref)

{

   cout << ref.get() << endl;

}

};

Class Counter: public IObserver

// Prints the length of observed string into cout

{

public:

virtual void handleEvent(const SupervisedString& ref)

{

cout << "length = " << ref.get().length() << endl;

}

};

Int main()

{

SupervisedString str;

Reflector refl;

Counter cnt;

str.add(refl);

str.reset("Hello, World!");

cout << endl;

str.remove(refl);

str.add(cnt);

str.reset("World, Hello!");

cout << endl;

return 0;

}

Рассмотрим еще раз саму идею паттерна, его применение и реализацию.

Наблюдатель – поведенческий шаблон проектирования.

Данный шаблон проектирования встречается под именем “подчиненные” (Dependents), “издатель-подписчик” (Publisher-Subscriber).

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

Рассмотрим случай, в которых может быть применен, если система обладает следующими свойствами:

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

Диаграмма классов представлена ниже.

 

Основными элементами в данном паттерне являются объект наблюдения (Subject) и реализация различных наблюдателей (extends Observer).

Будем хранить всех наблюдателей объекта непосредственно в нем.

Реализуем паттерн наблюдатель, в основу идеи положим оповещение учителя и родителей (Наблюдателей) об полученной учеником (Subject) оценке.

Абстрактный класс Observer содержит абстрактный метод update, который реализует каждый из конкретных наблюдателей в зависимости от своих целей.

Так же класс Observer содержит ссылку на субъект, за которым он наблюдает.

Реализация представлена ниже:

 



Поделиться:


Последнее изменение этой страницы: 2021-11-27; просмотров: 32; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.128.199.162 (0.013 с.)