访问者模式

简介: • 定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。它将对数据的操作与数据结构进行分离,是行为类模式中最复杂的一种模式。


定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。它将对数据的操作与数据结构进行分离,是行为类模式中最复杂的一种模式。

优点:1.扩展性好。方便添加新的访问者。

          2. 复用性好。可以通过访问者来定义整个对象结构通用的功能,从而提高系统的复用程度。

          3.灵活性好。访问者模式将数据结构与作用于结构上的操作解耦,使得操作集合可相对自由地演化而不影响系统的数据结构。

           4.符合单一职责原则。访问者模式把相关的行为封装在一起,构成一个访问者,使每一个访问者的功能都比较单一。

缺点:1.破坏封装。访问者模式中具体元素对访问者公布细节,这破坏了对象的封装性。

           2.违反了依赖倒置原则。访问者模式依赖了具体类,而没有依赖抽象类。

           3、具体访问者元素变更比较困难。

使用场景:不同的人使用不同的方法,避免使用if-else。

原理:把需要调用的方法的实现写在调用者自己的类中,被调用者依赖于调用者。

类图:

image.png

实例代码

访问者接口

1. public interface Visitor {
2. void visit(ConcreteElementA elementA);
3. void visit(ConcreteElementB elementB);
4. }

访问者实现

1. public class ConcreteVisitorA implements Visitor {
2. 
3. 
4. @Override
5. public void visit(ConcreteElementA elementA) {
6. 
7.     }
8. 
9. @Override
10. public void visit(ConcreteElementB elementB) {
11. 
12.     }
13. }
1. public class ConcreteVisitorB implements Visitor {
2. @Override
3. public void visit(ConcreteElementA elementA) {
4. 
5.     }
6. 
7. @Override
8. public void visit(ConcreteElementB elementB) {
9. 
10.     }
11. }

抽象元素 一般定义一个accept方法

1. public interface Element {
2. void accept(Visitor visitor);
3. }

具体元素

1. public class ConcreteElementA implements Element {
2. public void accept(Visitor visitor) {
3. System.out.println("访问A");
4.         visitor.visit(this);
5.     }
6. }
1. public class ConcreteElementB implements Element {
2. public void accept(Visitor visitor) {
3. System.out.println("访问b");
4.         visitor.visit(this);
5.     }
6. }

ObjectStructure存放具体元素对象的集合

1. public class ObjectStructure {
2. private List<Element> mElements = new ArrayList<>();
3. 
4. public void addElement(Element e) {
5.         mElements.add(e);
6.     }
7. 
8. public void removeElement(Element e) {
9.         mElements.remove(e);
10.     }
11. 
12. public void accpet(Visitor visitor) {
13. for (Element e : mElements) {
14.             e.accept(visitor);
15.         }
16.     }
17. }

调用

1. ObjectStructure os = new ObjectStructure();
2.     os.addElement(new ConcreteElementA());
3.     os.addElement(new ConcreteElementB());
4. //创建一个访问者
5. Visitor visitor = new ConcreteVisitorA();
6.     os.accpet(visitor);

代码

访问者接口

1. public interface Visitor {
2. 
3. void visit(Cavalry cavalry);
4. 
5. void visit(Infantry infantry);
6. }

 

访问者实现

1. public class liyunlong implements Visitor{
2. 
3. void visit(Cavalry cavalry){
4.       system.out.print("你们砍了多少鬼子啊" + cavalry.num)
5.     }
6. 
7. void visit(Infantry infantry){
8.        system.out.print("你们砍了多少鬼子啊" + infantry.num)
9. }
10. }
1. public class zhaogang implements Visitor{
2. 
3. void visit(Cavalry cavalry){
4.       system.out.print("你们背了多少条例啊" + cavalry.num)
5.     }
6. 
7. void visit(Infantry infantry){
8.       system.out.print("你们背了多少条例啊" + infantry.num)
9. }
10. }

具体元素接口

1. public interface Element {
2. 
3. // 核心方法,接受Visitor的访问
4. public void accept(Visitor visitor);
5. }

具体元素实现

1. public class Cavalry implements Element {
2. 
3. private int num;
4. //构造方法
5. public void accept(Visitor visitor) {
6.         System.out.println("骑兵");
7.         visitor.visit(this);
8.     }
9. }
1. public class Infantry implements Element {
2. private int num;
3. //构造方法
4. public void accept(Visitor visitor) {
5.         System.out.println("步兵");
6.         visitor.visit(this);
7.     }
8. }

管理类

1. public class ObjectStructure {
2. private List<Element> mElements = new ArrayList<>();
3. 
4. public void addElement(Element e) {
5.         mElements.add(e);
6.     }
7. 
8. public void removeElement(Element e) {
9.         mElements.remove(e);
10.     }
11. 
12. public void accpet(Visitor visitor) {
13. for (Element e : mElements) {
14.             e.accept(visitor);
15.         }
16.     }
17. }

调用

1. ObjectStructure os = new ObjectStructure();
2.     os.addElement(new Cavalry(10));
3.     os.addElement(new Infantry(22));
4. //创建一个访问者
5. Visitor visitor = new liyunlong();
6.     os.accpet(visitor);

 

经典实现场景

https://www.cnblogs.com/edisonchou/p/7247990.html


相关文章
|
2月前
|
设计模式 编译器 C#
访问者模式
访问者模式是一种行为型设计模式,用于将数据结构与其操作解耦。通过在不改变数据结构的前提下增加新的操作,访问者模式提供了一种灵活的方式来实现功能扩展。其关键特性包括分离操作、支持扩展和双分派机制。适用于需要对对象结构中的元素执行多种操作、频繁扩展操作以及不希望操作逻辑和数据结构耦合的场景。常见的使用案例包括编译器中的语法树、文件系统和游戏场景。优点是增加操作时无需修改数据结构,符合开闭原则;缺点是添加新的数据结构类型时需要修改所有访问者类,维护成本较高。
53 3
|
6月前
|
设计模式 Java
访问者模式问题之在不使用访问者模式的情况下,怎么在一个 SelectNode 类中实现 extractFunctions 方法
访问者模式问题之在不使用访问者模式的情况下,怎么在一个 SelectNode 类中实现 extractFunctions 方法
|
设计模式 算法
行为型设计模式11-访问者模式
行为型设计模式11-访问者模式
59 1
|
9月前
|
算法
行为型 访问者模式
行为型 访问者模式
67 0
|
9月前
|
设计模式 uml C++
行为型 迭代器模式
行为型 迭代器模式
51 0
|
设计模式 算法 BI
设计模式~访问者模式(Visitor)-15
在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对
58 0
|
设计模式 程序员
访问者模式是啥?咋实现呀?
访问者模式是啥?咋实现呀?
|
设计模式
我学会了,访问者模式
访问者模式属于行为型模式,这个类型的设计模式总结出了 类、对象之间的经典交互方式,将类、对象的行为和使用解耦了,花式的去使用对象的行为来完成特定场景下的功能。
127 0
我学会了,访问者模式
|
设计模式 算法 Java
观察者模式和访问者模式(1)
观察者模式和访问者模式(1)
217 0
观察者模式和访问者模式(1)