Observator (model de design)

Versiunea actuală a paginii nu a fost încă examinată de colaboratori experimentați și poate diferi semnificativ de versiunea revizuită pe 19 mai 2019; verificările necesită 15 modificări .
Observator
Observator
Tip de comportamental
Scop
  • Modelul Observer definește o dependență unu-la-mulți între obiecte, astfel încât atunci când starea unui obiect se schimbă, toate obiectele care depind de acesta sunt notificate și actualizate automat;
  • Modelul Observer încapsulează componenta principală (independentă) în abstractizarea Subiectului și componentele mutabile (dependente) în ierarhia Observator;
  • Modelul Observer definește partea „View” a unui model Model-View-Controller (MVC) [1] .
Descris în Design Patterns da

The  Observer este un model de design comportamental . Cunoscuți și ca „subordonați” ( ing. Dependents ). Implementează un mecanism de clasă care permite unui obiect din această clasă să primească notificări despre modificările stării altor obiecte și astfel să le observe [2] .  

Clasele la ale căror evenimente sunt abonate alte clase se numesc Subiecte, iar clasele abonate se numesc Observatori [ 3 ] . 

Șabloane similare: „ editor-abonat ”, „ intermediar ”, „ singuratic ”.

Numire

Definește o dependență unu-la-mulți între obiecte, astfel încât, atunci când starea unui obiect se schimbă, toți cei dependenți de acesta sunt notificați despre eveniment.

Implementare

La implementarea modelului de observator, sunt utilizate în mod obișnuit următoarele clase:

Domeniul de aplicare

Modelul de observator este utilizat atunci când sistemul are următoarele proprietăți:

Acest tipar este adesea folosit în situațiile în care expeditorul mesajelor nu este interesat de ceea ce fac destinatarii cu informațiile care le sunt furnizate.

Exemple

PHP5 (SPL)

Text sursă în limba php /** * PHP oferă suport încorporat pentru acest model prin extensia inclusă * SPL (Standard PHP Library): * SplObserver - interfață pentru Observer (observator), * SplSubject - interfață pentru Observable (observabil), * SplObjectStorage - clasa auxiliară (oferă salvarea și ștergerea îmbunătățite a obiectelor *, în special, sunt implementate metodele attach() și detach()). */ class Instrumente observabile SplSubject { private $storage ; function __construct () { $this -> storage = new SplObjectStorage (); } function attach ( SplObserver $observator ) { $this -> storage -> attach ( $observator ); } function detach ( SplObserver $observator ) { $this -> storage -> detach ( $observator ); } function notify () { foreach ( $this -> storage as $obj ) { $obj -> update ( $this ); } } } clasa ConcreteObserver implementeaza SplObserver { private $observabil ; private $index ; function __construct ( Observabil $observabil ) { static $sindex = 0 ; $this -> index = $sindex ++ ; $acest -> observabil = $observabil ; $observabil -> atașați ( $acest ); } function update ( SplSubject $subiect ) { if ( $subiect === $this -> observable ) { echo "Trimite notificare catre ConcreteObserver [ $this->index ] \n " ; } } } $observabil = nou Observabil (); nou ConcreteObserver ( $observable ); nou ConcreteObserver ( $observable ); nou ConcreteObserver ( $observable ); $observabil -> notifica ();

PHP5

