- Spreadsheet Data
- Spreadsheet Formula
- Bar Graph
- Pie Char
- When the abstraction has two aspects with one dependent on the other. Encapsulating these aspects in separate objects will increase the chance to reuse them independently.
- When the subject object doesn't know exactly how many observer objects it has.
- When the subject object should be able to notify it's observer objects without knowing who these objects are.
- Abstract coupling between subject and observer, each can be extended and reused individually.
- Dynamic relationship between subject and observer, such relationship can be established at run time. This gives a lot more programming flexibility.
- Support for broadcast communication. The notification is broadcast automatically to all interested objects that subscribed to it.
- Unexpected updates. Observes have no knowledge of each other and blind to the cost of changing in subject. With the dynamic relationship between subject and observers, the update dependency can be hard to track down.
- Smalltalk Model/View/Controller (MVC). User interface framework while Model is subject and View is observer.
- Smalltalk ET++, and the THINK class library provide the general Observer pattern.
- Other user interface toolkits such as InterViews, the Andrew Toolkit, and Unidraw.
- Knows it observers
- Has any number of observer
- Provides an interface to attach and detaching observer object at run time
- Provides an update interface to receive signal from subject
- Store subject state interested by observer
- Send notification to it's observer
- Maintain reference to a ConcreteSubject object
- Maintain observer state
- Implement update operation
- ConcreteSubject notifies its observers whenever a change that could make it's state inconsistent with observers.
- After a ConcreteObserver be notified, it queries the subject state by using the GetState function. ConcreteObserver uses this information to change it's internal state.
- State setting operation in subject to trigger Notify.
- Observer to trigger Notify.
- Push model: subject sends details change information to observer.
- Poll model: subject sends minimum change information to observer and observer query for the rest of the information.
- The Observer pattern defines an one-to-many dependency between a subject object and any number of observer objects so that when the subject object changes state, all its observer objects are notified and updated automatically.
The Observer pattern is also known as Dependents and Publish-Subscribe.
- The Observer design pattern has two parts and they are subject and observer. The relationship between subject and observer is one-to-many. In order to reuse subject and observer independently, their relationship has to be decoupled.
An example of using the observer pattern is the graphical interface toolkit which separates the presentational aspect with application data. The presentation aspect is the observer part and the application data aspect is the subject part.
In a spreadsheet program, the Observer pattern can be applied as in the following diagram. Each rectangular box in the diagram in an object. SpreadSheetFormula, BarGraph, and PieChart are the observer objects. SpreadsheetData is the subject object. The SpreadsheetData object notifies its observers whenever a data changes that could make it's state inconsistent with the observers.
Subject |
|
Send notify signal to observer object whenever data changes |
Observer |
|
Request subject for change information in order to update itself accordingly |
The relationship between subject and observer can be establish at run time.
- Use the observer pattern in any of the following situations:
- Further benefit and drawback of Observe pattern include:
back to top
- Mediator: Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
Singleton: Ensure a class only has one instance, and provide a global point of access to it.
- The following is class diagram of an observer pattern (Kremer 1998):
Subject
Observer
ConcreteSubject
- Mapping subjects to their observers. A subject can keep track it's list of observers as observer reference or in a hash table.
Observing more than one subject. It might make sense to implement many-to-many relationship between subject and observer. The Update interface in observer has to know which subject is sending the notification. One of the implement is that subject can pass itself as a parameter in the Update operation.
Who triggers the update (Notify operation in Subject).
Making sure subject state is self-consistent before notification. Otherwise, an observer can query subject's intermediate state through GetState operation.
Avoiding observer-specific update protocols: push and pull models.
Encapsulating complex update semantics. For any complex set of subject and observer relationships, one can implement Change Manage to handle their Update operation. For example, if multiple subjects have to change state before any of their observers can update. Change Manager can handle change and update sequence for the operation.
The Observer pattern has four major classes. This section describes each class's member functions at the coding level.
Subject() is the constructor. It is not used in our implementation and this helps to keep the code generic. However, there are possibilities to use it for some applications.
~Subject() is the distructor. It is not used in our implementation and this helps to keep the code generic. However, there are possibilities to use it for some applications.
void Attach(Observer*) establishes the relationship between Subject and Observer by attaching the input Observer to the _observers list.
void Detach(Observer*) terminates the relationship between Subject and Observer by removing the specified Observer from the _observers list.
vector<Observer*> _observers declares an array of Observer type pointers.
Observer() is the constructor. It is not used in our implementation and this helps to keep the code generic. However, there are possibilities to use it for some applications.
~Observer() is the distructor. It is not used in our implementation and this helps to keep the code generic. However, there are possibilities to use it for some applications.
virtual void Update(Subject *theChangeSubject) = 0 defines the function Update() that interfaces with the Subject class. This function is called by object of the type Subject.
The ConcreteSubjectClass needs to implement functions for its observer objects to query subject state after sending the notify signal.
It needs function to maintain its internal state. Whenever it has a state change, it has to notify all of its observers.
ConcreteObserver(ConcreteSubject *) establishes the relationship with the input subject by using the Subject class function Attach()
~ConcreteObserver() terminates the relationship with the subject by using the Subject class function Detach()
void Update(Subject *) updates the object's internal state to synchronize with its subject. It uses member functions in the subject object to find out the subject's current state. This Update() function is called by the subject object.
ConcreteSubject *_subject maintains a reference to its subject.
- The following example based on the idea from Gamma, E., Helm, R., Johnson, R. & Vlissides, J., 1995. It is a clock program that presents time in both analog and digital format.
Observer Pattern Class name |
Clock Program Class Name |
C++ file |
Subject | Subject | observer.cpp observer.h |
ConcreteSubject | ClockTimer | ClockTimer.cpp ClockTimer.h |
Observer | Observer | observer.cpp observer.h |
ConcreteObserver | AnalogClock DigitalClock |
AnalogClock.cpp AnalogClock.h DigitalClock.cpp DigitalClock.h |
Both the Subject class and the Observer class are written in a very generic way and they can be reused in other application without modification.
The ConcreteSubject class and the ConcreteObserver class contain application specific code. However, their class structure can still be reused with modification.
The clock program is written in MS-Visual C++ 4.0. For demo. purpose, both the AnalogClock and the DigitalClock only prints out time in ASCII when they receives the notify signal from the ClockTimer. The following are the C++ sources filenames.
- AnalogClock.cpp
AnalogClock.h
ClockTimer.cpp
ClockTimer.h
DigitalClock.cpp
DigitalClock.h
main.cpp
observer.cpp
observer.h
- Gamma, E., Helm, R., Johnson, R. & Vlissides, J. (1995). Design Patterns: Elements of Reusable Object-Oriented Software. Reading Mass., Addison Wesley.
Buschmann, F., Meunier, R., Rohnert, H., Sommerlad, P. & Stal, M. (1996). A System of Patterns: Pattern-Oriented Software Architecture. West Sussex, England, John Wiley & Sons.
April 2, 98
Stephen Lam
lamsh@cpsc.ucalgary.ca
'Development > C/C++' 카테고리의 다른 글
[VC++]Win32에서의 유니코드 (0) | 2011.08.13 |
---|---|
[펌] ThreadWaitForMultipleObjects를 쓸 때는 _beginthread를 안쓰.. (0) | 2011.08.13 |
[펌] Effective C++ (0) | 2011.08.13 |
[펌] C++ 기초 강좌 (0) | 2011.08.13 |
[펌] 펌) C++ Programming HOW-TO (0) | 2011.08.13 |