Megfigyelő (tervezési minta)

Az oldal jelenlegi verzióját még nem ellenőrizték tapasztalt közreműködők, és jelentősen eltérhet a 2019. május 19-én felülvizsgált verziótól ; az ellenőrzések 15 szerkesztést igényelnek .
Megfigyelő
Megfigyelő
Típusú viselkedési
Célja
  • Az Observer minta egy-többhöz függőséget határoz meg az objektumok között, így ha egy objektum állapota megváltozik, az összes attól függő objektum automatikusan értesítést kap és frissül;
  • Az Observer minta a fő (független) komponenst tartalmazza a Tárgy absztrakcióban és a változtatható (függő) komponenseket a Megfigyelő hierarchiában;
  • Az Observer minta egy Model-View-Controller (MVC) modell "View" részét határozza meg [1] .
Leírása: Tervezési minták Igen

Az  Observer egy viselkedési tervezési minta . _ Más néven "beosztottak" ( eng. Dependents ). Osztálymechanizmust valósít meg, amely lehetővé teszi, hogy ennek az osztálynak az objektumai értesítéseket kapjanak más objektumok állapotának változásairól, és ezáltal megfigyeljék azokat [2] .  

Azokat az osztályokat, amelyek eseményeire más osztályok előfizetnek, alanyoknak, a feliratkozó osztályokat Observereknek [ 3 ] nevezzük . 

Hasonló sablonok: " kiadó-előfizető ", " közvetítő ", " magányos ".

Időpont

Egy a többhez függőséget határoz meg az objektumok között, így amikor egy objektum állapota megváltozik, az összes tőle függő értesítést kap az eseményről.

Megvalósítás

A megfigyelői minta implementálásakor általában a következő osztályokat használják:

Hatókör

A megfigyelő mintát akkor használjuk, ha a rendszer a következő tulajdonságokkal rendelkezik:

Ezt a mintát gyakran alkalmazzák olyan helyzetekben, amikor az üzenet küldőjét nem érdekli, mit kezdenek a címzettek a nekik adott információval.

Példák

PHP5 (SPL)

Forrás szöveg php nyelven /** * A PHP beépített támogatást biztosít ehhez a mintához a mellékelt * SPL (Standard PHP Library) kiterjesztésen keresztül: * SplObserver - interfész az Observer számára (megfigyelő), * SplSubject - a megfigyelhető (megfigyelhető), * SplObjectStorage - segédosztály (javított * objektumok mentését és törlését biztosítja, különös tekintettel az attach() és detach() metódusok megvalósítására). */ class Megfigyelhető implements SplSubject { private $storage ; function __construct () { $this -> storage = new SplObjectStorage (); } function csatolás ( SplObserver $observer ) { $this -> storage -> attach ( $observer ); } function detach ( SplObserver $observer ) { $this -> storage -> detach ( $observer ); } function notify () { foreach ( $this -> storage as $obj ) { $obj -> update ( $this ); } } } class ConcreteObserver implementálja a SplObservert { private $megfigyelhető ; privát $index ; function __construct ( Megfigyelhető $megfigyelhető ) { static $sindex = 0 ; $this -> index = $sindex ++ ; $ez -> megfigyelhető = $megfigyelhető ; $megfigyelhető -> csatolja ( $this ); } function update ( SplSubject $subject ) { if ( $subject === $this -> observable ) { echo "Értesítés küldése a ConcreteObservernek [ $this->index ] \n " ; } } } $megfigyelhető = new Megfigyelhető (); új ConcreteObserver ( $megfigyelhető ); új ConcreteObserver ( $megfigyelhető ); új ConcreteObserver ( $megfigyelhető ); $megfigyelhető -> értesít ();

PHP5

