访问者是一种行为设计模式,可让您将算法与它们操作的对象分开。
假设您有一个由各种几何形状组成的画布。您现在需要将画布导出为 XML 格式。您的计划是为每个几何形状类添加一个导出方法,然后遍历画布上的每个形状,执行导出方法。
在形状类中包含 XML 导出代码是否有意义?这些类主要负责在画布上显示坐标和使用坐标。
此外,很有可能有人会在该功能实施后要求能够以另一种格式导出。
访客设计模式
访问者模式建议您将新行为放入一个名为访问者的单独类中,而不是尝试将其集成到现有类中。现在,必须执行此行为的原始对象作为参数传递给访问者的方法,使该方法可以访问对象中包含的所有数据。
UML 类图
实施步骤
源代码实现
访问者接口定义了可以将对象结构的具体元素作为参数的访问方法。
package com.learncsdesign;
public interface Visitor {
public void visit(Dot dot);
public void visit(Rectangle rect);
public void visit(Circle circle);
}具体访问者 XMLExportVisitor 实现了相同行为的多个版本,为不同的具体元素类量身定制。
package com.learncsdesign;
public class XMLExportVisitor implements Visitor {
@Override
public void visit(Dot dot) {
System.out.println(
"Exporting Dot ID and coordinates: ID: " + dot.getId() + ", x:" + dot.getX() + ", y:" + dot.getY());
}
@Override
public void visit(Rectangle rect) {
System.out.println("Exporting Dot ID and coordinates: ID: " + rect.getId() + ", x:" + rect.getX() + ", y:" + rect.getY());
}
@Override
public void visit(Circle circle) {
System.out.println("Exporting Dot ID and coordinates: ID: " + circle.getId() + ", x:" + circle.getX() + ", y:" + circle.getY());
}
}Shape (Element) 接口声明了一个接受访问者的方法。 它应该有一个参数来声明访问者界面的类型。
package com.learncsdesign;
public interface Shape {
public void move(int x, int y);
public void draw();
public void accept(Visitor visitor);
}Concrete Shapes Dot, Rectangle & Circle 必须各自实现验收方法。 此方法将调用重定向到与当前元素类对应的正确访问者方法。
package com.learncsdesign;
import java.util.Random;
public class Dot implements Shape {
private int id;
private int x;
private int y;
public Dot() {
this.id = new Random().nextInt(100000);
}
public int getId() {
return id;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override
public void move(int x, int y) {
this.x += x;
this.y += y;
draw();
}
@Override
public void draw() {
System.out.println("Drawing Dot at (" + x + "," + y + ")");
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}package com.learncsdesign;
import java.util.Random;
public class Rectangle implements Shape {
private int id;
private int x;
private int y;
public Rectangle() {
this.id = new Random().nextInt(100000);
}
public int getId() {
return id;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override
public void move(int x, int y) {
this.x += x;
this.y += y;
draw();
}
@Override
public void draw() {
System.out.println("Drawing Rectangle at (" + x + "," + y + ")");
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}package com.learncsdesign;
import java.util.Random;
public class Circle implements Shape {
private int id;
private int x;
private int y;
public Circle() {
this.id = new Random().nextInt(100000);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override
public void move(int x, int y) {
this.x += x;
this.y += y;
draw();
}
@Override
public void draw() {
System.out.println("Drawing Circle at (" + x + "," + y + ")");
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}通常,客户端代表一个集合或一些其他复杂的对象。 在大多数情况下,客户端不知道所有具体的元素类,因为它们通过一些抽象接口处理来自该集合的对象。
package com.learncsdesign;
import java.util.LinkedList;
import java.util.List;
public class VisitorClient {
List shapes;
public VisitorClient() {
shapes = new LinkedList();
Dot dot = new Dot();
dot.move(10, 20);
shapes.add(dot);
Rectangle rect = new Rectangle();
rect.move(100, 0);
shapes.add(rect);
Circle circle = new Circle();
circle.move(234, 20);
shapes.add(circle);
}
public static void main(String[] args) {
VisitorClient client = new VisitorClient();
XMLExportVisitor exportVisitor = new XMLExportVisitor();
for (Shape shape : client.shapes) {
shape.accept(exportVisitor);
}
}
} // Output
Drawing Dot at (10,20)
Drawing Rectangle at (100,0)
Drawing Circle at (234,20)
Exporting Dot ID and coordinates: ID: 63741, x:10, y:20
Exporting Dot ID and coordinates: ID: 29577, x:100, y:0
Exporting Dot ID and coordinates: ID: 2254, x:234, y:20
何时应用访客设计模式
访客设计模式的优点
更多APP/小程序/网站源码资源,请搜索"七爪网源码交易平台"!
| 留言与评论(共有 0 条评论) “” |