设计模式-访问者模式

简介

访问者模式是一种行为设计模式,它允许你向一个对象结构(通常是一个复杂的对象组合)添加更多操作而无需修改这些对象的类 。这种模式是通过创建一个外部的访问者类来实现的,这个类实现了对各种元素(组成对象的部分)的操作

角色

  • 访问者 (Visitor) :一个接口或抽象类,定义了对各种元素(Element)执行操作的方法。
  • 具体访问者 (Concrete Visitor):实现访问者接口的类,定义了对每种类型元素执行的具体操作。
  • 元素 (Element):接口或抽象类,定义了一个accept方法,该方法接受一个访问者对象。
  • 具体元素 (Concrete Element):实现元素接口的类,定义了元素的具体数据和accept方法的具体执行。
  • 对象结构 (Object Structure):一个集合或复合对象,包含元素对象,能枚举其元素,可能提供一个高层接口以允许访问者访问其元素。

示例实现

假设我们有一个电子商务系统,其中有多种类型的用户,我们想要对这些用户的数据执行不同的操作,例如生成报表、发送通知等。

  • 首先,定义元素和访问者接口:

    javascript 复制代码
    // 定义元素接口
    class User {
      accept(visitor) {}
    }
    
    // 定义访问者接口
    class Visitor {
      visitUser(user) {}
      visitAdmin(admin) {}
    }
    
    // 具体元素
    class RegularUser extends User {
      constructor(name) {
        super();
        this.name = name;
      }
    
      accept(visitor) {
        visitor.visitUser(this);
      }
    }
    
    class AdminUser extends User {
      constructor(name) {
        super();
        this.name = name;
      }
    
      accept(visitor) {
        visitor.visitAdmin(this);
      }
    }
  • 然后,实现具体的访问者:

    javascript 复制代码
    // 具体访问者
    class ReportVisitor extends Visitor {
      visitUser(user) {
        console.log(`Generating report for regular user: ${user.name}`);
      }
    
      visitAdmin(admin) {
        console.log(`Generating report for admin user: ${admin.name}`);
      }
    }
    
    class NotificationVisitor extends Visitor {
      visitUser(user) {
        console.log(`Sending notification to user: ${user.name}`);
      }
    
      visitAdmin(admin) {
        console.log(`Sending notification to admin: ${admin.name}`);
      }
    }
  • 最后,使用这些类:

    javascript 复制代码
    const users = [
      new RegularUser('Alice'),
      new AdminUser('Bob')
    ];
    
    const reportVisitor = new ReportVisitor();
    const notificationVisitor = new NotificationVisitor();
    
    users.forEach(user => {
      user.accept(reportVisitor);
      user.accept(notificationVisitor);
    });

总结

  • 访问者模式在 JavaScript 中可能不像在 Java 或 C# 中那样常见,因为 JavaScript 的灵活性允许我们在运行时添加或更改对象的行为。
  • 在处理复杂的对象结构,特别是当这些结构在多个不同的上下文中以不同的方式被处理时,访问者模式提供了一种清晰和可维护的方式来分离操作和对象本身。
  • 这种模式特别适合于库和框架,其中对象结构预定义,而操作则由最终用户通过访问者来定义。
相关推荐
梅头脑1 天前
学了6种设计模式却写出了同事看不懂的代码——SOLID五原则反例对照,治好了我的"过度设计"
设计模式
workflower1 天前
案例:大模型驱动的“发现- 研判- 整改- 验证”全闭环治理体系
人工智能·深度学习·机器学习·设计模式·机器人
董员外1 天前
RAG 系统进化论(九):RAG 评测,怎样证明系统真的变好了?
人工智能·设计模式·程序员
西安小哥1 天前
AI时代技术工程师的"道法术器势":学习图谱、成长规划与角色重塑
人工智能·设计模式·程序员
莫得感情 o1 天前
设计模式 08 · 装饰器模式
设计模式·装饰器模式
董员外2 天前
RAG 系统进化论(八):Agentic RAG(智能体式 RAG),从回答问题到完成任务
人工智能·后端·设计模式
董员外2 天前
RAG 系统进化论(七):Multimodal RAG(多模态 RAG),当知识存在于表格、图片和页面中
人工智能·后端·设计模式
大山同学2 天前
第 2 篇(03-04 章):代理设计原则与工具使用设计模式
设计模式
啦啦啦啦啦zzzz3 天前
设计模式:桥接模式和组合模式
c++·设计模式·组合模式·桥接模式
莫得感情 o3 天前
设计模式 03 · 工厂方法模式
设计模式·工厂方法模式