访问者模式js实现
访问者模式概述
访问者模式是一种行为设计模式,允许在不修改对象结构的情况下定义新操作。核心思想是将算法与对象结构分离,通过“访问者”对象集中处理不同对象的操作。
实现步骤
定义元素接口
元素接口声明一个accept方法,用于接受访问者对象:
class Element {
accept(visitor) {
throw new Error("Method 'accept()' must be implemented.");
}
}
实现具体元素类
每个具体元素类实现accept方法,调用访问者中对应自身类型的方法:
class ConcreteElementA extends Element {
accept(visitor) {
visitor.visitConcreteElementA(this);
}
operationA() {
return "Element A operation";
}
}
class ConcreteElementB extends Element {
accept(visitor) {
visitor.visitConcreteElementB(this);
}
operationB() {
return "Element B operation";
}
}
定义访问者接口
访问者接口声明一组visit方法,每个方法对应一种元素类型:
class Visitor {
visitConcreteElementA(element) {
throw new Error("Method 'visitConcreteElementA()' must be implemented.");
}
visitConcreteElementB(element) {
throw new Error("Method 'visitConcreteElementB()' must be implemented.");
}
}
实现具体访问者
具体访问者实现接口中定义的所有方法,定义对各类元素的操作逻辑:
class ConcreteVisitor1 extends Visitor {
visitConcreteElementA(element) {
console.log(`Visitor1: ${element.operationA()}`);
}
visitConcreteElementB(element) {
console.log(`Visitor1: ${element.operationB()}`);
}
}
class ConcreteVisitor2 extends Visitor {
visitConcreteElementA(element) {
console.log(`Visitor2: ${element.operationA()}`);
}
visitConcreteElementB(element) {
console.log(`Visitor2: ${element.operationB()}`);
}
}
客户端调用示例
客户端创建元素集合和访问者,通过accept方法触发访问逻辑:
const elements = [new ConcreteElementA(), new ConcreteElementB()];
const visitor1 = new ConcreteVisitor1();
const visitor2 = new ConcreteVisitor2();
elements.forEach(element => {
element.accept(visitor1);
element.accept(visitor2);
});
关键点
- 双分派机制:通过两次动态分配(元素调用
accept,访问者调用visit)实现多态行为。 - 扩展性:新增操作只需添加访问者类,无需修改元素类。
- 适用场景:对象结构稳定但需频繁新增操作的场景(如编译器语法树处理)。
输出示例
执行上述客户端代码后,控制台输出:
Visitor1: Element A operation
Visitor2: Element A operation
Visitor1: Element B operation
Visitor2: Element B operation 






