Observer
m (Reverted edits by Ebybymic (Talk); changed back to last version by Mujtaba Alshakhouri) |
|||
(16 intermediate revisions by 10 users not shown) | |||
Line 1: | Line 1: | ||
[[Category:Design Patterns]] | [[Category:Design Patterns]] | ||
[[Category:Behavioural Patterns]] | [[Category:Behavioural Patterns]] | ||
− | The Observer design pattern is used to observe the state of | + | The Observer design pattern is used when one object needs to observe the state of another. Whenever the state of the observed object (subject) changes, all depending objects (observer) are notified and updated automatically. Therefore the subject should know about all its dependent observers and keep a list of them. The subject has a one-to-many dependency to all observers. Each observer must register with the subject in order to be notified when the subject's state changes. |
==Typical Usage== | ==Typical Usage== | ||
Line 45: | Line 45: | ||
'''Classes:''' ''Observer'', multiple ''ConcreteObservers'', ''Subject'', ''ConcreteSubject''. | '''Classes:''' ''Observer'', multiple ''ConcreteObservers'', ''Subject'', ''ConcreteSubject''. | ||
− | * Observer class that | + | * Observer class that implements java.util.Observer in Java. |
* Subject class that extends java.util.Observable in Java. | * Subject class that extends java.util.Observable in Java. | ||
OR | OR | ||
Line 51: | Line 51: | ||
* notifyAll() method in Subject. | * notifyAll() method in Subject. | ||
* abstract update() method in Observer. | * abstract update() method in Observer. | ||
+ | |||
+ | ==Consequences== | ||
+ | *Loose coupling between a subject and its observers because a subject doesn't know the concrete classes of its observers. | ||
+ | *One subject can be observed by any number of observers. | ||
+ | *Using the observer pattern can lead to unexpected updates since observers have no knowledge about what other objects are observing the subject so they have no way of knowing what updates will be triggered when the subject changes. | ||
+ | |||
+ | == Example == | ||
+ | |||
+ | You can find [http://java.dzone.com/articles/design-patterns-uncovered here] a nicely explained example of the Observer Pattern usage in the real world along with java code. | ||
+ | |||
+ | ==Observer and Java Generics== | ||
+ | In Java 1.5, generics were introduced. However, they decided not to apply them to the existing Observable/Observer library classes. | ||
+ | |||
+ | Here is a draft version of a generic version of this pairing implemented with generics, which should [[Avoid downcasting]], which was often necessary when using Java's version of the observer pattern. Get it [[Media:GenericObserver.zip|here]]. | ||
+ | |||
+ | ''Please note: These not yet fully documented and need further testing!!'' | ||
+ | |||
+ | ==Observer in C# and other .NET languages== | ||
+ | In C#, the Observer pattern can easily be implemented in the standard manner using generic classes. However, C# has ''delegates'' and ''events'', which essentially render that technique obsolete. To become the equivalent of a '''Subject''', a class simply has to have an ''event'' in its public interface. Other objects can become '''Observer'''s by subscribing to the event. Since this doesn't require inheritance, it is not necessary in C# to [[Don't burn your base class|burn your base class]] in order to use the Observer pattern, unlike in Java. | ||
+ | |||
+ | Objects can attach and detach methods to the event, and all of the subscribing methods get called when the event fires. This is slightly different to the standard pattern in that the "Observers" are methods, rather than entire classes. This means that a single class can subscribe multiple methods to the same event. | ||
+ | |||
+ | ==Implementation Issues== | ||
+ | In some cases, the languages built-in Observer pattern support can not be applied to a design. This can occur when a ConcreteSubject or ConcreteObserver already inherits from some other superclass. In languages that only allow inheritance from one superclass, the concrete classes cannot inherit the appropriate Observer classes. One solution to this is to implement your own Observer pattern by adding the appropriate methods (Attach, Dettach, Update etc..) to the relevant concrete sub-classes. The other option could be to make the superclass of the concrete subclasses inherit the Observer pattern, but this may violate a number of design maxims. | ||
+ | |||
+ | ==Related Patterns== | ||
+ | *[[Mediator]]: Observer can facilitate communication between mediator colleagues and the mediator object. | ||
+ | *[[Singleton]]: When a change manager is used to facilitate the communication between the subject and its observers, only one instance of the change manager is usually needed so it can be implemented using the [[Singleton]] pattern. | ||
+ | |||
+ | ==Conflicts== | ||
+ | *[[Don't burn your base class]]: In Java, which has only single inheritance, the Observer pattern can be implemented by having the subjects extend the Observable class and observers implement the Observer interface. The subject class has burned its chance to inherit from any other class since Java supports only single inheritance. | ||
+ | *[[Tell, don't ask]]: Requires getters to get information from the subject object. | ||
==See also== | ==See also== | ||
− | *[[Model | + | *[[Model View Controller]] |
+ | *[[Hierarchical Model View Controller]] | ||
*[http://en.wikipedia.org/wiki/Swing_(Java) Java Swing] | *[http://en.wikipedia.org/wiki/Swing_(Java) Java Swing] | ||
{{design patterns}} | {{design patterns}} |
Latest revision as of 03:22, 25 November 2010
The Observer design pattern is used when one object needs to observe the state of another. Whenever the state of the observed object (subject) changes, all depending objects (observer) are notified and updated automatically. Therefore the subject should know about all its dependent observers and keep a list of them. The subject has a one-to-many dependency to all observers. Each observer must register with the subject in order to be notified when the subject's state changes.
Contents |
Typical Usage
- When an abstraction has two aspects, one dependent on the other. Encapsulating these aspects in separate objects allows the programmer to vary and reuse them independently.
- When a change to one object requires changing others and it is not known in advance how many objects need to be changed.
- When an object should be able to notify others but shouldn't know anything about them
One or more than one component display in a graphical way the state of an object. Changes the state of the object, all components need to be informed. All components know about the object but the object should stay independent from the components. Therefore it should be a loose coupling. In this case you would use the observer pattern.
Example: Results of a measurement are illustrated in a bar chart, line chart and in a table. The measured values are permantly changing. The components should always display those changes but the measured object itself shouldn't need to know anything about the structure of those components.
Structure
From the Gang of Four Book:
Participant Classes
Subject
This abstract class provides an interface for attaching and detaching observer objects and notifying those.
- registerObserver(): adds new observer to the list of observers
- removeObserver(): removes a certain observer from the list of observers
- notifyObserver(): notifies each observer that the state of the subject changed by going through the list of observers
ConcreteSubject
This class returns its own state whenever asked by the observer objects. It also calls up its superclass' notifyObserver() function
- getState(): returns the state of the subject
Observer
This class defines an update interface for all observer objects.
- update(): abstract method.
ConcreteObserver
This class maintains a reference to the observing subject.
- update(): When this function is called by the subject, the observer calls the getState() function to update its information about the subject's state
Recognising the pattern
Classes: Observer, multiple ConcreteObservers, Subject, ConcreteSubject.
- Observer class that implements java.util.Observer in Java.
- Subject class that extends java.util.Observable in Java.
OR
- addObserver(Observer) and removeObserver(Observer) methods in Subject.
- notifyAll() method in Subject.
- abstract update() method in Observer.
Consequences
- Loose coupling between a subject and its observers because a subject doesn't know the concrete classes of its observers.
- One subject can be observed by any number of observers.
- Using the observer pattern can lead to unexpected updates since observers have no knowledge about what other objects are observing the subject so they have no way of knowing what updates will be triggered when the subject changes.
Example
You can find here a nicely explained example of the Observer Pattern usage in the real world along with java code.
Observer and Java Generics
In Java 1.5, generics were introduced. However, they decided not to apply them to the existing Observable/Observer library classes.
Here is a draft version of a generic version of this pairing implemented with generics, which should Avoid downcasting, which was often necessary when using Java's version of the observer pattern. Get it here.
Please note: These not yet fully documented and need further testing!!
Observer in C# and other .NET languages
In C#, the Observer pattern can easily be implemented in the standard manner using generic classes. However, C# has delegates and events, which essentially render that technique obsolete. To become the equivalent of a Subject, a class simply has to have an event in its public interface. Other objects can become Observers by subscribing to the event. Since this doesn't require inheritance, it is not necessary in C# to burn your base class in order to use the Observer pattern, unlike in Java.
Objects can attach and detach methods to the event, and all of the subscribing methods get called when the event fires. This is slightly different to the standard pattern in that the "Observers" are methods, rather than entire classes. This means that a single class can subscribe multiple methods to the same event.
Implementation Issues
In some cases, the languages built-in Observer pattern support can not be applied to a design. This can occur when a ConcreteSubject or ConcreteObserver already inherits from some other superclass. In languages that only allow inheritance from one superclass, the concrete classes cannot inherit the appropriate Observer classes. One solution to this is to implement your own Observer pattern by adding the appropriate methods (Attach, Dettach, Update etc..) to the relevant concrete sub-classes. The other option could be to make the superclass of the concrete subclasses inherit the Observer pattern, but this may violate a number of design maxims.
Related Patterns
- Mediator: Observer can facilitate communication between mediator colleagues and the mediator object.
- Singleton: When a change manager is used to facilitate the communication between the subject and its observers, only one instance of the change manager is usually needed so it can be implemented using the Singleton pattern.
Conflicts
- Don't burn your base class: In Java, which has only single inheritance, the Observer pattern can be implemented by having the subjects extend the Observable class and observers implement the Observer interface. The subject class has burned its chance to inherit from any other class since Java supports only single inheritance.
- Tell, don't ask: Requires getters to get information from the subject object.
See also
Design patterns | |
---|---|
Creational: Abstract Factory | Builder | Factory Method | Prototype | Singleton |