Observer - спостерігач (патерни проектування), it sphere

Виконуючи нові вимоги замовника ми бачимо переваги архітектури заснованої на інтерфейсах. Для того щоб додати можливість підписуватися юридичним особам, нам достатньо просто створити клас Company. Єдине чим він відміну від першого прикладу в тому, що він теж реалізує інтерфейс Subsciber.

Нам не потрібно міняти клас Publisher. По тому що в ньому використовується абстракція Subscriber.

Observer - спостерігач (патерни проектування), it sphere

Observer - спостерігач (патерни проектування), it sphere

Висновок на екран не відрізняється від першого прикладу. Сподіваюся, що немає сенсу пояснювати, що такий код більш акуратний і підтримувати його простіше.

Тепер поговоримо про теорію даного шаблону.

Observer - спостерігач (патерни проектування), it sphere

Зверніть увагу на схему. Ті класи на які підписуються називаються СУБ'ЄКТАМИ а ті які підписуються називаються СПОСТЕРІГАЧАМИ. У нашому прикладі суб'єктом був інтерфейс Subscribable, а спостерігачами був інтерфейс Subscriber. Відповідно їх реалізації були ConcreteSubject і ConcreteObserver

На схемі Subject може бути як інтерфейсом так і класом. Варіант коли він є інтерфейсом більш гнучкий, по крайней мере в java це так. Причина цього те, що в Java неможливо множинне спадкування. Якщо Ваш клас Subject вже є чиїмось нащадком, то це накладає на Вас деякі обмеження. Таких обмежень немає, якщо Ви працюєте з інтерфейсом.

Observer так само може бути класом або інтерфейсом, з тими ж наслідками.

Необов'язково дуже точно слідувати UML схемою шаблон. Адже ми хочемо отримати його переваги, а не скопіювати схему в коді. Я не залишав посилання на subject в конкретних реалізаціях спостерігача, як це зроблено на схемі. Дивіться пунктир від ConcreteObserver. І не створював метод get / setState в ConcreteSubject.

Пам'ятайте, що суб'єкт нічого не повинен знати про реалізацію спостерігачів.

Патерн спостерігач визначає ставлення "один-ко-многим" між об'єктами.

Один суб'єкт - багато спостерігачів.

Таким чином, що при зміні стану одного об'єкта відбувається автоматичне оповіщення та оновлення всіх залежних об'єктів.

Зовсім об'єкти це спостерігачі.

  1. Єдине, що знає суб'єкт про спостерігачі це те, що він реалізує інтерфейс Observer. Це дозволяє нам додавати нові типи спостерігачів без модифікації суб'єкта.
  2. Нові спостерігачі можуть підписуватися і відписуватися від отримання оновлень в будь-який момент.
  3. Суб'єкт і спостерігач можуть використовуватися повторно.
  4. Зміна одного ніяк не впливає іншого.

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

У мові Java існує вбудована поддержкаданного паттерна

Це клас java.util.Observable, його розширюють суб'єкти. Я вже говорив про обмеження, які накладає на нас спадкування в реалізації через клас. Ще є java.util.Observer, це інтерфейс для спостерігачів.

Давайте наш останній приклад переробимо, щоб він використовував дані клас і інтерфейс.

Перше що ми зробимо, це видалимо наші інтерфейси.

Observer - спостерігач (патерни проектування), it sphere

Observer - спостерігач (патерни проектування), it sphere

Класи Company і Person тепер реалізують інтерфейс Observer. Метод update другим параметром отримує посилання на об'єкт журнал.

Observer - спостерігач (патерни проектування), it sphere

Клас publisher більше не відповідає за підписку і відписку. Всі ці методи знаходяться в його предка. Це гарна новина, тому що нам тепер не потрібно їх реалізовувати самостійно. Тим більше, що ці методи синхронізовані. Для того щоб все запрацювало, потрібно ще пам'ятати про метод setChanged, який перемикає стан класу в режим "змінений". Якщо цього не зробити, то спостерігачі не отримають оновлення.

Observer - спостерігач (патерни проектування), it sphere

Висновок на екран нічим не відрізняється від попередніх прикладів.

В JDK є ще кілька подібних класів і інтерфейсів. Наприклад, клас java.beans.PropertyChangeSupport і інтерфейс java.beans.PropertyChangeListener

Якщо не лінуйтеся, подивіться самі.

Ще один тип спостерігачів

Якби наша редакція випускала ще й газети, то ми могли б реалізувати шаблон трохи по іншому. Щоб надати більше гнучкості нашим класам. Спостерігачі можуть отримувати або газету, або журнал. Просто вони для цього повинні зробити запит через відповідний getter.

Observer - спостерігач (патерни проектування), it sphere

Observer - спостерігач (патерни проектування), it sphere

Наприклад людина виписує тільки журнали, а компанія тільки газети. Цього можна домогтися і не використовуючи java-ську реалізацію цього шаблону. Наприклад, передаючи кожному спостерігачу посилання на видавництво. Повністю код наводити не буду, спробуйте реалізувати його самі.

Читайте книги, поки!

Схожі статті