defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically
Strive for loosely coupled designs between objects that interact.
We will also be utilizing the previous principles we learned:
Let’s think about how the strategy pattern works real quick, and see if we can derive the observer pattern from it.
Whenever some action happens (e.g., a method call), we delegate to a strategy which encapsulates the desired behavior.
Whenever some action happens (e.g., an update), we notify an observer which encapsulates the dependent behavior.
Sounds familiar…
As long as we only have one dependency, we can see that the observer pattern and strategy pattern are basically identical.
So, how do we incorporate multiple dependencies into our strategy pattern?
We just add the ability to provide multiple strategy patterns to a subject!
public class Duck{
private final long id;
private final Observer observer1;
private final Observer observer2;
public Duck(long id,Observer o1,Observer o2,Observer o3){
// ...
}
public void fly(){
observer1.notifyOfFlight(id);
observer2.notifyOfFlight(id);
}
}
We will also typically provide the ability to subscribe and unsubscribe observers at run times, though this is not particularly different from the strategy pattern (though we often make strategy patterns final).
public class Duck{
private final long id;
private final List<Observer> observers=new ArrayList<>();
public Duck(long id){
this.id = id;
}
//...
}
public class Duck{
//...
public void fly(){
for(final Observer o : observers){
o.notifyOfFlight(id);
}
}
}
No! While the essence of these two patterns are the same, the use cases for the observer pattern often have common requirements (like (un)subscribing) and specific semantics related to when notifications should occur, etc.
Observers…
I.e., a subject does not care what the dependency is doing!
You should consider using the observer pattern when:
One issue with the observer pattern is that we really have no idea what dependents are doing. If an observer performs a large amount of computation, or cascades updates to its own observers, you can cause a huge performance hit!
We also must decide whether we want to use a pull model or a push model for our updates.