Bootstrap

java设计模式(二一)访问者模式(Visitor Pattern)

1、模式介绍:

访问者模式是一种行为设计模式,其主要目的是在不改变已有类的前提下,定义作用于这些类对象结构中的新功能。它将数据结构与数据操作分离,使得操作集合可以独立变化。

2、应用场景:

当一个数据结构包含许多不同类型的对象,而你希望对这些对象实施一些依赖其具体类型的操作时,可以使用访问者模式。例如,编译器中对抽象语法树(AST)的不同节点进行不同的操作。
当需要在不改变类的前提下,添加新的操作时,访问者模式可以帮助避免修改现有代码,而只需新增访问者类即可。
当对象结构中的元素类很少改变,但经常需要在此结构上定义新的操作时,访问者模式提供了一种灵活的方式。

3、优点:

符合单一职责原则:将相关行为封装在一起,使得代码易于理解和维护。
扩展性良好:可以通过增加新的访问者类,实现对已有代码的功能扩展,而无需修改现有代码。
分离数据结构和算法:可以在不修改原有数据结构的情况下,增加新的操作。

4、缺点:

增加新的元素类比较困难,需要修改所有的访问者类。
具体元素暴露,增加了对象结构的复杂度。

5、代码示例:

/**
 * 元素接口
 */
public interface Element {
 	void accept(Visitor visitor);
}

/**
 * 具体元素实现类A
 */
public class ConcreteElementA implements Element {
 	@Override
 	public void accept(Visitor visitor) {
  		visitor.visit(this);
 	}
}

/**
 * 具体元素实现类B
 */
public class ConcreteElementB implements Element {
 	@Override
 	public void accept(Visitor visitor) {
 		 visitor.visit(this);
 	}
}

/**
 * 访问者接口
 */
public interface Visitor {
 	void visit(ConcreteElementA element);
 	void visit(ConcreteElementB element);
}

/**
 * 具体的访问者实现
 */
public class ConcreteVisitor implements Visitor {
	@Override
	public void visit(ConcreteElementA element) {
		 System.out.println("Visitor is visiting ConcreteElementA");
	 	// 对ConcreteElementA的具体操作
	}

	@Override
	public void visit(ConcreteElementB element) {
	 	System.out.println("Visitor is visiting ConcreteElementB");
		 // 对ConcreteElementB的具体操作
	}
}

/**
 * 对象结构类,可以包含多种不同的元素对象
 */
public class ObjectStructure {
	private List<Element> elements = new ArrayList<>();

	public void attach(Element element) {
	 	elements.add(element);
	}

	public void detach(Element element) {
	 	elements.remove(element);
	}

	public void accept(Visitor visitor) {
	 	for (Element element : elements) {
	  		element.accept(visitor);
	 	}
	}
}

/**
 * 应用
 */
public class VisitorClient {
	public static void main(String[] args) {
		ObjectStructure objectStructure = new ObjectStructure();
		objectStructure.attach(new ConcreteElementA());
		objectStructure.attach(new ConcreteElementB());

		Visitor visitor = new ConcreteVisitor();
		objectStructure.accept(visitor);
	}
}

6、示例讲解:

Visitor 定义了访问者的接口,包括访问不同具体元素的方法。
ConcreteVisitor 是具体的访问者实现,实现了对不同具体元素的访问操作。
Element 定义了元素的接口,包括接受访问者访问的方法 accept()
ConcreteElementA 和 ConcreteElementB 是具体的元素实现类,实现了 Element 接口的 accept() 方法,并在其中调用访问者的访问方法。
ObjectStructure 定义了对象结构,可以包含多种不同的元素对象,并提供了接受访问者的方法 accept(),用于遍历其中的元素并调用它们的 accept() 方法。
在 main 方法中,创建了一个具体的对象结构 ObjectStructure,并向其中添加了 ConcreteElementA 和 ConcreteElementB。然后创建了一个具体的访问者 ConcreteVisitor,并调用对象结构的 accept() 方法,传入访问者,从而实现对元素的访问。

;