Friday, November 20, 2015

Observer Pattern

Observer Pattern

    Articolul reprezinta notitele mele cu privire la cursul "Design Patterns Library" din pluralsight, scris de catre by Steve Smith, David Starr, John Sonmez, John Brown, Brian Lagunas, Scott Allen, Robert Horvick, Keith Sparkjoy, Glenn Block, Niraj Bhatt, and Donald Belcham.



    Pattern-ul se recomanda a se aplica in urmatoarele situatii:

    1. Cand un obiect depinde de alt obiect
    2. Cand o schimbare intr-un (sau a unui) obiect necesita schimbarea unui alt obiect
    3. Cand o schimbare a unui obiect trebuie sa notifice alte obiecte fara a stii ca ele sunt acolo (alte clase si instante care monitorizeaza obiectul)

    Ca o prezentare generala a pattern-ului:
     Pe scurt, se foloseste o structura in care subiectul, cel care se schimba, il notifica pe cel care observa cu privire la modificarea facuta. Pentru a notifica, Observer-ul ar trebui sa poata sa se inregistreze si sa se de-inregistreze de la respectivul subiect.
     Deci, Subiectul notifica observer-ul. Acesta, la randul lui va trebui sa fie in stare sa poata sa modifice diverse valori prin subiect (status-uri, etc).
     Astfel daca observer-ul unu face o modificare, atunci observer-ul 2 va primi o notificare.


     Exista mai multe modalitati de implementare a acestui pattern:


     1. Traditional (conform cartii)

     In aceasta abordare:
     Este acela de a crea o clasa subject abstracta care furnizeze metodele necesare pentru inscrierea si de-inscrierea de la notificari, precum si o metoda de notificare. 
     Implementarea abstracta a clasei Observer furnizeaza implementarea goala a unui mecanism de actualizare (Update) si nu furnizeaza nici o implementare concreta a acestei metode (cod).
     De asemenea, GoogleObserver, in acest caz, reprezinta implementarea concreta si a clasei AbstractObserver. In aceasta clasa exista implementarea Update (concreta) precum si o refereinta la sursa de date concreta (la subject).
      Care sunt rezultatele acestei abordari:
      CONs:
        - Subiecti multipli pentru fiecare observator - este necesara pasarea subiectului to observer pentru a stii care din ele este cel care a facut update-ul.
        - Se declanseaza update-ul in mod automat cand diferite proprietati sunt implicate - trebuie putina atentie in momentul in care se efectueaza update-ul atunci cand mai multe proprietati sunt implicate in acelasi timp, avand grija sa nu declansezi update-uri duble cand de exemplu doua proprietati sunt modificate in acelasi timp.

        - Subiectii si observer-ii dispozati pot tine referinte unul la altul - in momentul in care se face dispose la un obiect, deoarece exista referinte de la observeri la subiecti si invers, atunci Garbage Collector-ul va fi impiedicat sa realizeze eliminarea acelor obiecte. Deci trebuie putina atentie aici.
        - Maparea subiectilor catre observer-ii lor - presupune un memory overhead.

        - Update-uri neasteptate - poate aparea cand exista mai multi observeri si o singura schimbare poate implica multiple schimbari peste tot. Mai ales cand sunt implicati foarte multi observeri, o singura schimbare din partea unui observer poate determina schimbari pentru restul observer-ilor ceea ce ar putea impacta negativ sistemul.

        - In cadrul acestei implementari, obiectul este privit in ansamblu.  Este dificil de urmarit schimbarea unei singure proprietati doar. Aceasta se rezolva in .net framework prin evenimente si delegati.


     

    2. Events and Delegates implementation

     In aceasta abordare:

     Aceasta metoda este implementata de .NET Framework prin niste facilitati de limbaj: events si delegates.
Acest pattern poate fi implementat fara abstract classes.
     In principiu evenimenul este creat de subiect si permite inregistrarea observer-ilor printr-un mecanism delegate callback. Observer-ii furnizeaza implementarea metodei delegate, care va fi chemata de subiect cand evenimentul este declansat.
     Imbunatatirea in aceasta abordare este faptul ca se pot avea si evenimente custom, in cazul de mai sus: StockChangeEventArgs (care ia un stock si niste alte date).

     

    3. IObserver <T>  - implementation

     A fost adaugata mai tarziu in .net si suporta cateva feature-uri precum Task Parallel Library. Implementarea arata astfel:

     Are o implementare similara cu varianta traditionala, dar in loc sa aiba o clasa abstracta, are un IObservable<T> si un IObserver<T>.
     In implementarea normala, a clasei concrete, avem o functie Subscribe (care adauga un observer la subject) si o metoda Notify care notifica observerii.
     Insa, la implementarea IObserver, exista trei metode in loc de una:
        - OnNext - ia urmatoarea valoare de la subiect
        - OnError - care este chemata cand este o eroare in procesare
        - OnCompleted - cand nu mai sunt alte schimbari pe subiect.

    IObservable pattern pare ar fi partea cealalta a lui IEnumerable.
    Cand se creeaza clasele de IObserver, nu mai este necesar sa trimiti in constructor subscriber-ul. Aceasta poti sa o faci mult mai tarziu, cand subscrii. Atunci este necesar sa trimiti, ca sa stii unde subscrii.
    

     Aceasta abordare poate sa intoarca si erori, nu numai date.







    






   
    












No comments:

Post a Comment