1 Intentions
Defines a one-to-many dependency between objects, and when an object's state changes, all objects that depend on it are notified and automatically updated.
2 aliases
Dependency (dependents), publish-subscribe (publish-subscribe)
3 Motive
Splitting a system into a series of mutually collaborative classes has a common side effect: the need to maintain consistency between related objects. We don't want to be tightly coupled in order to maintain consistency, because it reduces their reusability.
4 practicality
1, when an abstract model has two aspects, one aspect depends on another aspect. The two are encapsulated in separate objects so that they can be independently changed and reused.
2, when the change of an object need to change other objects at the same time, and do not know how many objects to be changed.
3, when an object must notify other objects, and it can not assume that other objects are who. In other words, you don't want these objects to be tightly coupled.
5 structure
7 Advantages and Disadvantages
1, the coupling between the target and the observer is the least abstract.
2. Support Broadcast Communication
3. unexpected updates because an observer does not know the existence of other observers, it may be ignorant of the ultimate cost of changing the target. An operation that looks harmless on the target may cause a series of updates to the observer and those objects that depend on those observers. In addition, if the dependency criteria are defined or poorly maintained, they often cause erroneous updates, which are often difficult to catch.
--The above is from the basis of reusable orientation software
code example:
This example simply simulates the relationship between a vehicle's operation and a traffic light. The example implements a Signallamp base class (Observer), and any class that inherits the base class can observe the traffic light information and let the (Concreteobserver) class vehicle, inherit Signallamp. A subject base class is implemented, and any concretesubject inheriting subject can be observed by the specific observer who inherits the Signallamp and implements the subclass Trafficsignal.
At the client we achieved a few cars in operation, when the traffic lights change, there is a car that observes traffic lights will be affected. So:
The picture here does not explain anything, but it is convenient for us to visualize the client scenario. Many cars are constantly moving, and when they turn red, the vehicles that watch the Trafficsignal event will stop moving, and the car without observing the event will not be affected.
1. The code in Observer.h is as follows:
#ifndef _observer_#define_observer_#include<iostream>using namespacestd;voidGotoxy (intXinty);enumsignallamp{redsignal, greensignal};classobservertrafficsignal{ Public: Observertrafficsignal () {}Virtual voidUpdatasignal (signallamp signal) =0;};classVehicle: Publicobservertrafficsignal{ Public: Vehicle (intPxintPY): _pointx (px), _pointy (py) {isred =false;} voiddrawvehicle (); voidclearvehicle (); voidupdataposition (); voidSetmovestep (intSTEPX,intstepy); Virtual voidupdatasignal (Signallamp signal);Private: int_pointx; int_pointy; int_move_x; int_move_y; int_save_movex; int_save_movey; BOOLisred;};#endif
Observer.h
2, the code in Observer.cpp is as follows:
#include"Observer.h"#include<iostream>using namespacestd; #include<windows.h>voidGotoxy (intXinty) {COORD COORD={x, y}; SetConsoleCursorPosition (GetStdHandle (std_output_handle), coord);}voidconceal_cursor () {Console_cursor_info CCI; Cci.bvisible=false; Cci.dwsize=sizeof(CCI); HANDLE HANDLE=GetStdHandle (Std_output_handle); Setconsolecursorinfo (Handle,&CCI);}voidVehicle::d rawvehicle () {//conceal_cursor (); intI=0; Gotoxy (_pointx, _pointy+ (i++)); cout<<" __________________"; Gotoxy (_pointx, _pointy+ (i++)); cout<<"| |"; Gotoxy (_pointx, _pointy+ (i++)); cout<<"| [_] [_] [_] [_] [_] [_]|"; Gotoxy (_pointx, _pointy+ (i++)); cout<<"|o _ _ |"; Gotoxy (_pointx, _pointy+ (i++)); cout<<" `(_)-------(_)(_)-\"";}voidvehicle::clearvehicle () {intI=0; Gotoxy (_pointx, _pointy+ (i++)); cout<<" "; Gotoxy (_pointx, _pointy+ (i++)); cout<<" "; Gotoxy (_pointx, _pointy+ (i++)); cout<<" "; Gotoxy (_pointx, _pointy+ (i++)); cout<<" "; Gotoxy (_pointx, _pointy+ (i++)); cout<<" ";}voidvehicle::updataposition () {_pointx+=_move_x; _pointy+=_move_y; if(_pointx > the) _pointx=1; if(_pointy> -) _pointy=1; if(_pointy<1) _pointy= -; if(_pointx<1) _pointx= the;}voidVehicle::setmovestep (intSTEPX,intstepy) {_move_x=stepx; _move_y=stepy; }voidvehicle::updatasignal (Signallamp signal) {Switch(signal) { Caseredsignal:if(!isred) {isred=true; _save_movex=_move_x; _save_movey=_move_y; Setmovestep (0,0); } Break; Casegreensignal:if(isred) {setmovestep (_save_movex, _save_movey); Isred=false; } Break; }}
Observer.cpp
The Updatasignal function in the code uses _save_movex and _save_movey to save the car's original movement speed when it encounters a red light, so that it recovers when it turns green.
3, the code in Subject.h is as follows:
#ifndef _subject_#define_subject_#include<list>usingstd::list; #include"Observer.h"classsubject{ Public: Subject () {}Virtual voidAttach (observertrafficsignal*ob); Virtual voidDetach (observertrafficsignal*ob); Virtual voidNotify () =0; List<observertrafficsignal* >_observers;};classTrafficsignal: Publicsubject{ Public: Trafficsignal (): _counttime (8), _signal (greensignal) {}Virtual voidnotify ();Private: int_counttime; Signallamp _signal;};#endif
subject.h
4, the code in Subject.cpp is as follows:
#include"subject.h"#include<iostream>#include<iterator>usingStd::iterator;voidSubject::attach (observertrafficsignal*ob) { if(NULL! =ob) _observers.push_back (OB);}voidSubject::d Etach (observertrafficsignal*ob) { if(NULL! =ob) _observers.remove (OB);}voidtrafficsignal::notify () {if(!_counttime) {_counttime= rand ()%5+4; ; if(_signal = =redsignal) _signal=greensignal; Else_signal=redsignal; } _counttime--; Gotoxy ( -,4); if(_signal = =redsignal) Std::cout<<"-- red light --"; ElseStd::cout<<"--Green--"; List<observertrafficsignal* >::iterator iter =_observers.begin (); for(ITER; ITER! = _observers.end (); iter++) { (*iter)updatasignal (_signal); }}
Subject.cpp
The Notify function in the code simulates a traffic light (only red and green) by a number of _counttime, and each run will _counttime minus one, and when _counttime equals zero, a number again, and a better traffic lights.
5, the code in Main.cpp is as follows:
#include <iostream>using namespacestd; #include<time.h>#include"subject.h"intMain () {Srand (0)); Vehicle ve1 ( the,5); Ve1.setmovestep (-3,0); Vehicle Ve2 ( the, A); Ve2.setmovestep (-4,0); Vehicle Ve3 ( the, -); Ve3.setmovestep (-2,0); Trafficsignal tra; Tra.attach (&ve1); //Tra.attach (&ve2);Tra.attach (&ve3); while(1) {ve1.drawvehicle (); Ve2.drawvehicle (); Ve3.drawvehicle (); _sleep ( $); Ve1.clearvehicle (); Ve2.clearvehicle (); Ve3.clearvehicle (); Ve1.updataposition (); Ve2.updataposition (); Ve3.updataposition (); Tra.notify (); } return 0;}
Observer Mode (Observer) C + + implementation