The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability%...

33
The Observer Pattern CSCI 3132 Summer 2011 1

Transcript of The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability%...

Page 1: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

The Observer Pattern

CSCI 3132 Summer 2011 1

Page 2: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

Seven  Sins  of  Design  

•  Rigidity  –  make  it  hard  to  change    •  Fragility  –  make  it  easy  to  break  

•  Immobility  –  make  it  hard  to  reuse  

•  Viscosity  –  make  it  hard  to  do  the  right  thing  

•  Needless  Complexity  –  over  design  

•  Needless  RepeAAon  –  error  prone  

•  Not  doing  any  2

Page 3: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

The  Rules  •  Apply  Common  Sense  •  Don’t  get  too  dogmaAc  /  religious  

•  Every  decision  is  a  tradeoff    

•  All  other  principles  are  just  that    – Guidelines  – “best  pracAces”  – Consider  carefully  if  you  should  violate  them    -­‐  but,  know  you  can.  

3

Page 4: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

Open  Closed  Principle  

•  SoRware  enAAes  (  Classes,  Modules,  Methods,  etc.  )  should  be  open  for  extension,  but  closed  for  modificaAon.  

•  Also  Known  As  Protected  VariaAon  •  QuesAon:  This  principle  is  applied  to  which  of  the  design  paZerns  we  have  learned  so  far?    

4

Page 5: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

Single  Responsibility  Principle  

•  A  Class  should  have  one  reason  to  change  – A  Responsibility  is  a  reasons  to  change  

•  Can  be  tricky    to  get  granularity  right  •  Single  Responsibility  =  increased  cohesion    •  Not  following  results  in  needless  dependencies  

– More  reasons  to  change.  – Rigidity,  Immobility  

•  QuesAon:  This  principle  is  applied  to  which  of  the  design  paZerns  we  have  learned  so  far?      

5

Page 6: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

Consider  the  Following  ApplicaAon  

Humidity  

Temperature  

Pressure  

Weather    StaAon  

Weather  Data    Object  

Three  Displays  

6

Page 7: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

What’s  Given  

•  The  WeatherData  class  has  geZer  methods  that  obtain  measurement  values  from  temperature,  humidity  and  pressure.  

•  The  class  has  a  measurementsChanged()  method  that  updates  the  three  values.  

•  Three  displays  must  be  implemented:  current  condiAons,  staAsAcs  and  forecast  display.  

•  System  must  be  expandable  –  other  display  elements  maybe  added  or  removed.  

7

Page 8: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

