VisitorPattern cannot be used here as I would have the Shapes implement some kind of interface Visitable which would force them to implement a edit(IEditorVisitor) method, and by this pollute the domain model with information about how it will be displayed in UI.
Well, no it doesn't have to give the domain model information about how it is displayed or edited. It need only give the domain model knowledge that it is visited.
Just don't name your visitor interface IEditorVisitor
and don't name the IVisitable
method edit
.
Visitor is very much suited to this sort of problem.
I would do it more like:
public interface IVisitableShape {
void accept(IShapeVisitor v);
}
public interface IShapeVisitor {
void visit(Line line);
void visit(Rectangle rectangle);
}
public class Line extends Shape implements IVisitableShape {
@Override
public void accept(IShapeVisitor v) {
v.visit(this);
}
}
public class EditorImpl implements IShapeVisitor {
public void visit(Line line) {
//show the line editor
}
public void visit(Rectangle rect) {
//show the rectangle editor
}
}
Note that this is essentially equivalent to your implementation sketch, only changing names, so that the function of editing is only in the editor.
The function names accept
and visit
are commonly used in descriptions of this pattern, and reflect the pattern. They can of course be changed, but I don't see the need, and it's certainly better to keep them from being explicitly tied to the editing function.