设计模式-访问者模式(visitor)以及JDK类库中的应用

访问者模式是一种设计模式,它定义了一个作用于对象结构的操作接口,允许在不修改元素类的情况下添加新的操作。模式包括抽象访问者、具体访问者、抽象元素和具体元素。这种模式的优点在于能解耦数据结构和操作,但可能违反迪米特法则和依赖倒转原则。常见应用场景是当对象结构稳定且需要添加多种操作时。在JDK中,`javax.lang.model.element.Element`和`ElementVisitor`等类体现了访问者模式的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

访问者模式

定义

表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变元素的类的前提下定义作用于这些元素的新操作。

结构

Visitor:抽象访问者类,为该对象结构中的每一个类声明visit操作。

ConcreteVisitor:具体抽象类,实现visit操作,将ConcreteElement作为方法参数。

Element:抽象元素类,定义一个accpet接口,将visior作为方法参数。

ConcreteElement:具体元素类,实现accept操作。

类图

抽象访问者:

abstract class Visitor {
	private String action;
	public abstract void visitConcreteElementA(ConcreteElementA concreteElementA);
	public abstract void visitConcreteElementB(ConcreteElementB concreteElementB);
	public String getAction() {
		return action;
	}
	public void setAction(String action) {
		this.action = action;
	}
	
}

具体访问者A:

public class ConcreteVisitorA extends Visitor{

	public ConcreteVisitorA(String action) {
		this.setAction(action);
	}
	
	@Override
	public void visitConcreteElementA(ConcreteElementA concreteElementA) {
		System.out.println(this.getAction()+"访问"+concreteElementA.getName());
	}

	@Override
	public void visitConcreteElementB(ConcreteElementB concreteElementB) {
		System.out.println(this.getAction()+"访问"+concreteElementB.getName());
	}

}

具体访问者B:

public class ConcreteVisitorB extends Visitor{

	public ConcreteVisitorB(String action) {
		this.setAction(action);
	}
	
	@Override
	public void visitConcreteElementA(ConcreteElementA concreteElementA) {
		System.out.println(this.getAction()+"访问"+concreteElementA.getName());
	}

	@Override
	public void visitConcreteElementB(ConcreteElementB concreteElementB) {
		System.out.println(this.getAction()+"访问"+concreteElementB.getName());
	}

}

抽象元素:

abstract class Element {
	private String name;
	public abstract void accept(Visitor visitor);
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
}

具体元素A:

public class ConcreteElementA extends Element{

	public ConcreteElementA(String name) {
		this.setName(name);
	}
	
	@Override
	public void accept(Visitor visitor) {
		visitor.visitConcreteElementA(this);
	}

}

具体元素B:

public class ConcreteElementB extends Element{

	public ConcreteElementB(String name) {
		this.setName(name);
	}
	
	@Override
	public void accept(Visitor visitor) {
		visitor.visitConcreteElementB(this);
	}

}

测试类:

	public static void main(String[] args) {
		ConcreteElementA a = new ConcreteElementA("具体元素A");
		a.accept(new ConcreteVisitorA("具体访问者A"));
		ConcreteElementB b = new ConcreteElementB("具体元素B");
		b.accept(new ConcreteVisitorA("具体访问者A"));
		ConcreteElementA c = new ConcreteElementA("具体元素A");
		c.accept(new ConcreteVisitorB("具体访问者B"));
		ConcreteElementB d = new ConcreteElementB("具体元素B");
		d.accept(new ConcreteVisitorB("具体访问者B"));
	}

测试结果:

优点

1.将数据结构和作用于数据结构上的操作解耦合,使得这些可以自由的演变。

2.符合开闭原则,增加一个新的操作将会很容易。

缺点

1.违反迪米特法则,具体元素对访问者公布细节。

2.违反了依赖倒转原则,接口依赖于细节。

使用场景

适用于对象数据结构不会发生变化,并且对该对象的操作欧不同的算法。

JDK类库中的访问者模式

javax.lang.model.element.Element and javax.lang.model.element.ElementVisitor 
javax.lang.model.type.TypeMirror and javax.lang.model.type.TypeVisitor 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值