Спостерігач, Observer — поведінковий шаблон проєктування. Також відомий як «підлеглі» (Dependents), «видавець-передплатник» (Publisher-Subscriber).
Призначення
Визначає залежність типу «один до багатьох» між об'єктами таким чином, що при зміні стану одного об'єкта всіх залежних від нього сповіщають про цю подію.
Переваги Він підтримує принцип вільного зв'язку між об'єктами, які взаємодіють один з одним Дозволяє ефективно передавати дані іншим об'єктам, без будь-яких змін у класах Subject або Observer Спостерігачі можуть бути додані / видалені в будь-який момент часу
Недоліки Інтерфейс Observer повинен бути впроваджений ConcreteObserver, який передбачає успадкування. Композиції для композиції немає, оскільки інтерфейс Observer може бути екземплятором. Якщо це неправильно реалізовано, спостерігач може додати складність і призвести до ненавмисних проблем із продуктивністю. У програмному застосуванні повідомлення іноді можуть бути невибагливими і призвести до умов перегонів або непослідовності.
Устрій
При реалізації шаблону «спостерігач» зазвичай використовуються такі класи: Subject — інтерфейс, що визначає методи для додавання, видалення та оповіщення спостерігачів. Observer — інтерфейс, за допомогою якого спостережуваний об'єкт оповіщає спостерігачів. ConcreteSubject — конкретний клас, який реалізує інтерфейс Subject. ConcreteObserver — конкретний клас, який реалізує інтерфейс Observer.
При зміні спостережуваного об'єкта, оповіщення спостерігачів може бути реалізоване за такими сценаріями: Спостережуваний об'єкт надсилає, кожному із зареєстрованих спостерігачів, всю потенційно релевантну інформацію (примусове розповсюдження). Спостережуваний об'єкт надсилає, кожному із зареєстрованих спостерігачів, лише повідомлення про те що інформація була змінена, а кожен із спостерігачів, за необхідності, самостійно здійснює запит необхідної інформації у спостережуваного об'єкта (розповсюдження за запитом).
Область застосування
Шаблон «спостерігач» застосовується в тих випадках, коли система володіє такими властивостями: існує, як мінімум, один об'єкт, що розсилає повідомлення є не менше одного одержувача повідомлень, причому їхня кількість і склад можуть змінюватися під час роботи програми.
Цей шаблон часто застосовують в ситуаціях, в яких відправника повідомлень не цікавить, що роблять одержувачі з наданою їм інформацією.
Простими словами Об'єкт володіє важливими даними і на нього підписані спостерігачі. Кожен спостерігач має можливість обновити ці дані а інші спостерігачі повинні отримати про це сповіщення і обновитись в слід якщо це необхідно.
Спостерігач не повинен запитувати об'єкт з певною періодичністю, він завжди знає що його дані актуальні.
Зв'язок із іншими патернами Посередник створює двосторонній зв'язок, часто незмінний. Забирає залежності між компонентами системи. Компоненти стають залежними від посередника. Спостерігач створює односторонній зв'язок, який може мінятись під час виконання програми. Таким чином одні об'єкти залежать від інших.
Приклади
Java
PHP5
C#
C++
ActionScript
Реалізації
Шаблон Спостерігач реалізований в численних бібліотеках і системах, включаючи майже всі інструментарії графічних інтерфейсів користувача.
Деякі з найпомітніших реалізацій шаблону перелічені нижче:
ActionScript flash.events, пакет у ActionScript 3.0 (який наслідував пакет mx.events у ActionScript 2.0).
BASIC Using the Observer Pattern, обговорення і реалізація в REALbasic
C GObject, у GLib — реалізація об'єктів і сигналів/зворотних викликів (Callback) в C. (Ця бібліотека часто включена в інші мови програмування)
C++ libsigc++ — бібліотека сигнальних шаблонів sigslot — C++ Signal/Slot Library Cpp::Events — Template-based C++ implementation that introduces separation of connection management interface of the event object from the invocation interface. XLObject — Template-based C++ signal/slot model patterned after Qt. Signals — A lightweight and non-intrusive C++ signal/slot model implementation. libevent — Multi-threaded Crossplatform Signal/Slot C++ Library Boost.Signals, an extension of the C++ STL providing a signal/slot model The Qt C++ framework's signal/slot model
C# Exploring the Observer Design Pattern — the C# and Visual Basic .NET implementation, using delegates and the Event pattern .NET Remoting, Applying the Observer Pattern in .NET Remoting (using C#)
Delphi Delphi Observer Pattern, a Delphi implementation
Java The Java Swing library makes extensive use of the observer pattern for event management PerfectJPattern Open Source Project , Provides a context-free and type-safe implementation of the Observer Pattern in Java.
JavaScript EventDispatcher singleton, a JavaScript core API based Signals and slots implementation — an observer concept different from Publish/subscribe — pretty lightweighted but still type-safety enforcing.
Lisp Cells , a dataflow extension to Common Lisp that uses meta-programming to hide some of the details of Observer pattern implementation.
PHP Event_Dispatcher , a PHP implementation SPL , the Standard PHP Library
Python Py-notify, a Python implementation Observer Pattern using Weak References implementation by Michael Kent PyPubSub an in-application Pub/Sub library for Observer behavior NotificationFramework classes directly implementing Observer patterns
Ruby Observer , from the Ruby Standard Library. Also see Russ Olsen's coverage of this pattern in Ruby in Design Patterns in Ruby
Інше CSP — Observer Pattern using CSP-like Rendezvous (each actor is a process, communication is via rendezvous). YUI Event utility implements custom events through the observer pattern Publish/Subscribe with LabVIEW, Implementation example of Observer or Publish/Subscribe using G.
Посилання Observer Pattern implementation in JDK 6 A sample implementation in .NET Observer Pattern in Java Definition, C# example & UML diagram Jt J2EE Pattern Oriented Framework Subject Observer example in C++ Observer Pattern recipe in Python
Джерела