Спостерігач, Observer — поведінковий шаблон проєктування. Також відомий як «підлеглі» (Dependents), «видавець-передплатник» (Publisher-Subscriber).
Призначення
Визначає залежність типу «один до багатьох» між об'єктами таким чином, що при зміні стану одного об'єкта всіх залежних від нього сповіщають про цю подію.
Переваги
- Він підтримує принцип вільного зв'язку між об'єктами, які взаємодіють один з одним
- Дозволяє ефективно передавати дані іншим об'єктам, без будь-яких змін у класах Subject або Observer
- Спостерігачі можуть бути додані / видалені в будь-який момент часу
Недоліки
- Інтерфейс Observer повинен бути впроваджений ConcreteObserver, який передбачає успадкування. Композиції для композиції немає, оскільки інтерфейс Observer може бути екземплятором.
- Якщо це неправильно реалізовано, спостерігач може додати складність і призвести до ненавмисних проблем із продуктивністю.
- У програмному застосуванні повідомлення іноді можуть бути невибагливими і призвести до умов перегонів або непослідовності.
Устрій
При реалізації шаблону «спостерігач» зазвичай використовуються такі класи:
- Subject — інтерфейс, що визначає методи для додавання, видалення та оповіщення спостерігачів.
- Observer — інтерфейс, за допомогою якого спостережуваний об'єкт оповіщає спостерігачів.
- ConcreteSubject — конкретний клас, який реалізує інтерфейс Subject.
- ConcreteObserver — конкретний клас, який реалізує інтерфейс Observer.
При зміні спостережуваного об'єкту, оповіщення спостерігачів може бути реалізоване за такими сценаріями:
- Спостережуваний об'єкт надсилає, кожному із зареєстрованих спостерігачів, всю потенційно релевантну інформацію (примусове розповсюдження).
- Спостережуваний об'єкт надсилає, кожному із зареєстрованих спостерігачів, лише повідомлення про те що інформація була змінена, а кожен із спостерігачів, за необхідності, самостійно здійснює запит необхідної інформації у спостережуваного об'єкта (розповсюдження за запитом).
Область застосування
Шаблон «спостерігач» застосовується в тих випадках, коли система володіє такими властивостями:
- існує, як мінімум, один об'єкт, що розсилає повідомлення
- є не менше одного одержувача повідомлень, причому їхня кількість і склад можуть змінюватися під час роботи програми.
Цей шаблон часто застосовують в ситуаціях, в яких відправника повідомлень не цікавить, що роблять одержувачі з наданою їм інформацією.
Простими словами
Об'єкт володіє важливими даними і на нього підписані спостерігачі. Кожен спостерігач має можливість обновити ці дані а інші спостерігачі повинні отримати про це сповіщення і обновитись в слід якщо це необхідно.
Спостерігач не повинен запитувати об'єкт з певною періодичністю, він завжди знає що його дані актуальні.
Зв'язок із іншими патернами
- Посередник створює двосторонній зв'язок, часто незмінний. Забирає залежності між компонентами системи. Компоненти стають залежними від посередника. Спостерігач створює односторонній зв'язок, який може мінятись під час виконання програми. Таким чином одні об'єкти залежать від інших.
Приклади
package example.pattern.observer; import java.util.ArrayList; import java.util.List; public interface Subject { void attach(Observer o); void detach(Observer o); void notifyObserver(); } public interface Observer { void update(); } public class ConcreteSubject implements Subject { private List<Observer> observers = new ArrayList<Observer>(); private int value; public void setValue(int value) { this.value = value; notifyObserver(); } public int getValue() { return value; } @Override public void attach(Observer o) { observers.add(o); } @Override public void detach(Observer o) { observers.remove(o); } @Override public void notifyObserver() { for (Observer o : observers) { o.update(); } } } public class ConcreteObserver1 implements Observer { private ConcreteSubject subject; public ConcreteObserver1(ConcreteSubject subject) { this.subject = subject; } @Override public void update() { System.out.println("Observer1: " + subject.getValue()); } } public class ConcreteObserver2 implements Observer { private ConcreteSubject subject; public ConcreteObserver2(ConcreteSubject subject) { this.subject = subject; } @Override public void update() { String out = ""; for (int i = 0; i < subject.getValue(); i++) { out += "*"; } System.out.println("Observer2: " + out); } } public class Program { public static void main(String[] args) { ConcreteSubject subject = new ConcreteSubject(); ConcreteObserver1 observer1 = new ConcreteObserver1(subject); ConcreteObserver2 observer2 = new ConcreteObserver2(subject); subject.attach(observer1); subject.attach(observer2); subject.setValue(3); subject.setValue(8); } }
<?php // Інтерфейс, за допомогою якого спостережуваний об'єкт сповіщає спостерігачів interface Observer{ function notify($obj); } // Клас спостережуваного об'єкта class ExchangeRate{ static private $instance = NULL; private $observers = array(); private $exchange_rate; private function ExchangeRate(){ } static public function getInstance(){ if(self::$instance == NULL){ self::$instance = new ExchangeRate(); } return self::$instance; } public function getExchangeRate(){ return $this->exchange_rate; } public function setExchangeRate($new_rate){ $this->exchange_rate = $new_rate; $this->notifyObservers(); } public function registerObserver($obj){ $this->observers[] = $obj; } function notifyObservers(){ foreach($this->observers as $obj){ $obj->notify($this); } } } // Клас спостерігача class ProductItem implements Observer{ public function __construct(){ ExchangeRate::getInstance()->registerObserver($this); } public function notify($obj){ if($obj instanceof ExchangeRate) { // Update exchange rate data print "Received update!\n"; } } } // Створення об'єктів спостерігачів $product1 = new ProductItem(); $product2 = new ProductItem(); // Зміна стану спостережуваного об'єкта та автоматичне // оповіщення про це спостерігачів через функцію notify() ExchangeRate::getInstance()->setExchangeRate(4.5); ?>
using System; using System.Collections; using System.Threading; namespace Observer { /// <summary> /// Observer Pattern Judith Bishop Jan 2007 /// /// The Subject runs in a thread and changes its state /// independently. At each change, it notifies its Observers. /// </summary> class Program { static void Main(string[] args) { Subject subject = new Subject(); Observer Observer = new Observer(subject,"Center","\t\t"); Observer observer2 = new Observer(subject,"Right","\t\t\t\t"); subject.Go(); // Wait for user Console.Read(); } } class Simulator : IEnumerable { string [] moves = {"5","3","1","6","7"}; public IEnumerator GetEnumerator() { foreach( string element in moves ) yield return element; } } class Subject { public delegate void Callback (string s); public event Callback Notify; Simulator simulator = new Simulator( ); const int speed = 200; public string SubjectState { get; set; } public void Go() { new Thread(new ThreadStart(Run)).Start( ); } void Run () { foreach (string s in simulator) { Console.WriteLine("Subject: " + s); SubjectState = s; Notify(s); Thread.Sleep(speed); // milliseconds } } } interface IObserver { void Update(string state); } class Observer : IObserver { string name; Subject subject; string state; string gap; public Observer(Subject subject, string name, string gap) { this.subject = subject; this.name = name; this.gap = gap; subject.Notify += Update; } public void Update(string subjectState) { state = subjectState; Console.WriteLine(gap + name + ": " + state); } } }
namespace ObserverPattern.Interfaces { interface IEvent { } interface IObserver<in TEvent> where TEvent : IEvent { void Handle(object sender, TEvent eventArgs); } interface ISubject<TEvent> where TEvent : IEvent { void Notify(TEvent raisedEvent); void Add(IObserver<TEvent> observer); void Remove(IObserver<TEvent> observer); } class UserRenamedEvent : IEvent { public string Name { get; } public UserRenamedEvent(string name) { Name = name; } } class User : ISubject<UserRenamedEvent> { private string _name; public string Name { get { return _name; } set { _name = value; this.Notify(new UserRenamedEvent(value)); } } private readonly ICollection<IObserver<UserRenamedEvent>> _userRenamedObservers = new List<IObserver<UserRenamedEvent>>(); public void Add(IObserver<UserRenamedEvent> observer) { _userRenamedObservers.Add(observer); } public void Remove(IObserver<UserRenamedEvent> observer) { _userRenamedObservers.Remove(observer); } public void Notify(UserRenamedEvent raisedEvent) { foreach (var observer in _userRenamedObservers) { observer.Handle(this, raisedEvent); } } } class ConsoleLogger : IObserver<UserRenamedEvent> { public void Handle(object sender, UserRenamedEvent eventArgs) { Console.WriteLine($"User has been renamed to [{eventArgs.Name}]"); } } class Program { static void Main(string[] args) { var logger = new ConsoleLogger(); var user = new User(); user.Add(logger); user.Name = "John Doe"; } } }
namespace ObserverPattern.Events { class UserRenamedEvent : EventArgs { public string Name { get; } public UserRenamedEvent(string name) { Name = name; } } class User { private string _name; public string Name { get { return _name; } set { _name = value; this.OnUserRenamed(new UserRenamedEvent(value)); } } public event EventHandler<UserRenamedEvent> UserRenamedEvent; // keep this protected to override event in derived class protected void OnUserRenamed(UserRenamedEvent raisedEvent) { UserRenamedEvent?.Invoke(this, raisedEvent); } } class ConsoleLogger { public void Handle(object sender, UserRenamedEvent eventArgs) { Console.WriteLine($"User has been renamed to [{eventArgs.Name}]"); } } class Program { static void Main(string[] args) { var logger = new ConsoleLogger(); var user = new User(); user.UserRenamedEvent += logger.Handle; user.Name = "John Doe"; } } }
namespace ObserverPattern.EventService { interface IEvent { } interface IEventHandler<in TEvent> where TEvent : IEvent { void Handle(object sender, TEvent raisedEvent); } interface IEventService { void Publish<TEvent>(object sender, TEvent raisedEvent) where TEvent : IEvent; void Subscribe<TEvent, THandler>() where TEvent : IEvent where THandler : IEventHandler<TEvent>; } class EventService : IEventService { private readonly IDictionary<Type, List<Type>> _eventHandlers = new Dictionary<Type, List<Type>>(); public void Publish<TEvent>(object sender, TEvent raisedEvent) where TEvent : IEvent { var eventType = typeof(TEvent); if (!_eventHandlers.ContainsKey(eventType)) return; foreach (var handlerType in _eventHandlers[eventType]) { var handler = Activator.CreateInstance(handlerType) as IEventHandler<TEvent>; handler.Handle(sender, raisedEvent); } } public void Subscribe<TEvent, THandler>() where TEvent : IEvent where THandler : IEventHandler<TEvent> { var eventType = typeof(TEvent); var handlerType = typeof(THandler); if (!_eventHandlers.ContainsKey(eventType)) { _eventHandlers.Add(eventType, new List<Type>()); } if (_eventHandlers[eventType].Any(ht => ht == handlerType)) { throw new ArgumentException($"Handler Type {handlerType.Name} already is registered for '{eventType.Name}'"); } _eventHandlers[eventType].Add(handlerType); } public static EventService Instance { get; } private EventService() { } static EventService() { Instance = new EventService(); } } class UserRenamedEvent : IEvent { public string Name { get; } public UserRenamedEvent(string name) { Name = name; } } class User { private string _name; public string Name { get { return _name; } set { _name = value; EventService.Instance.Publish(this, new UserRenamedEvent(value)); } } } class ConsoleLogger : IEventHandler<UserRenamedEvent> { public void Handle(object sender, UserRenamedEvent eventArgs) { Console.WriteLine($"User has been renamed to [{eventArgs.Name}]"); } } class Program { static void Main(string[] args) { EventService.Instance.Subscribe<UserRenamedEvent, ConsoleLogger>(); var user = new User(); user.Name = "John Doe"; } } }
#include <iostream> #include <string> #include <map> class SupervisedString; class IObserver { public: virtual void handleEvent (const SupervisedString&) = 0; }; class SupervisedString{ // Спостережний клас std::string _str; std::map<IObserver* const, IObserver* const> _observers; void _Notify() { for (auto &iter : _observers) { iter.second->handleEvent (*this); } } public: void add (IObserver& ref) { _observers.insert (item (&ref, &ref)); } void remove (IObserver& ref) { _observers.erase (&ref); } const std::string& get() const { return _str; } void reset (std::string str) { _str = str; _Notify(); } }; class Reflector: public IObserver{ // Надрукувати спостережуваний рядок у std::cout public: virtual void handleEvent (const SupervisedString& ref) { std::cout<<ref.get()<<std::endl; } }; class Counter: public IObserver{ // Надрукувати довжину спостережуваного рядка в std::cout virtual void handleEvent (const SupervisedString& ref) { std::cout<<"length = "<<ref.get().length()<<std::endl; } }; int main() { SupervisedString str; Reflector refl; Counter cnt; str.add (refl); str.reset ("Hello, World!"); std::cout<<std::endl; str.remove (refl); str.add (cnt); str.reset ("World, Hello!"); std::cout<<std::endl; return 0; }
//файл IObserver.as package { public interface IObserver { function notify(obj:Object):void; } } //файл ExchangeRate.as package { public class ExchangeRate { private static var _instance:ExchangeRate = null; private var observers:Array = []; private var _exchangeRate:Object; public function ExchangeRate() { if (_instance == null) throw new Error('Model Singleton!'); } public static function getInstance():ExchangeRate { if (_instance == null) { _instance = new ExchangeRate(); } return _instance; } public function get exchangeRate():Object { return _exchangeRate; } public function set exchangeRate(value:Object):void { _exchangeRate = value; this.notifyObservers(); } public function registerObserver(value:IObserver):void { this.observers.push(value); } private function notifyObservers():void { for each(var observer:IObserver in this.observers) { observer.notify(this); } } } } //файл ProductItem.as package { public class ProductItem implements IObserver { public function ProductItem() { ExchangeRate.getInstance().registerObserver(this); } public function notify(value:Object):void { if (value is ExchangeRate) { var exchange:ExchangeRate = value as ExchangeRate; trace(exchange.exchangeRate); } } } } //файл Main.as package { import flash.display.Sprite; public class Main extends Sprite { public function Main():void { var item1:ProductItem = new ProductItem(); var item2:ProductItem = new ProductItem(); ExchangeRate.getInstance().exchangeRate = 3.5; } } }
Реалізації
Шаблон Спостерігач реалізований в численних бібліотеках і системах, включаючи майже всі інструментарії графічних інтерфейсів користувача.
Деякі з найпомітніших реалізацій шаблону перелічені нижче:
- , пакет у ActionScript 3.0 (який наслідував пакет mx.events у ActionScript 2.0).
BASIC
- , обговорення і реалізація в
C
- , у GLib — реалізація об'єктів і / (Callback) в C. (Ця бібліотека часто включена в інші мови програмування)
C++
- — бібліотека шаблонів
- sigslot [ 14 березня 2010 у Wayback Machine.] — C++ Signal/Slot Library
- Cpp::Events [ 24 липня 2010 у Wayback Machine.] — Template-based C++ implementation that introduces separation of connection management interface of the event object from the invocation interface.
- XLObject [ 8 серпня 2010 у Wayback Machine.] — Template-based C++ signal/slot model patterned after Qt.
- Signals [ 9 липня 2010 у Wayback Machine.] — A lightweight and non-intrusive C++ implementation.
- libevent [ 23 травня 2010 у Wayback Machine.] — Multi-threaded Crossplatform Signal/Slot C++ Library
- , an extension of the C++ STL providing a signal/slot model
- The Qt C++ framework's
C#
- Exploring the Observer Design Pattern [ 7 березня 2010 у Wayback Machine.] — the C# and Visual Basic .NET implementation, using and the Event pattern
- , Applying the Observer Pattern in .NET Remoting (using C#)
- , a Delphi implementation
- The Java Swing library makes extensive use of the observer pattern for event management
- PerfectJPattern Open Source Project [ 29 липня 2010 у Wayback Machine.], Provides a context-free and type-safe implementation of the Observer Pattern in Java.
- , a JavaScript core API based Signals and slots implementation — an observer concept different from — pretty lightweighted but still type-safety enforcing.
- Cells [ 17 липня 2011 у Wayback Machine.], a dataflow extension to Common Lisp that uses meta-programming to hide some of the details of Observer pattern implementation.
PHP
- Event_Dispatcher [ 28 березня 2010 у Wayback Machine.], a PHP implementation
- SPL [ 12 квітня 2011 у Wayback Machine.], the Standard PHP Library
- , a Python implementation
- Observer Pattern using Weak References [ 16 травня 2010 у Wayback Machine.] implementation by Michael Kent
- PyPubSub [ 16 травня 2010 у Wayback Machine.] an in-application Pub/Sub library for Observer behavior
- NotificationFramework [ 6 липня 2010 у Wayback Machine.] classes directly implementing Observer patterns
- Observer [ 29 квітня 2010 у Wayback Machine.], from the Ruby Standard Library. Also see Russ Olsen's coverage of this pattern in Ruby in Design Patterns in Ruby [ 11 липня 2010 у Wayback Machine.]
Інше
- CSP [ 13 червня 2010 у Wayback Machine.] — Observer Pattern using CSP-like Rendezvous (each actor is a process, communication is via rendezvous).
- implements custom events through the observer pattern
- , Implementation example of Observer or Publish/Subscribe using G.
Посилання
- Observer Pattern implementation in JDK 6 [ 6 серпня 2009 у Wayback Machine.]
- Observer Pattern in Java [ 30 березня 2010 у Wayback Machine.]
- Definition, C# example & UML diagram [ 23 липня 2010 у Wayback Machine.]
- J2EE Pattern Oriented Framework
- Observer Pattern recipe in Python [ 16 квітня 2010 у Wayback Machine.]
Джерела
- Design Patterns: Elements of Reusable Object-Oriented Software [ 9 листопада 2012 у Wayback Machine.]
Література
Алан Шаллоуей, Джеймс Р. Тротт. Шаблоны проектирования. Новый подход к объектно-ориентированному анализу и проектированию = Design Patterns Explained: A New Perspective on Object-Oriented Design. — М. : «Вильямс», 2002. — 288 с. — .
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
Div takozh Sposterigach znachennya Sposterigach Observer povedinkovij shablon proyektuvannya Takozh vidomij yak pidlegli Dependents vidavec peredplatnik Publisher Subscriber PriznachennyaViznachaye zalezhnist tipu odin do bagatoh mizh ob yektami takim chinom sho pri zmini stanu odnogo ob yekta vsih zalezhnih vid nogo spovishayut pro cyu podiyu PerevagiVin pidtrimuye princip vilnogo zv yazku mizh ob yektami yaki vzayemodiyut odin z odnim Dozvolyaye efektivno peredavati dani inshim ob yektam bez bud yakih zmin u klasah Subject abo Observer Sposterigachi mozhut buti dodani vidaleni v bud yakij moment chasuNedolikiInterfejs Observer povinen buti vprovadzhenij ConcreteObserver yakij peredbachaye uspadkuvannya Kompoziciyi dlya kompoziciyi nemaye oskilki interfejs Observer mozhe buti ekzemplyatorom Yaksho ce nepravilno realizovano sposterigach mozhe dodati skladnist i prizvesti do nenavmisnih problem iz produktivnistyu U programnomu zastosuvanni povidomlennya inodi mozhut buti nevibaglivimi i prizvesti do umov peregoniv abo neposlidovnosti UstrijPri realizaciyi shablonu sposterigach zazvichaj vikoristovuyutsya taki klasi Subject interfejs sho viznachaye metodi dlya dodavannya vidalennya ta opovishennya sposterigachiv Observer interfejs za dopomogoyu yakogo sposterezhuvanij ob yekt opovishaye sposterigachiv ConcreteSubject konkretnij klas yakij realizuye interfejs Subject ConcreteObserver konkretnij klas yakij realizuye interfejs Observer Pri zmini sposterezhuvanogo ob yektu opovishennya sposterigachiv mozhe buti realizovane za takimi scenariyami Sposterezhuvanij ob yekt nadsilaye kozhnomu iz zareyestrovanih sposterigachiv vsyu potencijno relevantnu informaciyu primusove rozpovsyudzhennya Sposterezhuvanij ob yekt nadsilaye kozhnomu iz zareyestrovanih sposterigachiv lishe povidomlennya pro te sho informaciya bula zminena a kozhen iz sposterigachiv za neobhidnosti samostijno zdijsnyuye zapit neobhidnoyi informaciyi u sposterezhuvanogo ob yekta rozpovsyudzhennya za zapitom Oblast zastosuvannyaShablon sposterigach zastosovuyetsya v tih vipadkah koli sistema volodiye takimi vlastivostyami isnuye yak minimum odin ob yekt sho rozsilaye povidomlennya ye ne menshe odnogo oderzhuvacha povidomlen prichomu yihnya kilkist i sklad mozhut zminyuvatisya pid chas roboti programi Cej shablon chasto zastosovuyut v situaciyah v yakih vidpravnika povidomlen ne cikavit sho roblyat oderzhuvachi z nadanoyu yim informaciyeyu Prostimi slovamiOb yekt volodiye vazhlivimi danimi i na nogo pidpisani sposterigachi Kozhen sposterigach maye mozhlivist obnoviti ci dani a inshi sposterigachi povinni otrimati pro ce spovishennya i obnovitis v slid yaksho ce neobhidno Sposterigach ne povinen zapituvati ob yekt z pevnoyu periodichnistyu vin zavzhdi znaye sho jogo dani aktualni Zv yazok iz inshimi paternamiPoserednik stvoryuye dvostoronnij zv yazok chasto nezminnij Zabiraye zalezhnosti mizh komponentami sistemi Komponenti stayut zalezhnimi vid poserednika Sposterigach stvoryuye odnostoronnij zv yazok yakij mozhe minyatis pid chas vikonannya programi Takim chinom odni ob yekti zalezhat vid inshih PrikladiJava Kod programi na movi Java package example pattern observer import java util ArrayList import java util List public interface Subject void attach Observer o void detach Observer o void notifyObserver public interface Observer void update public class ConcreteSubject implements Subject private List lt Observer gt observers new ArrayList lt Observer gt private int value public void setValue int value this value value notifyObserver public int getValue return value Override public void attach Observer o observers add o Override public void detach Observer o observers remove o Override public void notifyObserver for Observer o observers o update public class ConcreteObserver1 implements Observer private ConcreteSubject subject public ConcreteObserver1 ConcreteSubject subject this subject subject Override public void update System out println Observer1 subject getValue public class ConcreteObserver2 implements Observer private ConcreteSubject subject public ConcreteObserver2 ConcreteSubject subject this subject subject Override public void update String out for int i 0 i lt subject getValue i out System out println Observer2 out public class Program public static void main String args ConcreteSubject subject new ConcreteSubject ConcreteObserver1 observer1 new ConcreteObserver1 subject ConcreteObserver2 observer2 new ConcreteObserver2 subject subject attach observer1 subject attach observer2 subject setValue 3 subject setValue 8 PHP5 Kod programi na movi PHP5 lt php Interfejs za dopomogoyu yakogo sposterezhuvanij ob yekt spovishaye sposterigachiv interface Observer function notify obj Klas sposterezhuvanogo ob yekta class ExchangeRate static private instance NULL private observers array private exchange rate private function ExchangeRate static public function getInstance if self instance NULL self instance new ExchangeRate return self instance public function getExchangeRate return this gt exchange rate public function setExchangeRate new rate this gt exchange rate new rate this gt notifyObservers public function registerObserver obj this gt observers obj function notifyObservers foreach this gt observers as obj obj gt notify this Klas sposterigacha class ProductItem implements Observer public function construct ExchangeRate getInstance gt registerObserver this public function notify obj if obj instanceof ExchangeRate Update exchange rate data print Received update n Stvorennya ob yektiv sposterigachiv product1 new ProductItem product2 new ProductItem Zmina stanu sposterezhuvanogo ob yekta ta avtomatichne opovishennya pro ce sposterigachiv cherez funkciyu notify ExchangeRate getInstance gt setExchangeRate 4 5 gt C Kod programi na movi C using System using System Collections using System Threading namespace Observer lt summary gt Observer Pattern Judith Bishop Jan 2007 The Subject runs in a thread and changes its state independently At each change it notifies its Observers lt summary gt class Program static void Main string args Subject subject new Subject Observer Observer new Observer subject Center t t Observer observer2 new Observer subject Right t t t t subject Go Wait for user Console Read class Simulator IEnumerable string moves 5 3 1 6 7 public IEnumerator GetEnumerator foreach string element in moves yield return element class Subject public delegate void Callback string s public event Callback Notify Simulator simulator new Simulator const int speed 200 public string SubjectState get set public void Go new Thread new ThreadStart Run Start void Run foreach string s in simulator Console WriteLine Subject s SubjectState s Notify s Thread Sleep speed milliseconds interface IObserver void Update string state class Observer IObserver string name Subject subject string state string gap public Observer Subject subject string name string gap this subject subject this name name this gap gap subject Notify Update public void Update string subjectState state subjectState Console WriteLine gap name state Kod programi na movi C Rishennya na osnovi interfejsiv namespace ObserverPattern Interfaces interface IEvent interface IObserver lt in TEvent gt where TEvent IEvent void Handle object sender TEvent eventArgs interface ISubject lt TEvent gt where TEvent IEvent void Notify TEvent raisedEvent void Add IObserver lt TEvent gt observer void Remove IObserver lt TEvent gt observer class UserRenamedEvent IEvent public string Name get public UserRenamedEvent string name Name name class User ISubject lt UserRenamedEvent gt private string name public string Name get return name set name value this Notify new UserRenamedEvent value private readonly ICollection lt IObserver lt UserRenamedEvent gt gt userRenamedObservers new List lt IObserver lt UserRenamedEvent gt gt public void Add IObserver lt UserRenamedEvent gt observer userRenamedObservers Add observer public void Remove IObserver lt UserRenamedEvent gt observer userRenamedObservers Remove observer public void Notify UserRenamedEvent raisedEvent foreach var observer in userRenamedObservers observer Handle this raisedEvent class ConsoleLogger IObserver lt UserRenamedEvent gt public void Handle object sender UserRenamedEvent eventArgs Console WriteLine User has been renamed to eventArgs Name class Program static void Main string args var logger new ConsoleLogger var user new User user Add logger user Name John Doe Kod programi na movi C Rishennya na osnovi podij namespace ObserverPattern Events class UserRenamedEvent EventArgs public string Name get public UserRenamedEvent string name Name name class User private string name public string Name get return name set name value this OnUserRenamed new UserRenamedEvent value public event EventHandler lt UserRenamedEvent gt UserRenamedEvent keep this protected to override event in derived class protected void OnUserRenamed UserRenamedEvent raisedEvent UserRenamedEvent Invoke this raisedEvent class ConsoleLogger public void Handle object sender UserRenamedEvent eventArgs Console WriteLine User has been renamed to eventArgs Name class Program static void Main string args var logger new ConsoleLogger var user new User user UserRenamedEvent logger Handle user Name John Doe Kod programi na movi C Rishennya na osnovi servisu namespace ObserverPattern EventService interface IEvent interface IEventHandler lt in TEvent gt where TEvent IEvent void Handle object sender TEvent raisedEvent interface IEventService void Publish lt TEvent gt object sender TEvent raisedEvent where TEvent IEvent void Subscribe lt TEvent THandler gt where TEvent IEvent where THandler IEventHandler lt TEvent gt class EventService IEventService private readonly IDictionary lt Type List lt Type gt gt eventHandlers new Dictionary lt Type List lt Type gt gt public void Publish lt TEvent gt object sender TEvent raisedEvent where TEvent IEvent var eventType typeof TEvent if eventHandlers ContainsKey eventType return foreach var handlerType in eventHandlers eventType var handler Activator CreateInstance handlerType as IEventHandler lt TEvent gt handler Handle sender raisedEvent public void Subscribe lt TEvent THandler gt where TEvent IEvent where THandler IEventHandler lt TEvent gt var eventType typeof TEvent var handlerType typeof THandler if eventHandlers ContainsKey eventType eventHandlers Add eventType new List lt Type gt if eventHandlers eventType Any ht gt ht handlerType throw new ArgumentException Handler Type handlerType Name already is registered for eventType Name eventHandlers eventType Add handlerType public static EventService Instance get private EventService static EventService Instance new EventService class UserRenamedEvent IEvent public string Name get public UserRenamedEvent string name Name name class User private string name public string Name get return name set name value EventService Instance Publish this new UserRenamedEvent value class ConsoleLogger IEventHandler lt UserRenamedEvent gt public void Handle object sender UserRenamedEvent eventArgs Console WriteLine User has been renamed to eventArgs Name class Program static void Main string args EventService Instance Subscribe lt UserRenamedEvent ConsoleLogger gt var user new User user Name John Doe C Kod programi na movi C include lt iostream gt include lt string gt include lt map gt class SupervisedString class IObserver public virtual void handleEvent const SupervisedString amp 0 class SupervisedString Sposterezhnij klas std string str std map lt IObserver const IObserver const gt observers void Notify for auto amp iter observers iter second gt handleEvent this public void add IObserver amp ref observers insert item amp ref amp ref void remove IObserver amp ref observers erase amp ref const std string amp get const return str void reset std string str str str Notify class Reflector public IObserver Nadrukuvati sposterezhuvanij ryadok u std cout public virtual void handleEvent const SupervisedString amp ref std cout lt lt ref get lt lt std endl class Counter public IObserver Nadrukuvati dovzhinu sposterezhuvanogo ryadka v std cout virtual void handleEvent const SupervisedString amp ref std cout lt lt length lt lt ref get length lt lt std endl int main SupervisedString str Reflector refl Counter cnt str add refl str reset Hello World std cout lt lt std endl str remove refl str add cnt str reset World Hello std cout lt lt std endl return 0 ActionScript Kod programi na movi ActionScript fajl IObserver as package public interface IObserver function notify obj Object void fajl ExchangeRate as package public class ExchangeRate private static var instance ExchangeRate null private var observers Array private var exchangeRate Object public function ExchangeRate if instance null throw new Error Model Singleton public static function getInstance ExchangeRate if instance null instance new ExchangeRate return instance public function get exchangeRate Object return exchangeRate public function set exchangeRate value Object void exchangeRate value this notifyObservers public function registerObserver value IObserver void this observers push value private function notifyObservers void for each var observer IObserver in this observers observer notify this fajl ProductItem as package public class ProductItem implements IObserver public function ProductItem ExchangeRate getInstance registerObserver this public function notify value Object void if value is ExchangeRate var exchange ExchangeRate value as ExchangeRate trace exchange exchangeRate fajl Main as package import flash display Sprite public class Main extends Sprite public function Main void var item1 ProductItem new ProductItem var item2 ProductItem new ProductItem ExchangeRate getInstance exchangeRate 3 5 RealizaciyiShablon Sposterigach realizovanij v chislennih bibliotekah i sistemah vklyuchayuchi majzhe vsi instrumentariyi grafichnih interfejsiv koristuvacha Deyaki z najpomitnishih realizacij shablonu perelicheni nizhche ActionScript paket u ActionScript 3 0 yakij nasliduvav paket mx events u ActionScript 2 0 BASIC obgovorennya i realizaciya v C u GLib realizaciya ob yektiv i Callback v C Cya biblioteka chasto vklyuchena v inshi movi programuvannya C biblioteka shabloniv sigslot 14 bereznya 2010 u Wayback Machine C Signal Slot Library Cpp Events 24 lipnya 2010 u Wayback Machine Template based C implementation that introduces separation of connection management interface of the event object from the invocation interface XLObject 8 serpnya 2010 u Wayback Machine Template based C signal slot model patterned after Qt Signals 9 lipnya 2010 u Wayback Machine A lightweight and non intrusive C implementation libevent 23 travnya 2010 u Wayback Machine Multi threaded Crossplatform Signal Slot C Library an extension of the C STL providing a signal slot model The Qt C framework s C Exploring the Observer Design Pattern 7 bereznya 2010 u Wayback Machine the C and Visual Basic NET implementation using and the Event pattern Applying the Observer Pattern in NET Remoting using C Delphi a Delphi implementation Java The Java Swing library makes extensive use of the observer pattern for event management PerfectJPattern Open Source Project 29 lipnya 2010 u Wayback Machine Provides a context free and type safe implementation of the Observer Pattern in Java JavaScript a JavaScript core API based Signals and slots implementation an observer concept different from pretty lightweighted but still type safety enforcing Lisp Cells 17 lipnya 2011 u Wayback Machine a dataflow extension to Common Lisp that uses meta programming to hide some of the details of Observer pattern implementation PHP Event Dispatcher 28 bereznya 2010 u Wayback Machine a PHP implementation SPL 12 kvitnya 2011 u Wayback Machine the Standard PHP Library Python a Python implementation Observer Pattern using Weak References 16 travnya 2010 u Wayback Machine implementation by Michael Kent PyPubSub 16 travnya 2010 u Wayback Machine an in application Pub Sub library for Observer behavior NotificationFramework 6 lipnya 2010 u Wayback Machine classes directly implementing Observer patterns Ruby Observer 29 kvitnya 2010 u Wayback Machine from the Ruby Standard Library Also see Russ Olsen s coverage of this pattern in Ruby in Design Patterns in Ruby 11 lipnya 2010 u Wayback Machine Inshe CSP 13 chervnya 2010 u Wayback Machine Observer Pattern using CSP like Rendezvous each actor is a process communication is via rendezvous implements custom events through the observer pattern Implementation example of Observer or Publish Subscribe using G PosilannyaObserver Pattern implementation in JDK 6 6 serpnya 2009 u Wayback Machine Observer Pattern in Java 30 bereznya 2010 u Wayback Machine Definition C example amp UML diagram 23 lipnya 2010 u Wayback Machine J2EE Pattern Oriented Framework Observer Pattern recipe in Python 16 kvitnya 2010 u Wayback Machine DzherelaDesign Patterns Elements of Reusable Object Oriented Software 9 listopada 2012 u Wayback Machine LiteraturaAlan Shallouej Dzhejms R Trott Shablony proektirovaniya Novyj podhod k obektno orientirovannomu analizu i proektirovaniyu Design Patterns Explained A New Perspective on Object Oriented Design M Vilyams 2002 288 s ISBN 0 201 71594 5