趣学设计模式之访问者模式
创作时间:
作者:
@小白创作中心
趣学设计模式之访问者模式
引用
CSDN
1.
https://blog.csdn.net/qq_56158663/article/details/146021887
目录
- 一、 啥是访问者模式?
- 二、 为什么要用访问者模式?
- 三、 访问者模式的实现方式
- 四、 访问者模式的优缺点
- 五、 访问者模式的应用场景
- 六、 总结
这篇文章带你详细认识一下设计模式中的访问者模式
一、 啥是访问者模式?
想象一下,你每年都要去医院做一次体检 🏥。 体检的项目有很多,比如量血压、验血、做心电图等等 🩺。 不同的医生负责不同的检查项目,比如内科医生负责量血压,化验师负责验血 🧪。
访问者模式,就是表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作!简单来说,就是把对对象的操作从对象本身分离出来,放到访问者中去执行 👨 ⚕️。
简单来说,就是让不同的“医生(访问者)”来“检查(访问)”你的“身体(元素)”,并执行不同的检查项目!👨 ⚕️+🏥
- 你想对一个对象结构中的对象执行不同的操作,但是你不想修改这些对象的类:就像你想让不同的医生检查你的身体,但是你不想修改你的身体结构 🧍!
- 你想在运行时动态地添加新的操作:就像你想临时增加一个检查项目,比如做核磁共振 🧲!
- 你想把操作和对象结构分离,降低耦合度:就像你想把检查项目和身体分离,让它们可以独立变化 🏥!
二、 为什么要用访问者模式?
用访问者模式,好处多多 👍:
- 分离操作:将操作和对象结构分离,降低耦合度 🔗!
- 增加新操作:可以在不修改对象结构的前提下,增加新的操作 ➕!
- 符合单一职责原则:每个访问者只负责一种操作 👨 ⚕️!
- 易于扩展:可以很容易地添加新的访问者和新的元素 🆕!
三、 访问者模式的实现方式
访问者模式主要包含以下几个角色:
- 访问者(Visitor):声明一个访问操作,针对对象结构中的每一种元素都提供一个访问方法 👨 ⚕️。
- 具体访问者(ConcreteVisitor):实现访问者声明的访问操作,执行具体的操作 👨 ⚕️。
- 元素(Element):定义一个接受访问操作的方法(accept),该方法接受一个访问者作为参数 🧍。
- 具体元素(ConcreteElement):实现元素定义的接受访问操作的方法,通常是将访问者传递给自身 🧍。
- 对象结构(ObjectStructure):包含一组元素,并提供一个方法来让访问者访问这些元素 🏥。
代码示例:
// 访问者接口:医生
public interface Doctor {
void visit(BodyPartA bodyPartA); // 检查身体部位 A
void visit(BodyPartB bodyPartB); // 检查身体部位 B
}
// 具体访问者:内科医生
public class InternalMedicineDoctor implements Doctor {
@Override
public void visit(BodyPartA bodyPartA) {
System.out.println("内科医生检查 " + bodyPartA.getName() + ":量血压");
}
@Override
public void visit(BodyPartB bodyPartB) {
System.out.println("内科医生检查 " + bodyPartB.getName() + ":听诊");
}
}
// 具体访问者:化验师
public class LabTechnician implements Doctor {
@Override
public void visit(BodyPartA bodyPartA) {
System.out.println("化验师检查 " + bodyPartA.getName() + ":验血");
}
@Override
public void visit(BodyPartB bodyPartB) {
System.out.println("化验师检查 " + bodyPartB.getName() + ":验尿");
}
}
// 元素接口:身体部位
public interface BodyPart {
String getName();
void accept(Doctor doctor); // 接受医生
}
// 具体元素:手臂
public class BodyPartA implements BodyPart {
@Override
public String getName() {
return "手臂";
}
@Override
public void accept(Doctor doctor) {
doctor.visit(this); // 接受医生,并将自身传递给医生
}
}
// 具体元素:心脏
public class BodyPartB implements BodyPart {
@Override
public String getName() {
return "心脏";
}
@Override
public void accept(Doctor doctor doctor) {
doctor.visit(this); // 接受医生,并将自身传递给医生
}
}
// 对象结构:身体
public class Body {
private List<BodyPart> bodyParts = new ArrayList<>();
public void add(BodyPart bodyPart) {
bodyParts.add(bodyPart);
}
public void remove(BodyPart bodyPart) {
bodyParts.remove(bodyPart);
}
public void accept(Doctor doctor) {
for (BodyPart bodyPart : bodyParts) {
bodyPart.accept(doctor); // 让每个身体部位接受医生
}
}
}
// 客户端
public class Client {
public static void main(String[] args) {
Body body = new Body(); // 创建身体对象
body.add(new BodyPartA()); // 添加手臂
body.add(new BodyPartB()); // 添加心脏
Doctor internalMedicineDoctor = new InternalMedicineDoctor(); // 创建内科医生
Doctor labTechnician = new LabTechnician(); // 创建化验师
body.accept(internalMedicineDoctor); // 让内科医生检查身体
body.accept(labTechnician); // 让化验师检查身体
}
}
分析:
Doctor是访问者接口,定义了访问不同身体部位的visit方法。InternalMedicineDoctor和LabTechnician是具体访问者,分别实现了内科医生和化验师的检查逻辑。BodyPart是元素接口,定义了accept方法,用于接受医生。BodyPartA和BodyPartB是具体元素,分别代表手臂和心脏,实现了accept方法,将自身传递给医生。Body是对象结构,包含了所有的身体部位,并提供了accept方法,让每个身体部位接受医生。
输出结果:
内科医生检查 手臂:量血压
内科医生检查 心脏:听诊
化验师检查 手臂:验血
化验师检查 心脏:验尿
四、 访问者模式的优缺点
优点:
- 分离操作 🔗!
- 增加新操作 ➕!
- 符合单一职责原则 👨 ⚕️!
- 易于扩展 🆕!
缺点:
- 增加了系统的复杂度 😫!
- 违反了开闭原则(如果增加新的元素,需要修改所有的访问者) ❌!
- 元素必须暴露内部状态给访问者 🙈!
五、 访问者模式的应用场景
- 对对象结构中的对象执行不同的操作,但是你不想修改这些对象的类:就像你想让不同的医生检查你的身体,但是你不想修改你的身体结构 🧍!
- 需要在运行时动态地添加新的操作:就像你想临时增加一个检查项目,比如做核磁共振 🧲!
- 操作和对象结构之间的关系比较稳定:就像检查项目和身体之间的关系比较稳定 🏥!
六、 总结
- 访问者模式就像让不同的“医生(访问者)”来“检查(访问)”你的“身体(元素)”,并执行不同的检查项目! 👨 ⚕️+🏥
- 优点是分离操作、增加新操作、符合单一职责原则、易于扩展! 👍
- 缺点是增加复杂度、违反开闭原则、元素必须暴露内部状态! 👎
- 适用于需要对对象结构中的对象执行不同的操作,但是你不想修改这些对象的类的场景! 🎯
希望这个例子能让你彻底理解访问者模式! 💯 祝你学习愉快! 😄
热门推荐
庄子教你如何修炼心理强大
一江山岛:冬日里的热带沙滩天堂
一江山岛战地文化遗址:从军事遗址到世界遗产
杜甫的藏头诗,你也能写出来吗?
苏轼的藏头诗:智慧与幽默并存
《还珠格格》里的藏头诗,你get到了吗?
铜陵犁桥水镇必打卡美食攻略
长三角慢生活旅游新选择:犁桥水镇
孕期营养餐:科学搭配助你养胎不养肉!
重庆安琪儿妇产医院专家详解:孕期营养搭配全攻略
春节不去人挤人,这8个小众旅行地,适合长假出行,游玩放松
江西上饶十大特色美食,从辣椒炒肉到羊肉粉,每一道都让人垂涎三尺
Excel表格数据美化指南:16种实用技巧让你的数据表格更专业
Excel表格中有效数据区域的快速选择方法
妙佑医疗推荐:成人高烧正确处理法
冬季高烧后如何科学补身体?
阴阳两虚可以通过锻炼来恢复吗
春节打卡贵州绝美景点:荔波小七孔&黄果树瀑布
春节打卡贵州三大必游景点:黄果树、荔波、西江苗寨!
探秘贵州春节:苗寨里的别样年味
新年打卡大佛坊:贵州春节民俗风情体验
缅怀先人:帛事悼念挽词与吊唁用语完整指南
布洛芬、枇杷膏,谁是退烧神器?
谁的工作可能被AI替代?
中科院团队揭示灵芝酸抗癌新机制:可靶向抑制癌细胞葡萄糖代谢
从"沙进人退"到"沙里掘金"——我国沙漠治理带动产业发展观察
苏州两天一晚深度游:园林、博物馆、古街、夜景全体验
AlphaGo大战李世石:算法与算力的巅峰对决
“东数西算”驱动算力爆发,2025年将破369EFLOPS
三国智谋的双星:庞统与诸葛亮的资格比较