23种设计模式之访问者模式
目录
1. 简介
访问者设计模式(Visitor Pattern) 是一种行为型设计模式,其核心思想是将数据结构和操作分离,通过将操作封装到独立的访问者对象中,实现对对象结构中的元素进行操作。这种模式允许在不改变现有对象结构的前提下,为对象结构中的元素添加新的操作。
访问者模式包含以下几个主要角色:
访问者(Visitor) :定义了一个访问操作接口,每个操作对应一个对象类型,这些操作是抽象的,具体的实现由具体的访问者类提供。
具体访问者(Concrete Visitor) :实现了访问者接口中的操作,对每个具体对象类型执行特定的行为。
元素(Element) :定义了一个接受访问者的方法,通常称为accept(),以访问者作为参数。
具体元素(Concrete Element) :实现了元素接口中的accept
方法,调用访问者的访问方法来完成对元素的操作。
对象结构(Object Structure) :能够枚举其元素,并提供接口让访问者访问元素。
2. 代码
2.1 ComputerPartVisitor (访问者接口)
public interface ComputerPartVisitor {
void visit(Keyboard keyboard);
void visit(Mouse mouse) ;
void visit(Monitor mouse) ;
void visit(Computer computer) ;
}
2.2 ComputerDisplayVisitor(具体访问者)
public class ComputerDisplayVisitor implements ComputerPartVisitor{
@Override
public void visit(Computer computer) {
System.out.println("Displaying Computer");
}
@Override
public void visit(Keyboard keyboard) {
System.out.println("Displaying Keyboard");
}
@Override
public void visit(Monitor monitor) {
System.out.println("Displaying Monitor");
}
@Override
public void visit(Mouse mouse) {
System.out.println("Displaying Mouse");
}
}
2.3 ComputerPart (元素接口)
public interface ComputerPart {
public void accept(ComputerPartVisitor computerPartVisitor) ;
}
2.4 Mouse (具体元素)
public class Mouse implements ComputerPart{
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
2.5 Monitor(具体元素)
public class Monitor implements ComputerPart{
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
2.6 Keyboard (具体元素)
public class Keyboard implements ComputerPart{
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
2.7 Computer (对象结构类)
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 (ComputerPart part : parts) {
part.accept(computerPartVisitor);
}
computerPartVisitor.visit(this);
}
}
2.8 Test (测试类)
public class Test {
public static void main(String[] args) {
ComputerPart computer = new Computer();
computer.accept(new ComputerDisplayVisitor());
}
}
2.9 运行结果
Displaying Mouse
Displaying Keyboard
Displaying Monitor
Displaying Computer
3. 使用场景
- 对象结构相对稳定但操作频繁变化:当对象结构(如树形结构、图形结构等)相对稳定,而需要对其中的元素进行多种不同的操作时,访问者模式非常适用。例如,在图形编辑器中,可以使用访问者模式来计算所有图形的面积总和,而无需修改原有的图形类。
- 需要对一组对象进行不同的操作:当一组不同类型的对象需要执行一系列操作,而这些操作很少变动时,访问者模式非常适用。操作可以由访问者进行封装和实现,从而避免修改这些对象的代码。
- 跨多个类的操作:当需要对多个不同类的对象执行相同的操作时,可以使用访问者模式将这些操作封装在访问者类中。这样可以避免在每个类中添加额外的方法,从而简化代码。
- 累积与分离操作:当需要对对象结构中的元素进行累积(如求和、统计等)或分离(如过滤、分类等)操作时,访问者模式提供了一种优雅的实现方式。
- 数据结构与操作分离:访问者模式允许将数据结构与数据操作分离,解决数据结构和操作耦合性问题。在被访问的类里面加一个对外提供接待访问者的接口,使得可以在不改变数据结构的前提下添加新的操作。
- 处理复杂嵌套结构:在处理包含多种类型对象并执行依赖于具体类型的操作时,访问者模式可以有效地实现这一需求。例如,在数据库堡垒中引入数据分析访问者实现复杂数据处理,或者在消息传输系统中通过加密访问者增加加密功能。
- 适应未来环境变化:访问者模式提供了一种灵活的方式,允许在不修改对象结构的情况下向对象层次结构添加新操作,适用于需要适应未来环境变化的场景。
访问者模式通过将操作封装到访问者类中,实现了对复杂对象结构的操作,同时保持了代码的可维护性和可扩展性。然而,它也有一定的局限性,主要在于它要求对象结构相对稳定,在对象结构频繁变化的系统中使用会增加维护成本。因此,在使用访问者模式时,需要根据具体情况权衡其优缺点,选择合适的应用场景。
4. 优缺点
优点:
- 扩展性好:访问者模式允许在不修改对象结构的情况下为对象添加新的功能。通过引入新的访问者类,可以轻松地增加新的操作,而无需修改现有的元素类。
- 符合开闭原则:访问者模式遵循开闭原则,即可以在不修改现有代码的情况下增加新的功能。
- 分离职责:访问者模式将数据结构与数据操作分离,使得每个部分都可以独立变化,提高了代码的可维护性。
- 灵活性高:访问者模式允许定义多个不同的访问者,每个访问者执行不同的操作,从而实现灵活的行为扩展。
- 集中操作逻辑:所有的操作逻辑都集中在访问者对象中,避免了将操作分散在多个对象中的情况,提高了代码的可读性和可维护性。
- 符合单一职责原则:访问者模式将相关的行为封装在一起,构成一个访问者,使每一个访问者的功能都比较单一。
缺点:
- 增加复杂性:引入了访问者和元素之间的额外层次,可能会增加代码的复杂性。
- 违反依赖倒置原则:访问者模式依赖于具体类而非抽象类,这可能导致代码的灵活性和可维护性降低。
- 破坏封装性:访问者模式要求具体元素公布内部细节,这违背了迪米特法则,可能导致具体元素变更比较困难。
- 重构抵抗性:当对被访问类进行重构或扩展时,整个访问者类层次结构都需要修改,增加了系统的复杂度。
- 不适用于小规模场景:在小规模场景下,使用访问者模式可能会显得繁琐和过于复杂。
- 增加新元素类困难:每增加一个新的元素类都需要在访问者中添加一个新的抽象操作,并在每一个具体访问者类中实现相应的操作,这违背了开闭原则。
访问者设计模式适用于需要灵活处理不同数据类型、数据结构和数据量变化的场景,如报表生成、数据统计等,能够有效解决数据处理的复杂性和灵活性问题。
5. 总结
将组装过程隐藏,直接就是两行代码完成
原文地址:https://blog.csdn.net/weixin_51395608/article/details/144438182
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!