设计模式使用场景实现示例及优缺点(行为型模式——访问者模式)

在一个古老的、被电子设备和程序填满的王国里,所有的程序和设备都各司其职,日复一日地进行着他们预设的任务。然而,随着时间的推移,王国的需要开始变化,旧的程序无法满足新的需求,新的功能需要被引入。但是,要改变这些程序的基本结构非常困难,每次变化都需要巨大的努力和时间。

这时,一个名为“访问者”的智慧法师来到了这个王国。他提出了一个方案,称为“访问者模式”。这个模式允许王国的管理者向程序中添加新的操作,而不需要改变程序本身的结构。法师解释说,通过这种方式,他可以为每一个程序添加特定的“访问”能力,这样每当有新的需求时,只需要引入一个新的访问者,而无需更改程序的内核。

法师首先遇到了一座巨大的数据库堡垒。它原本只能存储和检索数据,但现在需要进行复杂的数据分析。法师引入了一个数据分析访问者,这个访问者能够在不更改数据库结构的情况下,实现复杂的数据处理功能。

接着,法师来到了消息传输系统,这个系统需要增加加密功能以提高安全性。再次,法师引入了一个加密访问者,它在不打扰原有系统运行的前提下,成功地为每条消息添加了加密层。

最后,法师访问了用户界面工厂,这里需要一种方法来支持多种语言,以适应国际化的趋势。法师带来了一个国际化访问者,它可以轻松地为界面添加多语言支持,而不需更改界面本身的代码。

访问者模式(Visitor Pattern)

访问者模式(Visitor Pattern)是一种行为设计模式,允许你向一个对象结构中添加新的操作,而无需改变这些对象的类。它通过将操作逻辑从对象结构中分离出来,使得你可以在不修改这些对象的情况下定义新的操作。

核心组件

  • Visitor(访问者):定义一个接口,为每种类型的元素类声明一个访问操作。
  • ConcreteVisitor(具体访问者):实现每个访问操作,定义对每个元素的具体处理逻辑。
  • Element(元素):定义一个接受访问者的接口。
  • ConcreteElement(具体元素):实现接受访问者的操作,其方法体通常都是访问者访问该元素的入口。
  • ObjectStructure(对象结构):一个元素的集合,可以遍历其内的所有元素,以供访问者访问。

适用场景

  1. 操作复杂的对象结构
    • 当一个对象结构包含多种类型的对象,且你希望对这些对象执行一些依赖于其具体类的操作。
  2. 业务规则要求遍历多个不同的对象
    • 如果你需要对一个复合对象进行很多不同并且不相关的操作,但你不想让这些操作“污染”这些对象的类,使用访问者模式可以将相关的操作集中起来。

实现实例

以计算机硬件结构的维护和信息提取为例,使用访问者模式来区分各硬件部件的操作。

访问者接口(Visitor Interface)

定义了对每个元素类访问的操作。

public interface ComputerPartVisitor {
    void visit(Computer computer);
    void visit(Mouse mouse);
    void visit(Keyboard keyboard);
    void visit(Monitor monitor);
}
具体元素类(Concrete Element)

实现接受访问者的方法。

public class Computer implements ComputerPart {
    ComputerPart[] parts;

    public Computer(){
        parts = new ComputerPart[] {new Mouse(), new Keyboard(), new Monitor()};
    }

    public void accept(ComputerPartVisitor computerPartVisitor) {
        for (int i = 0; i < parts.length; i++) {
            parts[i].accept(computerPartVisitor);
        }
        computerPartVisitor.visit(this);
    }
}
具体访问者(Concrete Visitor)

实现访问者接口,定义对每个元素的具体操作。

public class ComputerPartDisplayVisitor implements ComputerPartVisitor {
    public void visit(Computer computer) {
        System.out.println("Displaying Computer.");
    }

    public void visit(Mouse mouse) {
        System.out.println("Displaying Mouse.");
    }

    public void visit(Keyboard keyboard) {
        System.out.println("Displaying Keyboard.");
    }

    public void visit(Monitor monitor) {
        System.out.println("Displaying Monitor.");
    }
}
客户端代码(Client Code)

演示访问者模式的使用。

public class Client {
    public static void main(String[] args) {
        ComputerPart computer = new Computer();
        computer.accept(new ComputerPartDisplayVisitor());
    }
}

优缺点

优点
  1. 增加新操作容易
    • 在不修改现有对象结构的情况下,可以很容易地向现有对象结构中添加新操作。
  2. 集中相关操作
    • 通过将相关操作集中在一个访问者类中,可以改进系统的组织和清晰度。
缺点
  1. 增加新类困难
    • 如果需要增加一个新的具体元素类,所有的访问者类都需要修改,这可能会带来维护问题。
  2. 打破封装
    • 访问者假设具体元素类的实现细节是公开的,这可能会破坏对象的封装性。

类图

+------------------+         +----------------+         +-----------------+
|   Visitor        |<--------|   Element      |<--------|  ConcreteElement|
+------------------+         +----------------+         +-----------------+
| + visit(...)     |         | + accept(...)  |         | + accept(...)   |
+------------------+         +----------------+         +-----------------+
                              |                          |
                              v                          v
                      +----------------+         +-----------------+
                      |  ConcreteVisitor      |         |  ConcreteElement   |
                      +----------------+         +-----------------+
                      | + visit(...)     |         | + accept(...)   |
                      +----------------+         +-----------------+

总结

访问者模式允许你将操作添加到对象结构中,而不改变这些对象的类。它特别适用于那些对象结构相对稳定,但其上的操作经常变化的系统。通过这种方式,可以将操作的实现与对象结构分离开,从而增强系统的灵活性和可维护性。

  • 14
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

懒人w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值