Forrás szöveg php nyelven interface Observer { function notify ( $obj ); } class Árfolyam { static private $példány = NULL ; privát $megfigyelők = array (); privát $árfolyam ; privát függvény __construct () {} privát függvény __klón () {} static public function getInstance () { if ( self :: $példány == NULL ) { self :: $példány = new ExchangeRate (); } return self :: $példány ; } public function getExchangeRate () { return $this -> árfolyam ; } public function setExchangeRate ( $új_árfolyam ) { $this -> árfolyam = $új_árfolyam ; $this -> notifyObservers (); } public function registerObserver ( Observer $obj ) { $this -> megfigyelők [] = $obj ; } function notifyObservers () { foreach ( $this -> megfigyelők mint $obj ) { $obj -> notify ( $this ); } } } osztály ProductItem megvalósítja az Observert { public function __construct () { ExchangeRate :: getInstance () -> registerObserver ( $this ); } public function notify ( $obj ) { if ( $obj instanceof ExchangeRate ) { // Árfolyamadatok frissítése print "Frissítés érkezett! \n " ; } } } $termék1 = új termékelem (); $termék2 = új Termékelem (); ExchangeRate :: getInstance () -> setExchangeRate ( 4.5 );

C#

Forrásszöveg C# nyelven a rendszer használatával ; a System.Collections használatával ; a System.Collections.Generic használatával ; a System.Threading használatával ; névtér Megfigyelő { /// <összefoglaló> /// Observer Pattern Judith Bishop 2007. jan. /// Frissítette: Kobel' Bohdan 2013 /// /// Az alany egy szálban fut, és /// függetlenül változtatja állapotát . Minden változásnál értesíti a Megfigyelőit. /// </summary> class Program { static void Main ( string [] args ) { Subject tárgy = new Subject (); Megfigyelő megfigyelő = new Observer ( tárgy , "Közép" , "\t\t" ); Observer megfigyelő2 = new Observer ( tárgy , "Jobb" , "\t\t\t\t" ); tárgy . megy (); // Várja meg a felhasználói konzolt . olvasni (); } } class Simulator : IEnumerable { string [] moves = { "5" , "3" , "1" , "6" , "7" }; public IEnumerator GetEnumerator () { foreach ( karakterlánc elem a mozgásokban ) hozam return elem ; } } interface ISubject { void AddObserver ( IObserver megfigyelő ); void RemoveObserver ( IObserver megfigyelő ); void NotifyObservers ( string s ); } class Tárgy : ISubject { public string SubjectState { get ; készlet ; } public List < IObserver > Megfigyelők { get ; magánkészlet ; _ } privát szimulátor szimulátor ; privát const int sebesség = 200 ; public Subject () { Megfigyelők = new List < IObserver >(); szimulátor = új Szimulátor (); } public void AddObserver ( IObserver megfigyelő ) { Megfigyelők . Add ( megfigyelő ); } public void RemoveObserver ( IObserver megfigyelő ) { Megfigyelők . Eltávolítás ( megfigyelő ); } public void NotifyObservers ( karakterláncok ) { foreach ( var megfigyelő a Megfigyelőkben ) { megfigyelő . _ Frissítés ( ek ); } } public void Go () { new Thread ( new ThreadStart ( Futtatás )). Indítás ( ); } void Futtatás ( ) { foreach ( karakterlánc a szimulátorban ) { Konzol . WriteLine ( "Tárgy: " + s ); SubjectState = s ; NotifyObservers ( ek ); szál . alvás ( sebesség ); // ezredmásodperc } } } interface IObserver { void Frissítés ( karakterlánc állapota ); } class Megfigyelő : IObserver { string name ; IStárgy tárgy ; karakterlánc állapota ; húrrés ; _ public Observer ( ISubject tárgy , karakterlánc neve , string gap ) { this . tárgy = alany ; ezt . név = név ; ezt . rés = rés ; tárgy . AddObserver ( ez ); } public void Frissítés ( string subjectState ) { state = tárgyállapot ; Konzol . WriteLine ( hézag + név + ": " + állapot ); } } }

Java

Java forrás // A példa leírja, hogyan lehet adatokat fogadni egy meteorológiai állomástól (WeatherData osztály, esemény diszpécser) és //azokat használni a képernyőn való megjelenítéséhez (CurrentConditionsDisplay osztály, eseményfigyelő). //A figyelő a registerObserver metódussal van regisztrálva a megfigyelőnél (ebben az esetben a figyelő felkerül a megfigyelők listájára). //A regisztráció a currentDisplay objektum létrehozásának pillanatában történik, mert a registerObserver metódust alkalmazzuk a konstruktorban. //Amikor az időjárási adatok megváltoznak, a notifyObservers metódus meghívásra kerül, ami viszont meghívja az update metódust //az összes hallgatón, átadva nekik a frissített adatokat. 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 (); időjárásadatok . registerObserver ( currentDisplay ); időjárásadatok . setMeasurements ( 29 f , 65 f , 745 ); időjárásadatok . setMeasurements ( 39 f , 70 f , 760 ); időjárásadatok . setMeasurements ( 42 f , 72 f , 763 ); } } interfész Observer { void update ( lebegő hőmérséklet , úszó páratartalom , belső nyomás ); } interface Megfigyelhető { void registerObserver ( Observer o ); void removeObserver ( Observer o ); void notifyObservers (); } osztály WeatherData megvalósítja a Megfigyelhető { private List < Observer > megfigyelőket ; privát úszó hőmérséklet ; privát úszó páratartalom ; privát int nyomás ; public WeatherData () { megfigyelők = new LinkedList <> (); } @Override public void registerObserver ( Observer o ) { megfigyelők . add ( o ); } @Override public void removeObserver ( Observer o ) { megfigyelők . eltávolítás ( o ); } @Override public void notifyObservers () { for ( Megfigyelő megfigyelő : megfigyelők ) megfigyelő . frissítés ( hőmérséklet , páratartalom , nyomás ); } public void setMeasurements ( úszó hőmérséklet , úszó páratartalom , belső nyomás ) { this . hőmérséklet = hőmérséklet ; ezt . páratartalom = páratartalom ; ezt . nyomás = nyomás ; notifyObservers (); } } class CurrentConditionsDisplay implements Observer { private float temperature ; privát úszó páratartalom ; privát int nyomás ; @Public void frissítés felülbírálása ( lebegő hőmérséklet , úszó páratartalom , belső nyomás ) { this . hőmérséklet = hőmérséklet ; ezt . páratartalom = páratartalom ; ezt . nyomás = nyomás ; kijelző (); } public void display () { Rendszer . ki . printf ( "Most az értékek: %.1f Celsius fok és %.1f %% páratartalom. Nyomás %d Hgmm\n" , hőmérséklet , páratartalom , nyomás ); } }

C++

Forrásszöveg C++ nyelven #include <iostream> #include <karakterlánc> #include <list> névtér használata std ; osztály FelügyeltString ; osztályú IObserver { nyilvános : virtual void handleEvent ( const FelügyeltString & ) = 0 ; }; class SupervisedString // Megfigyelhető osztály { string_str ; _ lista < IObserver *> _observers ; érvénytelen _Értesítés () { for ( auto & megfigyelő : _observers ) { megfigyelő -> handleEvent ( * this ); } } nyilvános : érvénytelen hozzáadás ( IObserver & ref ) { _megfigyelők . push_back ( & ref ); } érvénytelen eltávolítás ( IObserver & ref ) { _megfigyelők . eltávolítás ( & ref ); } const string & get () const { return_str ; _ } void reset ( string str ) { _str = str ; _Értesítés (); } }; class Reflector : public IObserver // A megfigyelt karakterláncot kiírja cout { nyilvános : virtuális void handleEvent ( const SupervisedString & ref ) { cout << ref . get () << endl ; } }; class Számláló : public IObserver // Kiírja a megfigyelt karakterlánc hosszát cout { nyilvános : virtuális void handleEvent ( const SupervisedString & ref ) { cout << "length = " << ref . kap (). hossz () << endl ; } }; int main () { FelügyeltString str ; reflektor refl ; Számláló cnt ; str . add ( refl ); str . reset ( "Hello, World!" ); cout << endl ; str . eltávolítani ( refl ); str . add ( cnt ); str . reset ( "Világ, helló!" ); cout << endl ; return 0 ; }

ActionScript

Forrásszöveg az ActionScriptben //fájl IObserver.as package { public interface IObserver { function notify ( obj : Object ): void ; } } //fájl ExchangeRate.as package { public class Árfolyamérték { private static var _instance : ExchangeRate = null ; private var megfigyelők : Array = []; private var _exchangeRate : Objektum ; 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 ( érték : Object ): void { _exchangeRate = érték ; ezt . notifyObservers (); } public function registerObserver ( érték : IObserver ): void { this . megfigyelők . push ( érték ); } private function notifyObservers ( ) : void { for every ( var megfigyelő : IObserver ebben . megfigyelők ) { megfigyelő . értesíteni ( ezt ); } } } } //file ProductItem.as package { public class ProductItem implements IObserver { public function ProductItem () { ExchangeRate . getInstance (). registerObserver ( ez ); } public function notify ( érték : objektum ) : void { if ( az érték ExchangeRate ) { var Exchange : ExchangeRate = Árfolyam értéke ; nyomkövetés ( Exchange.exchangeRate ) ; _ } } } } //fájl 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 (); Árfolyam . getInstance (). árfolyam = 3,5 ; } } }

VB.NET

Forrásszöveg VB.NET nyelven Importálás System.Collections Imports System.Threading Névtér Megfigyelő ''' <összegzés> ''' Megfigyelő minta Judith Bishop 2007. jan. ''' ''' Az alany egy szálban fut, és függetlenül változtatja állapotát ''''. Minden változásnál értesíti a Megfigyelőit. '''' </summary> Osztály Program Megosztott alfő ( ) Halvány tárgy új témaként ( ) Halvány megfigyelő új megfigyelőként ( tárgy , " Közép " , vbTab & vbTab ) Halvány megfigyelő2 Új megfigyelőként ( tárgy , "Jobb" , vbTab & vbTab & vbTab & vbTab ) tárgy . menj () Várja meg a felhasználói konzolt . Olvassa el () End Sub végi osztály Az osztályszimulátor IEnumerable privát mozgásokat valósít meg karakterláncként ( ) = { "5" , "3" , "1" , "6" , "7" } Nyilvános függvény GetEnumerator () Ahogy az IEnumerator megvalósítja az IEnumerable -t . GetEnumerator Return lépések . GetEnumerator ' // Hozamvégi függvény végosztálya Osztály alany nyilvános delegált alhívás ( ByVal s As String ) _ Nyilvános eseményértesítés visszahívásként Privát szimulátor új szimulátorként ( ) Privát m_SubjectState karakterláncként Privát Const sebesség egész számként = 200 _ _ _ Public Property SubjectState () As String Get Return m_SubjectState End Get Set ( ByVal érték As String ) m_SubjectState = érték End Set End Tulajdonság Nyilvános Sub Go () Hívás ( Új szál ( New ThreadStart ( AddressOf Run ))). Kezdés () Vége Sub Privát alfutás ( ) Minden s karakterláncként szimulátorkonzolban . _ _ _ _ WriteLine ( "Tárgy: " & s ) SubjectState = s RaiseEvent Notify ( s ) ' ezredmásodperc Thread . Alvás ( sebesség ) Következő End Sub End Class Interfész IObserver Sub Update ( ByVal állapot As String ) End Interface Class Observer Az IObservert valósítja meg Privát név Karakterláncként Privát tárgy Tárgyként Privát állapot Karakterláncként Privát rés Karakterláncként _ _ _ _ Public Sub New ( ByVal tárgy As Subject , ByVal név As String , ByVal gap As String ) Me . tárgy = tárgy Én . név = név Én . rés = hézag AddHandler tárgy . Értesítés , AddressOf Update End Sub Nyilvános alfrissítés ( ByVal subjectState As String ) Az IObservert valósítja meg . Állapot frissítése = tárgyStateConsole . _ WriteLine ( hézag & név & ": " & állapot ) End Sub End Class End névtér

Python

Forráskód Pythonban abc importból ABCMeta , abstractmethod _ osztály megfigyelő ( metaosztály = ABCMeta ): """ Absztrakt megfigyelő """ @abstractmethod def update ( self , message : str ) -> None : """ Get new message """ pass osztály Megfigyelhető ( metaclass = ABCMeta ): """ Absztrakt megfigyelhető """ def __init__ ( self ) -> None : """ Konstruktor. """ self . megfigyelők = [] # a megfigyelők listájának inicializálása def register ( self , megfigyelő : Megfigyelő ) -> None : """ Új megfigyelő regisztrálása """ self feliratkozáshoz . megfigyelők . hozzáfűz ( megfigyelő ) def notify_observers ( self , message : str ) -> None : """ Üzenet küldése minden olyan megfigyelőnek, aki feliratkozott a """ megfigyelhető osztály adott objektumának eseményeire az önmagában megfigyelő számára . megfigyelők : megfigyelő . frissítés ( üzenet ) osztály Újság ( Megfigyelhető ): """ Több ezer ember által követett újság """ def add_news ( self , news : str ) -> None : """ Új hírközlés " "" self . notify_observers ( hírek ) osztályú polgár ( Figyelő ): """ Egy hétköznapi polgár, aki szereti reggelente olvasni kedvenc újságját """ def __init__ ( self , name : str ) -> None : """ Konstruktor. :param név: az állampolgár neve , nehogy összetévessze valaki mással """ self .name = név def update ( self , message : str ) -> None : """ A következő hír beszerzése """ print ( f ' { self . name } a következőket tanulta: { üzenet } ' ) if __name__ == '__main__' : newspaper = Újság () # hozzon létre egy kis újságot . register ( Citizen ( 'Ivan' )) # adj hozzá két újságos embert . regisztráció ( Polgár ( 'Vaszilij' )) # ... rendszeresen előfizetik # ... és bedobunk egy másik újság kacsa újságot . add_news ( 'Megfigyelő - Viselkedési tervezési minta' ) '' Iván a következőket tanulta: Megfigyelő - Viselkedési tervezési minta Vaszilij a következőket tanulta: Megfigyelő - Viselkedési tervezési minta '''

ObjectPascal

Forrásszöveg Object Pascalban (Delphi) programfigyelő ; _ /// Observer Pattern Judith Bishop 2007. jan. /// Pascalra portolta Dmitry Boyarintsev, 2018. május /// /// Az alany egy szálban fut, és /// függetlenül változtatja állapotát . Minden változásnál értesíti a Megfigyelőit. {$ifdef fpc}{$mode delphi}{$H+}{$endif} SysUtils , Classes ; _ típus TBaseObserver = osztály ( TObject ) eljárás Frissítés ( const astate : string ) ; virtuális ; absztrakt ; vége ; TBaseSubject = osztály ( TObject ) eljárás AddObserver ( aobserver : TBaseObserver ) ; virtuális ; absztrakt ; eljárás RemoveObserver ( aobserver : TBaseObserver ) ; virtuális ; absztrakt ; eljárás NotifyObservers ( const s : string ) ; virtuális ; absztrakt ; vége ; típus { TSubject } TSubject = osztály ( TBaseSubject ) privát fObszerverek : TLista ; fSzimulátor : TStringList ; sebesség : Integer ; védett eljárás Futtatás ; public konstruktor Létrehozás ; destructor Elpusztítani ; felülbírálni ; eljárás AddObserver ( aobserver : TBaseObserver ) ; felülbírálni ; eljárás RemoveObserver ( aobserver : TBaseObserver ) ; felülbírálni ; eljárás NotifyObservers ( konst állapot : string ) ; felülbírálni ; eljárás Go ; vége ; TObserver = osztály ( TBaseObserver ) private fname : string ; fsubject : TBaseSubject ; fstate : string_ _ fgap : string_ _ public konstruktor Create ( abject : TBaseSubject ; const aname , agap : string ) ; procedúra Frissítés ( const astate : string ) ; felülbírálni ; vége ; { TSubject } eljárás TSubject . futni ; var i : integer ; s : string_ _ start for i := 0 az fSimulatorhoz . Count - 1 do begin s := fSimulator [ i ] ; Writeln ( 'Tárgy: ' , s ) ; NotifyObservers ( ek ) ; Alvás ( sebesség ) ; // ezredmásodperc vége ; vége ; konstruktor TSubject . létrehozni ; begin inherited Create ; fObservers := TLista . létrehozni ; sebesség := 200 ; fSimulator := TStringList . létrehozni ; fSzimulátor . AddStrings ([ '5' , '3' , '1' , '6' , '7' ]) ; vége ; destructor TSubject . elpusztítani ; indítsa el a fObservers-t . Ingyenes ; fSzimulátor . Ingyenes ; vége ; eljárás TSubject . AddObserver ( megfigyelő : TBaseObserver ) ; indítsa el a fObservers-t . Add ( aobserver ) ; vége ; eljárás TSubject . RemoveObserver ( megfigyelő : TBaseObserver ) ; indítsa el a fObservers-t . Eltávolítás ( aobserver ) ; vége ; eljárás TSubject . NotifyObservers ( const astate : string ) ; var i : integer ; Kezdje az i := 0 -hoz az fObservershez . Számlálás - 1 do TBaseObserver ( fObservers [ i ]) . Frissítés ( astate ) ; vége ; típus { TMethodThread } TMethodThread = osztály ( TThread ) védett fMethod : TThreadMethod ; eljárás Végrehajtás ; felülbírálni ; public konstruktor Create ( AMethod : TThreadMethod ) ; vége ; { TMethodThread } konstruktor TMethodThread . Létrehozás ( AMethod : TThreadMethod ) ; begin fMethod := AMethod ; FreeOnTerminate := Igaz ; öröklött Létrehozás ( hamis ) ; vége ; eljárás TMethodThread . Végrehajtás ; kezdődik , ha Assigned ( fMethod ) then fMethod () ; vége ; eljárás TSubject . menj ; kezdje el a TMethodThread programot . Létrehoz ( Self.Run ) ; _ _ vége ; konstruktor TObserver . Create ( asubject : TBaseSubject ; const aname , agap : string ) ; begin inherited Create ; fsubject := alattject ; fname := név ; fgap := agap ; ha Assigned ( fsubject ) akkor fsubject . AddObserver ( saját ) ; vége ; eljárás TObserver . Frissítés ( const astate : string ) ; begin fstate := astate ; writeln ( fgap , fname , ':' , állapot ) ; vége ; /// Fő program var tárgy : TSubject ; megfigyelő : TObserver ; megfigyelő2 : TOmegfigyelő ; beginsubject : = TSubject . létrehozni ; megfigyelő := TObserver . Létrehoz ( tárgy , 'Közép' , #9#9 ) ; megfigyelő2 := TOmegfigyelő . Létrehozása ( tárgy , 'Jobb' , #9#9#9#9 ) ; próbáld ki a témát . menj () ; // Várja meg a readln felhasználót ; végre megfigyelő . Ingyenes ; megfigyelő2 . Ingyenes ; tárgy . Ingyenes ; vége ; vége .

Ruby

Ruby forráskód modul Megfigyelhető def inicializálás @observers = [] vége def add_observer ( megfigyelő ) @observers << megfigyelő , hacsak nem @observers . tartalmazza? ( megfigyelő ) vége def delete_observer ( megfigyelő ) @observers . törlés ( megfigyelő ) vége def notify_observers @observers . mindegyik { | x | x . frissítés ( self )} end end osztály Munkavállalói közé tartozik Megfigyelhető attr_reader :name attr_accessor :title , :fizetés def inicializálás ( név , beosztás , fizetés ) szuper ( ) @ név = név @ cím = cím @fizetés = fizetés vége vége osztály BaseObserver def update lift 'Meg kell valósítani a "frissítési" funkciót' end end class Bérszámfejtés < BaseObserver def update ( alkalmazott ) p ( "Új csekk kivágása #{ alkalmazott . neve } !" ) p ( " A fizetése most #{ alkalmazott . fizetés } !" ) end end osztály TaxMan < BaseObserver def update ( alkalmazott ) p ( "Küldj #{ alkalmazott . neve } új adószámlát!" ) end end mike = Alkalmazott . új ( 'Mike' , 'projektmanger' , 25000 ) Mike . add_observer ( Bérszámfejtés . új ) mike . add_observer ( TaxMan . új ) Mike . fizetés = 35000 mike . title = 'vezető projektmenedzser' mike . notify_observers =begin A "Vágjon új csekket Mike-nak!" "Most 35000 a fizetése!" – Küldj új adószámlát Mike-nak! =vége

Rozsda

Forráskód Rustban /// A példa leírja, hogyan lehet adatokat fogadni egy meteorológiai állomástól (WeatherData szerkezet, esemény diszpécser) és /// használni a képernyőn való megjelenítéséhez (CurrentConditionsDisplay szerkezet, eseményfigyelő). /// A figyelőt a register_observer metódussal regisztráljuk a megfigyelővel, amely egy lezárást végez és /// hozzáadja a megfigyelők listájához. Amikor az időjárási adatok megváltoznak, a notify_observers metódus meghívódik, amely /// bezárja az összes figyelőt, átadva nekik a frissített adatokat. használja std :: rc :: Rc ; std használata :: cella :: RefCell ; típus ObserverFn = Box < dyn Fn ( f32 , f32 , i32 ) > ; Megfigyelhető tulajdonság { fn register_observer ( & mut self , o : ObserverFn ) -> usize ; fn remove_observer ( & mut self , idx : usize ); fn notify_observers ( & mut self ); } #[derive (alapértelmezett)] struct WeatherData { megfigyelők : Vec < ObserverFn > , hőmérséklet : f32 , páratartalom : f32 , nyomás : i32 , } impl Időjárásadatok { fn set_measurements ( & mut self , hőmérséklet : f32 , páratartalom : f32 , nyomás : i32 ) { önmaga . hőmérséklet = hőmérséklet ; önmaga . páratartalom = páratartalom ; önmaga . nyomás = nyomás ; önmaga . notify_observers (); } } impl Megfigyelhető időjárási adatokhoz { fn register_observer ( & mut self , o : ObserverFn ) -> usize { önmaga . megfigyelők . nyomni ( o ); önmaga . megfigyelők . len () - 1 } fn remove_observer ( & mut self , idx : usize ) { önmaga . megfigyelők . eltávolítás ( idx ); } fn notify_observers ( & mut self ) { önmagában megfigyelő számára . _ megfigyelők . iter () { ( * megfigyelő )( saját . hőmérséklet , saját . páratartalom , saját . nyomás ); } } } #[derive (alapértelmezett)] struct CurrentConditionsDisplay { hőmérséklet : f32 , páratartalom : f32 , nyomás : i32 , } impl CurrentConditionsDisplay { fn display ( & self ) { println! ( "Most az értékek: {:.1} Celsius-fok és {:.1} % páratartalom. Nyomás {} Hgmm." , önmaga . hőmérséklet , önmaga . páratartalom , önmaga . nyomás ); } fn frissítés ( & mut self , hőmérséklet : f32 , páratartalom : f32 , nyomás : i32 ) { önmaga . hőmérséklet = hőmérséklet ; önmaga . páratartalom = páratartalom ; önmaga . nyomás = nyomás ; önmaga . kijelző (); } } fn main () { let mut weather_data = Időjárási adatok :: alapértelmezett (); let current_display = Rc :: new ( RefCell :: new ( CurrentConditionsDisplay :: default ())); let megfigyelő = aktuális_megjelenítés . klón (); weather_data . register_observer ( Box :: new ( mozgás | t , h , p | megfigyelő . kölcsön_mut (). update ( t , h , p ))); weather_data . set_measurements ( 29.0 , 65.0 , 745 ); weather_data . set_measurements ( 39.0 , 70.0 , 760 ); weather_data . set_measurements ( 42.0 , 72.0 , 763 ); }

io

Io forráskód # Egy példa teljesen megegyezik a fentivel a Pythonban Observer := Objektum klón Megfigyelhető := List klón do ( regiszter := getSlot ( "push" ) notify := method ( üzenet , saját foreach ( megfigyelő , megfigyelő frissítés ( üzenet ))) ) Newspaper := Megfigyelhető klón do ( addNews := metódus ( hír , értesíteni ( hír ))) Citizen := Observer clone do ( create := metódus ( név , önklón lexicalDo ( név := név )) update := metódus ( üzenet , writeln ( név .. " megtudta: " .. üzenet ) ) ) újság : = Újságklón újság do ( regiszter ( Citizen create ( "Ivan" ) )) regisztrál ( Citizen create ( "Vaszilij" )) addNews ( "Observer - Behavioral Design Pattern" ) ) #>>>> Iván a következőket tanulta: A megfigyelő egy viselkedési tervezési minta #>>>> Vaszilij megtanulta a következőket: A megfigyelő egy viselkedési tervezési minta

JavaScript ES6

Forrásszöveg javascriptben class Megfigyelhető { konstruktor () { this . hallgatók = {}; } // Iratkozz fel. on ( e , visszahívás ) { if ( this . hallgatók [ e ] == undefined ) { this . hallgatók [ e ] = {}; ezt . hallgatók [ e ]. eventProperty = {}; ezt . hallgatók [ e ]. eventProperty . isOnOnce = false ; ezt . hallgatók [ e ]. adat = []; } ezt . hallgatók [ e ]. adatok . push ( visszahívás ); } // Iratkozz fel egyszer. onOnce ( e , visszahívás ) { this . on ( e , visszahívás ); ezt . hallgatók [ e ]. eventProperty . isOnOnce = igaz ; } // Leiratkozás. off ( e , visszahívás ) { this . hallgatók [ e ]. adat = ez . hallgatók [ e ]. adatok . filter ( function ( figyelő ) { return hallgató !== visszahívás ; }); } // Üzenet küldése az előfizetőknek. emit ( e , adat ) { if ( ez . hallgatók [ e ] == undefined || this . hallgatók [ e ]. adat == undefined ) { return ; } let itObj = ez ; ezt . hallgatók [ e ]. adatok . forEach ( hallgató => { if ( itObj . hallgatók [ e ]. eventProperty . isOnOnce ) { itObj . off ( e , itObj . hallgatók [ e ]. adatok [ 0 ]); } figyelő ( adat ); }); } }

További információk

A .NET Framework 4.0 -ban a megfigyelő tervezési mintája általános interfészek System.IObservable<T>és System.IObserver<T>[2] megvalósításával valósul meg .

Irodalom

  • Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides . Objektumorientált tervezés technikái. Tervezési minták = Design Patterns. Az újrafelhasználható objektum-orientált szoftver elemei. - Szentpétervár. : Péter, 2009. - 366 p. - ISBN 978-5-469-01136-1 .
  • Eric Freeman, Elizabeth Freeman. Tervezési minták = Head First Design Patterns. - Szentpétervár. : Péter, 2011. - 656 p. - ISBN 978-5-459-00435-9 .

Jegyzetek

  1. Megfigyelő minta . Letöltve: 2013. június 13. Az eredetiből archiválva : 2013. június 13..
  2. 1 2 Megfigyelő tervezési minta . Letöltve: 2013. június 13. Az eredetiből archiválva : 2013. június 13..
  3. Megfigyelő minta . Letöltve: 2019. november 4. Az eredetiből archiválva : 2019. november 4..