Java 根据对象实例显示自定义编辑器的设计模式是什么?
我有几个对象都扩展了Java 根据对象实例显示自定义编辑器的设计模式是什么?,java,design-patterns,strategy-pattern,visitor-pattern,Java,Design Patterns,Strategy Pattern,Visitor Pattern,我有几个对象都扩展了形状基本类。对于每个对象,我想显示不同的对象编辑器,例如行与矩形有不同的属性可编辑 class Shape; class Line extends Shape; class Rectangle extends Shape; List<Shape> shapes; void onEditEvent(Shape shape) { new ShapeEditorPopup(shape); //how to avoid instanceof check
形状
基本类。对于每个对象,我想显示不同的对象编辑器
,例如行
与矩形
有不同的属性可编辑
class Shape;
class Line extends Shape;
class Rectangle extends Shape;
List<Shape> shapes;
void onEditEvent(Shape shape) {
new ShapeEditorPopup(shape);
//how to avoid instanceof checks here
}
VisitorPattern不能在这里使用,因为我会让这些形状实现某种类型的界面可访问性,这将迫使它们实现编辑(IEditorVisitor)方法,从而污染域模型,使其包含有关如何在UI中显示的信息
不,它不必给出域模型关于如何显示或编辑的信息。它只需要给出被访问的领域模型知识
只是不要命名访问者界面IEditorVisitor
,也不要命名IVisitable
方法edit
访客非常适合处理这类问题
我更愿意这样做:
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
}
}
请注意,这本质上等同于您的实现草图,仅更改名称,因此编辑功能仅在编辑器中
函数名
accept
和visit
通常用于此模式的描述中,并反映该模式。它们当然可以更改,但我不认为有必要,而且最好不要将它们显式地绑定到编辑功能。好吧,如果它们实际上用于编辑对象,那么将方法命名为“编辑”以外的方法就没有意义了。无论如何,我更新了我的答案。这就是你的建议吗?但我还是不太满意,因为我必须在我所有的域对象中提供一个编辑委托……你给访问者的具体实现一个特定于函数的名称。您还可以创建其他访问者,用于除编辑对象之外的其他功能。感谢完整的示例@Don。我承认,到目前为止,我还没有完全理解访问者模式,因为我不知道只有VisitorImpl起作用,其余的是一种每次都要应用的固定模式。
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
}
}