Die in Keep it DRY! vorgestellte INotification-Lösung ist zwar ganz ok, aber es geht noch besser: Anstelle einer typensicheren Benachrichtigung mit Hilfe überladener created-Methoden auf der ICreationListener-Schnittstelle können wir auch direkt einen visitor-basierten Ansatz wählen; der Double-Dispatch, mit dessen Hilfe wir uns den Typecast sparen, bleibt dabei selbstverständlich erhalten.
<RefactoringMode> Und so sieht das dann aus:
public interface ICreationListener {
public void created(Resource resource);
}
public interface IResourceVisitor {
public void visit(IntLiteral literal);
public void visit(StringLiteral literal);
...
}
public class StringLiteral extends Resource {
...
public void accept(IResourceVisitor visitor) {
visitor.visit(this);
}
}
public class IntLiteral extends Resource {
...
public void accept(IResourceVisitor visitor) {
visitor.visit(this);
}
}
Die Benachrichtigung der ICreationListener sieht dann so aus:
public void notifyListeners(Resource resource){
Iterator iter = fCreationListeners.iterator();
while (iter.hasNext()) {
ICreationListener element = (ICreationListener)
iter.next();
element.created(resource);
}
}
Und eine mögliche Umsetzung eines entsprechenden ICreationListeners:
class CreationListener
implements ICreationListener {
private IResourceVisitor
fImplementation = new IResourceVisitor()
{
public void visit(StringLiteral literal)
{
// Was auch immer getan werden muss
}
public void visit(IntLiteral literal)
{
// Was auch immer getan werden muss
}
};
public void created(Resource resource) {
resource.accept(fImplementation);
}
}