Reputation: 5885
The book Head First Design Patterns presents the following UML as an example of the Observer pattern:
What strikes me in this diagram is the association relationship between the Subject
and Observer
interfaces. As far as I understand Java interfaces, they cannot implement a "Has-a" relationship in this way.
When I look at the implementation example provided a few pages later, I find that sure enough, the interfaces are plain old interfaces:
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers;
}
public interface Observer {
public void update(float temp, float humidity, float pressure);
}
Instead, the association relationship is implemented in the concrete WeatherData
and Display
classes:
public class WeatherData implements Subject {
private List<Observer> observers;
//more code
}
Which does not correspond to the UML and feels a bit wrong to me. Why not just implement Subject
as an abstract class instead? Does the UML spec formalize the idea of associating an interface with another interface?
Upvotes: 3
Views: 434
Reputation: 73456
You are right about your questioning. And let's see why the things are as they are:
Coming back to your observer:
Subject
has a navigable association to Observer
. In the code, you cannot implement nor even directly declare this kind of relationship in the interface. However, the fact that the Subject
interface shall allow to register and remove Observers
, implicitly suggest such an association.WheatherData
has a navigable association to CurrentConditionDisplay
. But in principle, they should, since these classes realize Subject
and Observer
respectively. This makes the diagram ambiguous. However, if we trust these classes to comply with the interface, we could live without showing the extra associations, just assuming that they have to be here. Moreover, strict UML compliance would require to add 3 such associations here, making the diagram more difficult to read.Now, as you rightly say, we could implement the design patterns using an abstract class instead of an interface. But since Java does not allow multiple inheritance, this approach would forbid subjects or observers to be in other class hierarchies.
First of all, the observer pattern -- as all patterns in Heads first Design Pattern -- originates from the GoF. Interestingly, GoF predates UML and Java; Its patterns only used class inheritance, if needed with multiple inheritance. When the book mentioned "interface", it was only about the implicit interface exposed by classes, very often abstract classes.
When Java came out, it was then a challenge to transpose all these design patterns, making explicit difference between interfaces (in the Java sense) and abstract classes. This is why you'll often find several variants among class diagrams of these patterns.
Heads first is no exception. The goal of that excellent book is to teach using patterns in coding. The main purpose of its diagrams is therefore to convey the design intent, and not to teach the rigorous use of advanced UML. So they used diagrams that might sometimes be formally ambiguous. Overall I think they made an excellent job.
Upvotes: 3