访问者模式
访问者模式是封装一些施加于某种数据结构元素之上的操作,一旦这些操作需要修改,接受这个操作的数据结构则可以保持不变
访问者模式的定义
封装一些用于某种数据结构中的各元素的操作,他可以在不改变数据结构的前提下定义这些元素的新操作。
访问者模式的参与者:
- visitor 抽象访问者:该角色声明一个或多个访问操作,定义访问者可以访问那些元素
- Concrete Visitor 具体访问者角色:该角色实现抽象访问角色中的各个操作
- Element 抽象元素角色:该角色声明一个接受操作接受一个访问者对象
- Concrete Element 具体元素角色:该角色实现抽象元素中的接受操作
- Object Structure 结构对象角色:该角色一般用于容纳多个元素对象,一般情况下,很难抽象出这个角色。
访问者模式的简单示例
抽象元素角色
public interface Element {
public void doSomething();
//声明一个接受操作,接受一个访问者对象
public void accept(Visitor v);
}
具体元素角色
- 具体元素1
public class ConcreteElement1 implements Element {
@Override
public void doSomething() {
System.out.println("与模范1坐在一起聊天");
}
// 实现抽象元素中的接受操作
@Override
public void accept(Visitor v) {
v.visit(this);
}
}
- 具体元素2
public class ConcreteElement2 implements Element {
@Override
public void doSomething() {
System.out.println("与模范2吃家常饭");
}
@Override
public void accept(Visitor v) {
v.visit(this);
}
}
抽象访问者角色
public interface Visitor {
// 声明访问者要访问那些元素
public void visit(ConcreteElement1 e1);
public void visit(ConcreteElement2 e2);
}
具体访问者角色
- 访问者1
public class ConcreteVisitor1 implements Visitor {
// 实现访问方法的具体过程
@Override
public void visit(ConcreteElement1 e1) {
System.out.println("1号领导嘘寒问暖,然后握手");
System.out.print("1号领导");
e1.doSomething();
}
@Override
public void visit(ConcreteElement2 e2) {
System.out.println("1号领导视察生活条件,然后握手");
System.out.print("1号领导");
e2.doSomething();
}
}
- 访问者2
public class ConcreteVisitor2 implements Visitor {
@Override
public void visit(ConcreteElement1 e1) {
System.out.println("2号领导表示亲切慰问");
System.out.print("2号领导");
e1.doSomething();
}
@Override
public void visit(ConcreteElement2 e2) {
System.out.println("2号领导表示亲切关怀");
System.out.print("2号领导");
e2.doSomething();
}
}
结构对象角色
public class ObjectStructure {
private Vector<Element> elements;
public ObjectStructure(){
this.elements = new Vector<>();
}
public void add(Element e) {
elements.add(e);
}
public void action(Visitor vi){
for (Element e: elements) {
e.accept(vi);
}
}
}
访问者模式的优缺点和使用场景
访问者模式的优点
- 访问者模式使得易于增加新的操作
- 访问者集中相关操作而分离无关操作
- 符合单一职责原则
访问者模式的缺点
- 增加新的 ConcreteElement 类很困难
- 具体元素对访问者公布细节
- 违背了依赖倒置原则
访问者模式的使用场景
- 一个对象结构有很多类,他们有不同的接口,当对这些对象实施依赖于具体类的操作时,即使用迭代器模式下不能胜任的场景
- 需要对一个对象结构中进行很多不同且不相关的操作,避免操作污染类
- 业务规则要求遍历多个不同对象,迭代器模式只能访问相同类或同接口的数据,而访问者模式是对迭代器模式的扩充,可以遍历不同的对象,执行不同的操作。
Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。
它的内容包括:
- 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
- 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
- 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
- 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
- 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
- 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
- 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
- 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw
目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:
想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询
同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。