MetaTrader 5 / Bibliothèque
observer (push) - behavioral design pattern - bibliothèque pour MetaTrader 5
3208
//+------------------------------------------------------------------+ //| 201111_091814.mq5 | //| 2019-2020, dimitri pecheritsa | //| 792112@gmail.com | //+------------------------------------------------------------------+ // // observer (push) - behavioral design pattern // // from: design patterns: elements of reusable object-oriented software // by gof: erich gamma, richard helm, ralph johnson, john vlissides // published in 1994 // // intent // // define a one-to-many dependency between objects so that when one object //changes state, all its dependents are notified and updated automatically // // applicability // // when an abstraction has two aspects, one dependent on the other. //encapsulating these aspects in separate objects lets you vary and reuse //them independently // when a change to one object requires changing others, and you don't //know how many objects need to be changed // when an object should be able to notify other objects without making //assumptions about who these objects are. in other words, you don't want //these objects tightly coupled // // structure // // observers // | Subject |---------------------->*|Observer| // |----------------------| |--------| // |Attach(Observer) | |Update()| // |Detach(Observer) | ^ // |Notify() | | // | forall o in observers| | // | o.Update() | | // ^ | // | | ConcreteObserver | // | subject |--------------------| // | ConcreteSubject |<----------------|Update() | // |-----------------------| | observerState= | // |GetState() | | subject.GetState()| // | return subject.State()| |--------------------| // |SetState() | |observer_state | // |-----------------------| // |subject_state | // // participants // // subject // knows its observers. any number of observer objects may observe //a subject // provides an interface for attaching and detaching observer objects // observer // defines an updating interface for objects that should be notified //of changes in a subject // concrete subject // stores state of interest to concrete observer objects // sends a notification to its observers when its state changes // concrete observer // maintains a reference to a concrete subject object // stores state that should stay consistent with the subject's // implements the observer updating interface to keep its state consistent //with the subject's // // collaborations // // concrete subject notifies its observers whenever a change occurs //that could make its observers' state inconsistent with its own. // after being informed of a change in the concrete subject, a concrete //observer object may query the subject for information. concrete observer //uses this information to reconcile its state with that of the subject. // // aConcrete aConcrete another // Subject Observer ConcreteObserver // | | | // | SetState() | | // | |<-------------------| | | // | |Notify() | | | // | |-----------+ | | // | | | | | // | |<----------+ | | // | |Update() | | // | |------------------->| | | // | | GetState()| | | // | |<-------------------| | | // | |Update() | | // | |---------------------|--------------->| | // | | | GetState()| | // | |<--------------------|----------------| | // | | | // // note how the observer object that initiates the change request postpones //its update until it gets a notification from the subject. notify is //not always called by the subject. it can be called by an observer or //by another kind of object entirely. // #include <Mqh\201111_084634.mqh> //push observer #include <Mqh\201111_084512.mqh> //push subject #include <Mqh\201111_091110.mqh> //push concrete subject #include <Mqh\201111_090802.mqh> //push concrete observer //+------------------------------------------------------------------+ //| client | //+------------------------------------------------------------------+ void OnStart(void) { ConcreteSubject subject; subject.Attach(new ConcreteObserver(subject)); subject.Attach(new ConcreteObserver(subject)); subject.State("new push state"); subject.Notify(); } // // output // // subject state set to: new push state // pushing state to observer 2097152... // observer 2097152 state updated to: new push state // pushing state to observer 3145728... // observer 3145728 state updated to: new push state // // consequences // // the observer pattern lets you vary subjects and observers independently. //you can reuse subjects without reusing their observers, and vice versa. //it lets you add observers without modifying the subject or other observers. // further benefits and liabilities of the observer pattern include //the following: // abstract coupling between subject and observer // support for broadcast communication // unexpected updates // // implementation // // mapping subjects to their observers // observing more than one subject // who triggers the update? // dangling references to deleted subjects // making sure subject state is self-consistent before notification // avoiding observer-specific update protocols: the push and pull models // specifying modifications of interest explicitly // encapsulating complex update semantics // combining the subject and observer classes // // related patterns // // mediator // singleton //+------------------------------------------------------------------+