在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。 双龙物流
介绍
意图
旨在将数据结构与在该数据结构上执行的操作分离,从而使得添加新的操作变得更容易,而无需修改数据结构本身。
主要解决的问题
- 解决在稳定数据结构和易变操作之间的耦合问题,使得操作可以独立于数据结构变化。
使用场景
- 当需要对一个对象结构中的对象执行多种不同的且不相关的操作时,尤其是这些操作需要避免”污染”对象类本身。
实现方式
- 定义访问者接口:声明一系列访问方法,一个访问方法对应数据结构中的一个元素类。
- 创建具体访问者:实现访问者接口,为每个访问方法提供具体实现。
- 定义元素接口:声明一个接受访问者的方法。
- 创建具体元素:实现元素接口,每个具体元素类对应数据结构中的一个具体对象。
关键代码
- 访问者接口:包含访问不同元素的方法。
- 具体访问者:实现了访问者接口,包含对每个元素类的访问逻辑。
- 元素接口:包含一个接受访问者的方法。
- 具体元素:实现了元素接口,提供给访问者访问的入口。
应用实例
- 做客场景:访问者(如您)访问朋友家,朋友作为元素提供信息,访问者根据信息做出判断。
优点
- 单一职责原则:访问者模式符合单一职责原则,每个类只负责一项职责。
- 扩展性:容易为数据结构添加新的操作。
- 灵活性:访问者可以独立于数据结构变化。
缺点
- 违反迪米特原则:元素需要向访问者公开其内部信息。
- 元素类难以变更:元素类需要维持与访问者的兼容。
- 依赖具体类:访问者模式依赖于具体类而不是接口,违反了依赖倒置原则。
使用建议
- 当对象结构稳定,但需要在其上定义多种新操作时,考虑使用访问者模式。
- 当需要避免操作”污染”对象类时,使用访问者模式封装操作。
注意事项
- 访问者模式可以用于功能统一,如报表生成、用户界面显示、拦截器和过滤器等。
包含的几个主要角色
-
访问者(Visitor):
- 定义了访问元素的接口。
-
具体访问者(Concrete Visitor):
- 实现访问者接口,提供对每个具体元素类的访问和相应操作。
-
元素(Element):
- 定义了一个接受访问者的方法。
-
具体元素(Concrete Element):
- 实现元素接口,提供一个
accept
方法,允许访问者访问并操作。
- 实现元素接口,提供一个
-
对象结构(Object Structure)(可选):
- 定义了如何组装具体元素,如一个组合类。
-
客户端(Client)(可选):
- 使用访问者模式对对象结构进行操作。
实现 双龙物流
我们将创建一个定义接受操作的 ComputerPart 接口。Keyboard、Mouse、Monitor 和 Computer 是实现了 ComputerPart 接口的实体类。我们将定义另一个接口 ComputerPartVisitor,它定义了访问者类的操作。Computer 使用实体访问者来执行相应的动作。
VisitorPatternDemo,我们的演示类使用 Computer、ComputerPartVisitor 类来演示访问者模式的用法。
步骤 1
定义一个表示元素的接口。
ComputerPart.java
public interface ComputerPart { public void accept(ComputerPartVisitor computerPartVisitor); }
步骤 2
创建扩展了上述类的实体类。
Keyboard.java
public class Keyboard implements ComputerPart { @Override public void accept(ComputerPartVisitor computerPartVisitor) { computerPartVisitor.visit(this); } }
Monitor.java
public class Monitor implements ComputerPart { @Override public void accept(ComputerPartVisitor computerPartVisitor) { computerPartVisitor.visit(this); } }
Mouse.java
public class Mouse implements ComputerPart { @Override public void accept(ComputerPartVisitor computerPartVisitor) { computerPartVisitor.visit(this); } }
Computer.java
public class Computer implements ComputerPart { ComputerPart[] parts; public Computer(){ parts = new ComputerPart[] {new Mouse(), new Keyboard(), new Monitor()}; } @Override public void accept(ComputerPartVisitor computerPartVisitor) { for (int i = 0; i < parts.length; i++) { parts[i].accept(computerPartVisitor); } computerPartVisitor.visit(this); } }
步骤 3
定义一个表示访问者的接口。
ComputerPartVisitor.java
public interface ComputerPartVisitor { public void visit(Computer computer); public void visit(Mouse mouse); public void visit(Keyboard keyboard); public void visit(Monitor monitor); }
步骤 4
创建实现了上述类的实体访问者。
ComputerPartDisplayVisitor.java
public class ComputerPartDisplayVisitor implements ComputerPartVisitor { @Override public void visit(Computer computer) { System.out.println(“Displaying Computer.“); } @Override public void visit(Mouse mouse) { System.out.println(“Displaying Mouse.“); } @Override public void visit(Keyboard keyboard) { System.out.println(“Displaying Keyboard.“); } @Override public void visit(Monitor monitor) { System.out.println(“Displaying Monitor.“); } }
步骤 5
双龙物流使用 ComputerPartDisplayVisitor 来显示 Computer 的组成部分。
VisitorPatternDemo.java
public class VisitorPatternDemo { public static void main(String[] args) { ComputerPart computer = new Computer(); computer.accept(new ComputerPartDisplayVisitor()); } }
步骤 6 双龙物流
执行程序,输出结果:
Displaying Mouse. Displaying Keyboard. Displaying Monitor. Displaying Computer. 双龙物流
1.本站内容仅供参考,不作为任何法律依据。用户在使用本站内容时,应自行判断其真实性、准确性和完整性,并承担相应风险。
2.本站部分内容来源于互联网,仅用于交流学习研究知识,若侵犯了您的合法权益,请及时邮件或站内私信与本站联系,我们将尽快予以处理。
3.本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
4.根据《计算机软件保护条例》第十七条规定“为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。”您需知晓本站所有内容资源均来源于网络,仅供用户交流学习与研究使用,版权归属原版权方所有,版权争议与本站无关,用户本人下载后不能用作商业或非法用途,需在24个小时之内从您的电脑中彻底删除上述内容,否则后果均由用户承担责任;如果您访问和下载此文件,表示您同意只将此文件用于参考、学习而非其他用途,否则一切后果请您自行承担,如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
5.本站是非经营性个人站点,所有软件信息均来自网络,所有资源仅供学习参考研究目的,并不贩卖软件,不存在任何商业目的及用途
暂无评论内容