设计模式:访问者模式

文章目录

定义

访问者模式(Visitor Pattern)是一种将算法与对象结构分离的设计模式。这种模式中,可以在不修改已有程序结构的前提下,通过添加额外的"访问者"来定义作用于对象结构中各元素的新操作。它主要解决的是稳定的数据结构和易变的操作耦合问题。

应用场景

  • 当一个对象结构包含很多类对象,且这些类的对象对应的操作经常变化时。
  • 当需要对一个复杂的对象结构进行一些不依赖于对象具体类型的操作时。
  • 当需要对对象结构中的对象进行很多不同且不相关的操作,而需要避免让这些操作"污染"对象的类时。

示例代码

假设有一个电子商务系统,需要对不同类型的用户(如普通用户和VIP用户)进行不同的促销活动。

访问者接口 和具体的访问者实现

java 复制代码
interface Visitor {
    void visit(NormalUser user);
    void visit(VIPUser user);
}

class PromotionVisitor implements Visitor {
    @Override
    public void visit(NormalUser user) {
        System.out.println("给普通用户发送优惠券");
    }

    @Override
    public void visit(VIPUser user) {
        System.out.println("给VIP用户发送优惠券和积分");
    }
}

用户类接受访问的接口

java 复制代码
interface User {
    void accept(Visitor visitor);
}

class NormalUser implements User {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

class VIPUser implements User {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

客户端代码

java 复制代码
public class Client {
    public static void main(String[] args) {
        List<User> users = Arrays.asList(new NormalUser(), new VIPUser());
        Visitor promotion = new PromotionVisitor();
        
        for (User user : users) {
            user.accept(promotion);
        }
    }
}

反例

当对象结构非常稳定,几乎不会新增元素类型,同时操作经常变化时,使用访问者模式是合适的。如果对象结构经常变化,则每次新增类型都需要修改访问者接口和所有实现类,这违背了开闭原则,此时应考虑其他设计模式。

原则间的权衡与冲突

  • 开闭原则:访问者模式支持在不修改已有对象结构的情况下,向已有对象结构中添加新操作,符合开闭原则。但如果需要添加新的元素类,就需要修改访问者接口及其所有实现,这违背了开闭原则。
  • 单一职责原则:访问者模式允许将操作逻辑从对象结构中分离出来,每个访问者执行特定的操作,符合单一职责原则。

设计模式的局限性

  • 增加新的元素类比较困难,每添加一个新的元素类,都要在Visitor接口中添加一个新的访问操作,并在所有的访问者实现类中实现该操作,这使得系统变得复杂。
  • 访问者模式使得对象结构的修改变得困难,因为访问者依赖于对象结构中元素的具体类。

总结与建议

访问者模式适用于对象结构相对稳定,而操作易变的场景。它使得增加新操作变得简单,但增加新的元素类较为复杂。在使用访问者模式时,应该权衡其带来的灵活性和可能的复杂性。在对象结构频繁变化的场景下,应考虑其他设计模式。

相关推荐
朱一头zcy1 天前
设计模式入门:简单认识单例模式、模板方法、工厂模式、装饰模式、动态代理
java·设计模式
我爱cope1 天前
【从0开始学设计模式-10| 装饰模式】
java·开发语言·设计模式
sg_knight1 天前
设计模式实战:责任链模式(Chain of Responsibility)
python·设计模式·责任链模式
Pkmer2 天前
古法编程: 代理模式
后端·设计模式
Pkmer2 天前
古法编程: 责任链模式
后端·设计模式
Kel2 天前
LangChain.js 架构设计深度剖析
人工智能·设计模式·架构
Pkmer2 天前
古法编程: 装饰器模式
设计模式·全栈
深海鱼在掘金2 天前
从Claude Code泄露源码看工程架构:第九章 —— Claude Code 与架构的总结展望
人工智能·设计模式·架构
深海鱼在掘金2 天前
从Claude Code泄露源码看工程架构:第六章 —— 权限系统的四道闸门与纵深防御机制
人工智能·设计模式·架构
深海鱼在掘金2 天前
从Claude Code泄露源码看工程架构:第八章 —— MCP 接入层设计
人工智能·设计模式·架构