A  First  AZempt  class WeatherData{!public: ! ! void measurementChanged(){!! ! float temp = getTemperature();!! ! float humidity = getHumidity();!! ! float pressure = getPressure();!! ! currentConditionsDisplay.update(temp,humidity,

!! ! ! ! ! pressure)!! ! ! statisticsDisplay.update(temp,humidity,pressure)!! !! forecastDisplay.update(temp,humidity,pressure)! }!! //other WeatherData methods here!}; !

8

Page 9: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

The  Observer  PaZern  “Observed”  

Subject  Object  

int  2  

Dog Object Registers Observers  

Dog  Object  

Cat  Object  

Duck  Object  

Subject  Broadcasts  

2  

Cat  Object  Registers    Duck  Object  Registers  Subject  is  updated  

int    8  

Cat  object  de-­‐registers  

Cat  Object  

Subject  Broadcasts  

8  

8  

Other examples: “publish and subscription” services; eBay

9

Page 10: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

Handling  the  addiAon  of  new  customers:  

•  Sending  a  welcome  leZer  •  Verify  the  customer’s  address  with  the  post  office  

Another  Example  

10

Page 11: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

Customer:      When  a  customer  is  added,  this  object  will  make  the          calls  to  the  other  objects  to  have  the  corresponding          acAons  take  place  

WelcomeLeZer:     Creates  welcome  leZers  for  customers  that  let           them  know  they  were    added  to  the  system.  

AddrVerificaAon:     This  object  will  verify  the  address  of  any           customer  that  asks  it  to  

A  First  Try  

11

Page 12: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

               We  do  not  want  to  change  the  broadcasAng  object  every  Ame  there  is  a  change  to  the  set  of  objects  listening  to  the  broadcast.  

We  want  to  decouple  the  noAfy-­‐ers  (subject)  and  the  noAfy-­‐ees(observer).  

Two  things  vary  •  Different  kinds  of  objects  –  ones  that  need  to  be  noAfied  

of  a  change  in  state.  

•  Different  interfaces  –  Each  object  that  requires  noAficaAon  may  have  a  different  interface.  

Decoupling  

12

Page 13: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

All  observers  must  have  the  same  interface.  All  observers  must  register  themselves.  This  makes  them  

responsible  for  knowing  what  they  are  watching  for.    We  must  add  two  methods  to  the  subject.  •  attach(Observer) adds  the  given  observer  to  its  

list  of  observers.  •  detatch(Observer) removes  the  given  observer  

from  its  list  of  observers.  

The  observer  must  implement  a  method  called  update.    The  subject  implements  the  notify  method  that  goes  

through  its  list  of  Observers  and  calls  this  update  method  for  each  of  them.  

A  BeZer  SoluAon  

13

Page 14: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

The  Class  Diagram  

14

Page 15: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

class Customer{!public:! void attach( Observer *myObserver);! void detach( Observer *myObserver);! void notify();!private:! vector<Observer*> myObs;!};!void Customer::attach( Observer *myObserver)!{! myObs.push_back( myObserver);!}!

Example  (Cont’d)  

15

Page 16: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

void Customer::detach( Observer *myObserver){! for (int i= 0; i< myObs.size(); i++){! if (myObs[i]== myObserver){! myObs.erase(myObs.begin()+i);! return;! }! }!}!void Customer::notify(){! for (int i= 0; i< myObs.size(); i++){! myObs[i]->update(this);! }!}!

Example  (Cont’d)  

16

Page 17: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

DefiniAon  

•  The  observer  paZern  implements  a  one-­‐to-­‐many  relaAonship  between  a  set  of  objects.  

•  A  single  object  changes  state  and  updates  the  objects  (dependants)  that  are  affected  by  the  change.      

•  The  object  that  changes  state  is  called  the  subject  and  the  other  objects  are  the  observers.  

17

Page 18: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

Loose  Coupling  

•  Subjects  and  observers  are  loosely  coupled.  •  The  subject  only  knows  the  observer  interface  and  not  its  implementaAon.  

•  Observers  can  be  added  and  removed  at  any  Ame.  •  In  adding  new  observers  the  subject  does  not  need  to  be  modified.    

•  Subjects  and  observers  can  be  reused  independently.  

•  Changes  to  the  subject  or  observer  will  not  affect  the  other.  

18

Page 19: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

Design  Principle  

•  Strive  for  loosely  coupled  designs  between  objects  that  interact.  

•  Loosely  coupled  designs  allow  us  to  build  flexible  object-­‐oriented  systems.  

•  These  systems  can  handle  change  because  they  minimize  the  interdependency  between  objects.  

19

Page 20: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

Observer  Applicability  

•  Use  the  Observer  paZern  in  any  of  the  following  situaAons  – When  an  abstracAon  has  two  aspects,  one  dependent  on  the  other.  EncapsulaAng  these  aspects  in  separate  objects  lets  you  vary  and  reuse  them  independtly.  

– When  a  change  to  one  object  requires  changing  others,  and  you  do  not  know  how  many  objects  need  to  be  changed.  

– When  an  object  should  be  able  to  noAfy  other  objects  without  making  assumpAons  about  who  these  objects  are.   20

Page 21: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

Observer  ParAcipants  

•  Subject  – Knows  its  observers.  Any  numberof  Observer  objects  may  observe  a  subject.  

– Provides  an  interface  for  aZaching  and  detaching  Observer  Objects.  

•  Observer  – Defines  an  updaAng  interface  for  objects  that  should  be  noAfied  of  changes  in  a  subject    

21

Page 22: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

Observer  ParAcipants  •  ConcreteSubject  

– Stores  a  state  of  interest  to  ConcreteObserver  objects.  

– Sends  a  noAficaAon  to  its  observers  when  its  state  changes.  

•  ConcreteObserver  – Maintains  a  reference  to  a  ConcreteSubject  object  

– Stores  state  that  should  stay  consistent  with  the  subject  state.  

– Implements  the  Observer  updaAng  interface  to  keep  its  state  consistent  with  the  subject  state.   22

Page 23: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

 Weather  StaAon  Class  Diagram  

23

Page 24: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

The  Observer  PaZern:  Key  Features  

Intent:  Define  a  one-­‐to-­‐many  dependency  between  objects  so  that  when  one  object  changes  state,  all  its  dependents  are  noAfied  and  updated  automaAcally.  

Problem:  You  need  to  noAfy  a  varying  list  of  objects  that  an  event  has  occurred.  

Solu.on:  Observers  delegate  the  responsibility  for  monitoring  for  an  event  to  a  central  object:  The  subject.  

24

Page 25: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

The  Observer  PaZern:  Key  Features  

Implementa.on:  Have  objects  (Observers)  that  want  to  know  when  an  event  happen  aZach  themselves  to  another  object  (Subject)  that  is  watching  for  the  event  to  occur  or  that  triggers  the  event  itself.      

                 When  the  event  occurs,  the  Subject  tells  the  Observers  that  it  has  occurred.  

  The  Adapter  paZern  is  someAmes  needed    to  be  able  to  implement  the  Observer  interface  for  all  the  Observer-­‐type  objects.  

25

Page 26: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

Observer  PaZern:  Class  Diagram  

26

Page 27: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

Observer  Sequence  Diagram  

ConcreteSubject Object

ConcreteObserver ObjectA

ConcreteObserver ObjectB

Notify()

SetState()

Update()

GetState()

Update() GetState()

27

Page 28: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

Observer  Consequences  

•  Abstract  coupling  between  Subject  and  Object  – All  a  subject  knows  is  that  it  has  a  list  of  observers,  each  conforming  to  the  simple  interface  of  the  abstract  Observer  class.  The  subject  does  not  know  the  concrete  class  of  any  observer.  

•  Support  for  broadcast  communicaAon  – Unlike  and  ordinary  request,  the  noAficaAon  that  a  subject  sends  need  not  specify  its  receiver.  The  noAficaAon  is  broadcast  automaAcally  to  all  interested  objects  that  subscribed  to  it.  

28

Page 29: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

Observer  ImplementaAon  •   How  to  noAfy  -­‐  Approach  1    void ConcreteSubject::setstate(int newstate) { state_=newstate; notify(); // notify all observers that // state

has changed }

Subject s1; subject.setstate(6); // automatic call to notify Subject.setstate(5);

29

Page 30: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

Observer  ImplementaAon  

•   How  to  noAfy  -­‐  Approach  2    void ConcreteSubject::setstate(int newstate) { state_=newstate; }

Subject s1; subject.setstate(6); subject.setstate(5); Subject.notify(); // explicit call to notify

30

Page 31: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

Observer  ImplementaAon  

•  the  Push  model  and  the  Pull  model  – ImplementaAons  of  the  Observer  paZern  oRen  have  the  subject  broadcast  addiAonal  informaAon  about  the  change.  The  subject  passes  this  informaAon  as  an  argument  to  Update.    

– Push  model:  the  subject  sends  obervers  detailed  informaAon  about  the  change  

– Pull  model:  the  subject  sends  only  a  minimal  noAficaAon  and  observers  ask  for  details  explicitly    

31

Page 32: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

Observer  ImplementaAon  

What  happens  when  we  add  new  observers?  

Imagine  adding  the  ability  to  send  a  leZer  with  coupons  to  customers  located  within  20  miles  of  one  of  the  company’s  “Brick  and  Mortar”  stores.  

32

Page 33: The Observer Pattern - Dalhousie Universityjin/3132/lectures/dp-05.pdf · Observer%Applicability% • Use%the%Observer%paern in any%of%the%following% situaons% – When%an%abstracAon%has%two%aspects,one%

Observer  ImplementaAon  If  the  class  we  want  to  add  already  exists  and  we  can  not  modify  it,  

then  we  can  adapt  it  as  shown  below:  

33