访问者模式的定义
访问者模式(Visitor Pattern)是一个相对简单的模式,其定义如下:Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates. 即:封装一些作用于某些数据结构的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。
访问者模式的通用类图如下:

接下来我们分析一下访问者模式中的角色:
- Visitor 抽象访问者。抽象类或者接口,声明访问者可以访问哪些元素,具体到程序中就是visit方法的参数定义哪些对象是可以访问的。
- ConcreteVisitor 具体访问者。实现访问者访问到一个元素后做什么事情。
- Element 抽象元素。抽象类或接口,声明接受哪一类访问者访问,程序中是通过accept方法中的参数来定义的。
- ConcreteElement 具体元素。实现accept方法。
- ObjectStructure 结构对象。
访问者模式的通用代码如下:
import java.util.Random;
//抽象访问者
public interface IVisitor{
//可以访问哪些对象
public void visit(ConcreteElement1 element);
public void visit(ConcreteElement2 element);
}
//具体访问者
public class Visitor implements IVisitor{
@Override
public void visit(ConcreteElement1 element) {
element.doSomething();
}
@Override
public void visit(ConcreteElement2 element) {
element.doSomething();
}
}
//抽象元素
public abstract class Element{
//定义业务逻辑
public abstract void doSomething();
//允许谁来访问
public abstract void accept(Visitor visitor);
}
//具体元素类1
public class ConcreteElement1 extends Element{
@Override
public void doSomething() {
System.out.println("Element 1 doSomething...");
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
//具体元素类2
public class ConcreteElement2 extends Element{
@Override
public void doSomething() {
System.out.println("Element 2 doSomething...");
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
//结构对象
public class ObjectStructure{
//对象生成器,这里通过一个工厂方法模式模拟
public static Element createElement(){
Random rand = new Random();
if(rand.nextInt(100) > 50){
return new ConcreteElement1();
}
return new ConcreteElement2();
}
}
//客户端
public class VisitorClient{
public static void main(String[] args) {
for(int i=0; i<5; i++){
Element el = ObjectStructure.createElement();
el.accept(new Visitor());
}
}
}
代码运行结果如下:
Element 1 doSomething...
Element 2 doSomething...
Element 2 doSomething...
Element 2 doSomething...
Element 1 doSomething...
访问者模式的应用
访问者模式的优点
- 符合单一职责原则。具体元素角色(Element)负责数据的加载,而Visitor则负责报表的展现,两个不同的职责明显的分离开,各自演绎变化。
- 优秀的扩展性。
- 灵活性非常高。
访问者模式的缺点
- 具体元素对访问者公布。访问者要访问一个类就必须要求这个类公布一些方法和数据。也就是访问者关注了元素的内部细节,不符合迪米特法则。
- 具体元素变更比较困难。具体元素角色的增加、删除、修改都比较困难。
- 违背了依赖倒置原则。访问者依赖具体元素,而不是抽象元素。
访问者模式的适用场景
- 一个对象结构包含很多类对象,他们有不同的接口,而客户端需要对这些对象试试一些依赖于具体类的操作。
- 需要对一个对象结构中的对象进行很多不同且不相关的操作,且需要避免让这些操作污染这些对象的类。
《注》以上内容总结自秦小波-《设计模式之禅》,仅为个人学习笔记
网友评论