Text sursă în limba php interfață Observer { function notify ( $obj ); } clasa Rata de schimb { static private $instanta = NULL ; private $observers = matrice (); privat $rată_schimb ; funcție privată __construct () {} funcție privată __clone () {} static public function getInstance () { if ( self :: $instance == NULL ) { self :: $instance = new ExchangeRate (); } return self :: $instanta ; } public function getExchangeRate () { return $this -> exchange_rate ; } public function setExchangeRate ( $new_rate ) { $this -> exchange_rate = $new_rate ; $this -> notifyObservers (); } public function registerObserver ( Observator $obj ) { $this -> observatori [] = $obj ; } function notifyObservers () { foreach ( $this -> observatori ca $obj ) { $obj -> notify ( $this ); } } } clasa ProductItem implementează Observer { public function __construct () { ExchangeRate :: getInstance () -> registerObserver ( $this ); } public function notify ( $obj ) { if ( $obj instanceof ExchangeRate ) { // Actualizați datele cursului de schimb print "Actualizare primită! \n " ; } } } $produs1 = nou ProductItem (); $produs2 = nou ProductItem (); ExchangeRate :: getInstance () -> setExchangeRate ( 4.5 );

C#

Text sursă în C# folosind System ; folosind System.Collections ; folosind System.Collections.Generic ; folosind System.Threading ; namespace Observer { /// <summary> /// Observer Pattern Judith Bishop ian 2007 /// Actualizat de Kobel' Bohdan 2013 /// /// Subiectul rulează într-un fir și își schimbă starea /// independent. La fiecare schimbare, își anunță observatorii. /// </summary> class Program { static void Main ( string [] args ) { Subject subject = new Subject (); Observator observator = nou Observator ( subiect , „Centru” , „\t\t” ); Observator observator2 = nou Observator ( subiect , „Dreapta” , „\t\t\t\t” ); subiect . merge (); // Așteptați Consola utilizatorului . citește (); } } Simulator de clasă : IEnumerable { șir [] mută = { "5" , "3" , "1" , "6" , "7" }; public IEnumerator GetEnumerator () { foreach ( element șir în mișcări ) yield return element ; } } interfață ISubject { void AddObserver ( observator IObserver ); void RemoveObserver ( observator IObserver ); void NotifyObservers ( șir s ); } class Subiect : ISubject { public string SubjectState { get ; set ; } Public List < IObserver > Observatori { get ; set privat ; } Simulator privat Simulator ; private const int viteză = 200 ; public Subiect () { Observatori = listă nouă < IObserver >(); simulator = simulator nou (); } public void AddObserver ( observator IObserver ) { Observatori . Adăugați ( observator ); } public void RemoveObserver ( observator IObserver ) { Observatori . Eliminați ( observator ); } public void NotifyObservers ( șir s ) { foreach ( var observator în Observers ) { observator . Actualizare ( e ); } } public void Go () { new Thread ( new ThreadStart ( Run )). Start ( ); } void Run () { foreach ( șir de caractere în simulator ) { Consolă . WriteLine ( "Subiect: " + s ); SubjectState = s ; NotifyObservers ( s ); fir . somn ( viteza ); // milisecunde } } } interfață IObserver { void Update ( stare șir ); } class Observer : IObserver { string name ; Isubiect ; _ starea șirului ; decalaj al șirului ; public Observer ( subiect IS , nume de șir , decalaj de șir ) { this . subiect = subiect ; aceasta . nume = nume ; aceasta . gap = decalaj ; subiect . AddObserver ( aceasta ); } public void Actualizare ( șir subiectState ) { stat = subiectState ; Consola . WriteLine ( decalaj + nume + ": " + stare ); } } }

Java

Sursa Java // Exemplul descrie cum să primiți date de la o stație meteo (clasa WeatherData, dispecer de evenimente) și //utilizați-l pentru a le afișa pe ecran (clasa CurrentConditionsDisplay, ascultător de evenimente). //Ascultătorul este înregistrat cu observatorul folosind metoda registerObserver (în acest caz, ascultătorul este adăugat la lista de observatori). //Înregistrarea are loc în momentul în care este creat obiectul currentDisplay, deoarece metoda registerObserver este aplicată în constructor. //Când datele meteorologice se modifică, este apelată metoda notifyObservers, care la rândul său apelează metoda de actualizare //pe toți ascultătorii, transmițându-le datele actualizate. import java.util.LinkedList ; import java.util.List ; public class WeatherStation { public static void main ( String [] args ) { WeatherData weatherData = new WeatherData (); Observer currentDisplay = new CurrentConditionsDisplay (); Date meteo . registerObserver ( currentDisplay ); Date meteo . setMeasurements ( 29 f , 65 f , 745 ); Date meteo . setMeasurements ( 39 f , 70 f , 760 ); Date meteo . setMeasurements ( 42 f , 72 f , 763 ); } } interfață Observer { void update ( temperatura float , umiditate float , presiune int ); } interfață Observabil { void registerObserver ( Observer o ); void removeObserver ( Observer o ); void notifyObservers (); } clasa WeatherData implementează Observable { private List < Observer > observatori ; temperatura plutitorului privat ; umiditatea flotorului privat ; private int presiune ; public WeatherData () { observatori = new LinkedList <> (); } @Override public void registerObserver ( Observator o ) { observatori . adaugă ( o ); } @Override public void removeObserver ( Observator o ) { observatori . elimina ( o ); } @Override public void notifyObservers () { pentru ( observator observator : observatori ) observator . actualizare ( temperatura , umiditate , presiune ); } public void setMeasurements ( temperatura float , umiditate float , presiune int ) { asta . temperatura = temperatura ; aceasta . umiditate = umiditate ; aceasta . presiune = presiune ; notifyObservers (); } } class CurrentConditionsDisplay implements Observer { private float temperature ; umiditatea flotorului privat ; private int presiune ; @Override public void update ( temperatura float , umiditate float , presiune int ) { aceasta . temperatura = temperatura ; aceasta . umiditate = umiditate ; aceasta . presiune = presiune ; afișaj (); } public void display () { System . afară . printf ( "Acum valorile sunt: ​​%.1f grade Celsius si %.1f %% umiditate. Presiune %d mmHg\n" , temperatura , umiditatea , presiunea ); } }

C++

Text sursă în C++ #include <iostream> #include <șir> #include <listă> folosind namespace std ; clasa SupervisedString ; clasa IObserver { public : virtual void handleEvent ( const SupervisedString & ) = 0 ; }; class SupervisedString // Clasa observabilă { string_str ; _ lista < IObserver *> _observatori ; void _Notifică () { pentru ( auto & observator : _observers ) { observator -> handleEvent ( * this ); } } public : void add ( IObserver și ref ) { _observatori . push_back ( & ref ); } void remove ( IObserver și ref ) { _observatori . eliminați ( & ref ); } const string & get () const { return_str ; _ } void reset ( șir str ) { _str = str ; _Notifică (); } }; class Reflector : public IObserver // Imprimă șirul observat în cout { public : virtual void handleEvent ( const SupervisedString și ref ) { cout << ref . get () << endl ; } }; class Counter : public IObserver // Imprimă lungimea șirului observat în cout { public : virtual void handleEvent ( const SupervisedString și ref ) { cout << "lungime = " << ref . obține (). lungime () << endl ; } }; int main () { SupervisedString str ; reflector refl ; Contor cnt ; str . adaugă ( refl ); str . resetare ( "Bună ziua, lume!" ); cout << endl ; str . elimina ( refl ); str . adaugă ( cnt ); str . resetare ( „Lumea, Bună!” ); cout << endl ; returnează 0 ; }

ActionScript

Text sursă în ActionScript //file IObserver.as package { public interface IObserver { function notify ( obj : Object ): void ; } } //fișier ExchangeRate.as pachet { public class ExchangeRate { private static var _instance : ExchangeRate = null ; observatori var privați : Array = []; private var _exchangeRate : Obiect ; public function Rata de schimb () { if ( _instance == null ) throw new Error ( 'Model Singleton!' ); } funcția publică statică getInstance (): ExchangeRate { if ( _instance == null ) _instance = new ExchangeRate (); return _instanță ; } public function get exchangeRate (): Object { return _changeRate ; } set de funcții publice exchangeRate ( value : Object ): void { _exchangeRate = value ; aceasta . notifyObservers (); } funcția publică registerObserver ( valoare : IObserver ): void { this . observatori . push ( valoare ); } private function notifyObservers (): void { for each ( var observator : IObserver in this . observatori ) { observator . notifica ( acesta ); } } } } //fișier ProductItem.as pachet { public class ProductItem implementează IObserver { public function ProductItem () { ExchangeRate . getInstance (). registerObserver ( aceasta ); } public function notify ( value : Object ): void { if ( valoarea este ExchangeRate ) { var exchange : ExchangeRate = valoare ca ExchangeRate ; urmă ( exchange.exchangeRate ) ; _ } } } } //file Main.as package { import flash.display.Sprite ; public class Main extinde Sprite { public function Main (): void { var item1 : ProductItem = new ProductItem (); var item2 : ProductItem = nou ProductItem (); Rata de schimb . getInstance (). Rata de schimb = 3,5 ; } } }

VB.NET

Text sursă în limba VB.NET Imports System.Colelections Imports System.Threading Namespace Observer ''' <rezumat> ''' Observer Pattern Judith Bishop Ian 2007 ''' ''' Subiectul rulează într-un fir și își schimbă starea ''' independent. La fiecare schimbare, își anunță observatorii. ''' </summary> Class Program Shared Sub Main () Dim subiect ca nou subiect () Dim Observer ca nou observator ( subiect , „Centru” , vbTab și vbTab ) Dim observator2 ca nou observator ( subiect , „Dreapta” , vbTab & vbTab & vbTab & vbTab ) subiect . du-te () ' Așteptați Consola utilizator . Citiți () End Sub termina clasa Simulatorul de clasă implementează IEnumerable Mișcări private ca șir () = { "5" , "3" , "1" , "6" , "7" } Funcția publică GetEnumerator () Ca IEnumerator implementează IEnumerable . GetEnumerator Returnează mișcările . GetEnumerator ' // Randamentul funcției End End Class Subiectul clasei Delegat public Sub apel invers ( ByVal s As String ) Eveniment public Notificare ca apel invers Simulator privat ca simulator nou () Private m_SubjectState As String Private Const speed As Integer = 200 Proprietatea publică SubjectState () As String Get Return m_SubjectState End Get Set ( ByVal value As String ) m_SubjectState = value End Set End Proprietate Public Sub Go () Apel ( New Thread ( New ThreadStart ( AddressOf Run ))). Start () End Sub Private Sub Run () Pentru fiecare s ca șir în consola simulatorului . WriteLine ( "Subiect: " & s ) SubjectState = s RaiseEvent Notify ( e ) ' milisecunde Thread . Sleep ( viteză ) Next End Sub End Class Interfață IObserver Sub Update ( ByVal state As String ) End Interface Class Observer implementează IObserver Nume privat As String Subiect privat As Subiect Stat privat As String Gap privat As String Subiect public Nou ( Subiect ByVal ca subiect , numele ByVal ca șir , decalajul ByVal ca șir ) Eu . subiect = subiect Eu . nume = numesc pe mine . gap = gap AddHandler subiect . Notificare , AddressOf Update End Sub Actualizare publică sub ( ByVal subjectState As String ) Implementează IObserver . Actualizare stare = subjectStateConsole . _ WriteLine ( gap & name & ": " & state ) End Sub End Class End Namespace

Python

Cod sursă în Python din abc import ABCMeta , abstractmethod Class Observer ( metaclass = ABCMeta ): """ Observator abstract """ @abstractmethod def update ( self , message : str ) -> None : """ Obțineți mesajul nou """ pass clasa Observabil ( metaclasa = ABCMeta ): """ Observabil abstract """ def __init__ ( self ) -> None : """ Constructor. """ self . observatori = [] # initializarea listei de observatori def register ( self , observator : Observer ) -> None : """ Înregistrează un nou observator pentru a se abona la """ self . observatori . anexează ( observator ) def notify_observers ( self , message : str ) -> None : """ Trimite un mesaj tuturor observatorilor abonați la evenimentele obiectului dat din clasa observabilă """ pentru observator în sine . observatori : observator . actualizare ( mesaj ) Class Newspaper ( Observabil ): """ Un ziar care este urmat de mii de oameni """ def add_news ( self , news : str ) -> None : """ Nou comunicat de presă """ self . notify_observers ( stiri ) Class Citizen ( Observator ): """ Un cetățean obișnuit căruia îi place să citească ziarul preferat dimineața """ def __init__ ( self , name : str ) -> None : """ Constructor. :param name: numele cetateanului, pentru a nu-l confunda cu altcineva """ self .name = nume def update ( self , message : str ) -> None : """ Primirea următoarelor știri """ print ( f ' { self . name } a aflat următoarele: { mesaj } ' ) if __name__ == '__main__' : newspaper = Newspaper () # creați un mic ziar de ziar . înregistrare ( Cetăţean ( 'Ivan' )) # adăugaţi două persoane care sunt ziar . înregistrare ( Cetăţean ( 'Vasily' )) # ... este abonat în mod regulat # ... și aruncăm un alt ziar ziar rață . add_news ( 'Observator - Model de design comportamental' ) ''' Ivan a învățat următoarele: Observator - Model de design comportamental Vasily a învățat următoarele: Observator - Model de design comportamental '''

ObjectPascal

Text sursă în Object Pascal (Delphi) observator de program ; /// Modelul observatorului Judith Bishop ian 2007 /// Portat la Pascal de Dmitry Boyarintsev, mai 2018 /// /// Subiectul rulează într-un fir și își schimbă starea /// independent. La fiecare schimbare, își anunță observatorii. {$ifdef fpc}{$mode delphi}{$H+}{$endif} folosește SysUtils , Classes ; tip TBaseObserver = class ( TObject ) procedura Actualizare ( const stat : string ) ; virtual ; abstract ; sfârşitul ; TBaseSubject = procedura de clasă ( TObject ) AddObserver ( aobservator : TBaseObserver ) ; virtual ; abstract ; procedura RemoveObserver ( un observator : TBaseObserver ) ; virtual ; abstract ; procedura NotifyObservers ( const s : string ) ; virtual ; abstract ; sfârşitul ; tip { Subiectul } TSubject = clasă ( TBaseSubject ) fObservers private : TList ; fSimulator : TStringList ; viteza : Integer ; procedură protejată Run ; constructor public Creare ; destructor Distruge ; suprascrie ; procedura AddObserver ( aobserver : TBaseObserver ) ; suprascrie ; procedura RemoveObserver ( un observator : TBaseObserver ) ; suprascrie ; procedura NotifyObservers ( const stat : string ) ; suprascrie ; procedura Go ; sfârşitul ; TObserver = clasa ( TBaseObserver ) fname privat : șir ; fsubject : TBaseSubject ; fstate : șir _ fgap : șir _ constructor public Creare ( asubject : TBaseSubject ; const aname , agap : string ) ; procedura Actualizare ( const stat : string ) ; suprascrie ; sfârşitul ; { Subiectul } procedura TSubiect . alerga ; var i : întreg ; s : șir _ începe pentru i := 0 la fSimulator . Count - 1 do begin s := fSimulator [ i ] ; Writeln ( 'Subiect: ' , s ) ; NotifyObservers ( i ) ; Somn ( viteză ) ; // sfârşitul milisecundelor ; sfârşitul ; constructor TSubject . a crea ; începe moștenit Creare ; fObservers := TList . a crea ; viteza := 200 ; fSimulator := TStringList . a crea ; fSimulator . AddStrings ([ '5' , '3' , '1' , '6' , '7' ]) ; sfârşitul ; destructor TSubiect . Distruge ; începe fObservatori . Gratuit ; fSimulator . Gratuit ; sfârşitul ; procedura TSubiect . AddObserver ( un observator : TBaseObserver ) ; începe fObservatori . Adăugați ( un observator ) ; sfârşitul ; procedura TSubiect . RemoveObserver ( un observator : TBaseObserver ) ; începe fObservatori . Eliminați ( un observator ) ; sfârşitul ; procedura TSubiect . NotifyObservers ( const stat : string ) ; var i : întreg ; începe pentru i := 0 la fObservers . Count - 1 do TBaseObserver ( fObservers [ i ] ) . Actualizare ( statut ) ; sfârşitul ; tip { TMethodThread } TMethodThread = clasă ( TThread ) protejat fMethod : TThreadMethod ; procedura Execut ; suprascrie ; constructor public Creare ( AMethod : TThreadMethod ) ; sfârşitul ; { TMethodThread } constructor TMethodThread . Creare ( AMethod : TThreadMethod ) ; începe fMetodă := AMetodă ; FreeOnTerminate := Adevărat ; moştenit Creare ( fals ) ; sfârşitul ; procedura TMethodThread . Execută ; începe dacă este atribuit ( fMethod ) apoi fMethod () ; sfârşitul ; procedura TSubiect . du-te ; începe TMethodThread . Creați ( Self.Run ) ; _ _ sfârşitul ; constructor TObserver . Creare ( asubiect : TBaseSubject ; const aname , agap : string ) ; începe moștenit Creare ; fsubiect := asubiect ; fname := aname ; fgap := agap ; dacă este atribuit ( fsubject ) atunci fsubject . AddObserver ( auto ) ; sfârşitul ; procedura TObserver . Actualizare ( const stat : string ) ; begin fstate := stat ; writeln ( fgap , fname , ': ' , stat ) ; sfârşitul ; /// Programul principal var subiect : TSubiect ; observator : TObserver ; observator2 : TObserver ; beginsubject : = TSubiect . a crea ; observator := TObserver . Creați ( subiect , „Centru” , #9#9 ) ; observator2 := TObserver . Creați ( subiect , „Dreapta” , #9#9#9#9 ) ; incearca subiectul . mergi () ; // Așteptați utilizatorul readln ; în sfârşit observator . Gratuit ; observator2 . Gratuit ; subiect . Gratuit ; sfârşitul ; sfârşitul .

Ruby

Cod sursă Ruby module Observable def initialize @observers = [] end def add_observer ( observator ) @observers << observator cu excepția cazului în care @observers . include? ( observator ) sfârşit def delete_observer ( observator ) @observers . şterge ( observator ) sfârşit def notify_observers @observers . fiecare { | x | x . update ( self )} sfârşit sfârşit Clasa Angajat include Observable attr_reader :nume attr_accessor :title , :salary def initialize ( nume , titlu , salariu ) super ( ) @nume = nume @titlu = titlu @salariu = sfarsitul salariului class BaseObserver def update raise „Trebuie să implementeze funcția „actualizare”” end end class Salarizare < BaseObserver def update ( angajat ) p ( „Tăiați un nou cec pentru #{ angajat . nume } !” ) p ( „Salariul lui este acum #{ angajat . salariu } !” ) end end class TaxMan < BaseObserver def update ( angajat ) p ( „Trimite #{ angajat . nume } o nouă factură fiscală!” ) end end mike = Angajat . nou ( „Mike” , „proiect manager” , 25000 ) mike . add_observer ( Salarizare . nou ) mike . add_observer ( TaxMan . nou ) mike . salariu = 35000 mike . title = 'senior project manager' mike . notify_observers =begin Rezultatul „Tăiați un nou cec pentru Mike!” "Salariu lui este acum 35000!" „Trimite-i lui Mike o nouă factură fiscală!” =sfarsit

Rugina

Cod sursă în Rust /// Exemplul descrie cum să primiți date de la o stație meteo (structură WeatherData, dispecer de evenimente) și /// folosiți-l pentru a le afișa pe ecran (structura CurrentConditionsDisplay, ascultător de evenimente). /// Ascultătorul este înregistrat cu observatorul folosind metoda register_observer, care are o închidere și /// îl adaugă la lista de observatori. Când datele meteo se modifică, este apelată metoda notify_observers, care închide /// toți ascultătorii, transmițându-le datele actualizate. utilizați std :: rc :: Rc ; utilizați std :: cell :: RefCell ; tip ObserverFn = Box < dyn Fn ( f32 , f32 , i32 ) > ; trăsătură observabilă { fn register_observer ( & mut self , o : ObserverFn ) -> usize ; fn remove_observer ( & mut self , idx : use ); fn notify_observers ( & mut self ); } #[deriva (implicit)] struct WeatherData { observatori : Vec < ObserverFn > ​​, temperatura : f32 , umiditate : f32 , presiune : i32 , } impl WeatherData { fn set_measurements ( & mut self , temperatura : f32 , umiditate : f32 , presiune : i32 ) { sine . temperatura = temperatura ; sine . umiditate = umiditate ; sine . presiune = presiune ; sine . notify_observers (); } } impl Observabil pentru WeatherData { fn register_observer ( & mut self , o : ObserverFn ) -> use { sine . observatori . împinge ( o ); sine . observatori . len () - 1 } fn remove_observer ( & mut self , idx : usize ) { sine . observatori . elimina ( idx ); } fn notify_observers ( & mut self ) { pentru observator în sine . observatori . iter () { ( * observator )( auto . temperatură , sine . umiditate , auto . presiune ); } } } #[deriva (implicit)] struct CurrentConditionsDisplay { temperatura : f32 , umiditate : f32 , presiune : i32 , } impl CurrentConditionsDisplay { fn display ( & self ) { println! ( "Acum valorile sunt: ​​{:.1} grade Celsius și {:.1} % umiditate. Presiune {} mmHg." , sine . temperatura , sine . umiditate , sine . presiune ); } actualizare fn ( & mut self , temperatura : f32 , umiditate : f32 , presiune : i32 ) { sine . temperatura = temperatura ; sine . umiditate = umiditate ; sine . presiune = presiune ; sine . afișaj (); } } fn principal () { let mut weather_data = WeatherData :: implicit (); let current_display = Rc :: new ( RefCell :: new ( CurrentConditionsDisplay :: implicit ())); fie observator = curent_afișare . clona (); meteo_date . register_observer ( Box :: new ( mutare | t , h , p | observator . borrow_mut (). update ( t , h , p ))); meteo_date . set_measurements ( 29,0 , 65,0 , 745 ); meteo_date . set_measurements ( 39,0 , 70,0 , 760 ); meteo_date . set_measurements ( 42,0 , 72,0 , 763 ); }

io

Io cod sursă # Un exemplu este complet identic cu cel de mai sus în Python Observator := Clona obiect Observabil := Listă clona do ( registrează := getSlot ( "push" ) notify := metodă ( mesaj , self foreach ( observator , actualizare observator ( mesaj ))) ) Ziar := Clonă observabilă do ( addNews := metodă ( știri , notifica ( știri ))) Citizen := Observer clone do ( create := metoda ( nume , autoclonare lexicalDo ( nume := nume )) update := metoda ( mesaj , writeln ( nume .. " a aflat: " .. mesaj )) ) ziar := Clonă de ziar ziar do ( înregistrați ( Citizen create ( „Ivan” ) )) register ( Citizen create ( „Vasily” )) addNews ( „Observer - Behavioral Design Pattern” ) ) #>>>> Ivan a învățat următoarele: Observatorul este un model de design comportamental #>>>> Vasily a învățat următoarele: Observatorul este un model de design comportamental

JavaScript ES6

Text sursă în javascript class Observable { constructor () { this . ascultători = {}; } // Abonati-va. on ( e , callback ) { if ( this . listeners [ e ] == nedefinit ) { this . ascultători [ e ] = {}; aceasta . ascultători [ e ]. eventProperty = {}; aceasta . ascultători [ e ]. eventProperty . isOnOnce = fals ; aceasta . ascultători [ e ]. date = []; } aceasta . ascultători [ e ]. date . push ( callback ); } // Abonați-vă o dată. onOnce ( e , callback ) { this . on ( e , callback ); aceasta . ascultători [ e ]. eventProperty . isOnOnce = adevărat ; } // Dezabonare. off ( e , apel invers ) { this . ascultători [ e ]. date = asta . ascultători [ e ]. date . filtru ( function ( ascultător ) { return listener !== callback ; }); } // Trimite mesaj către abonați. emit ( e , date ) { dacă ( acest . ascultători [ e ] == nedefinit || acest . ascultători [ e ]. date == nedefinit ) { return ; } let itObj = this ; aceasta . ascultători [ e ]. date . forEach ( listener => { if ( itObj . listeners [ e ] eventProperty . isOnOnce ) { itObj . off ( e , itObj . listeners [ e ]. data [ 0 ]); } listener ( data ); }); } }

Informații suplimentare

În .NET Framework 4.0 , modelul de proiectare al observatorului este implementat prin implementarea interfețelor generice System.IObservable<T>și System.IObserver<T>[2] .

Literatură

  • Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides . Tehnici de proiectare orientată pe obiecte. Design Patterns = Design Patterns. Elemente de software reutilizabil orientat pe obiecte. - Sankt Petersburg. : Peter, 2009. - 366 p. - ISBN 978-5-469-01136-1 .
  • Eric Freeman, Elizabeth Freeman. Modele de design = Head First Design Patterns. - Sankt Petersburg. : Peter, 2011. - 656 p. - ISBN 978-5-459-00435-9 .

Note

  1. Modelul de observator . Consultat la 13 iunie 2013. Arhivat din original pe 13 iunie 2013.
  2. 1 2 Model de proiectare Observer . Consultat la 13 iunie 2013. Arhivat din original pe 13 iunie 2013.
  3. Modelul de observator . Preluat la 4 noiembrie 2019. Arhivat din original la 4 noiembrie 2019.