设计模式 - 访问者模式

news2024/11/22 21:35:19

目录

一. 前言

二. 实现

三. 优缺点


一. 前言

    访问者模式,即在不改变聚合对象内元素的前提下,为聚合对象内每个元素提供多种访问方式,即聚合对象内的每个元素都有多个访问者对象。访问者模式主要解决稳定的数据结构和易变元素的操作之间的耦合问题。

二. 实现

Visitor:访问者,为每一个 ConcreteElement 声明一个 visit 操作。
ConcreteVisitor:具体访问者,存储遍历过程中的累计结果。
ObjectStructure:对象结构,可以是组合结构,或者是一个集合。

public interface Element {
    void accept(Visitor visitor);
}

public class Customer implements Element {
    private String name;
    private List<Order> orders = new ArrayList<>();

    Customer(String name) {
        this.name = name;
    }

    String getName() {
        return name;
    }

    void addOrder(Order order) {
        orders.add(order);
    }

    public void accept(Visitor visitor) {
        visitor.visit(this);
        for (Order order : orders) {
            order.accept(visitor);
        }
    }
}

public class Order implements Element {
    private String name;
    private List<Item> items = new ArrayList();

    Order(String name) {
        this.name = name;
    }

    Order(String name, String itemName) {
        this.name = name;
        this.addItem(new Item(itemName));
    }

    String getName() {
        return name;
    }

    void addItem(Item item) {
        items.add(item);
    }

    public void accept(Visitor visitor) {
        visitor.visit(this);

        for (Item item : items) {
            item.accept(visitor);
        }
    }
}

public class Item implements Element {
    private String name;

    Item(String name) {
        this.name = name;
    }

    String getName() {
        return name;
    }

    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}
class CustomerGroup {
    private List<Customer> customers = new ArrayList<>();

    void accept(Visitor visitor) {
        for (Customer customer : customers) {
            customer.accept(visitor);
        }
    }

    void addCustomer(Customer customer) {
        customers.add(customer);
    }
}
public interface Visitor {
    void visit(Customer customer);

    void visit(Order order);

    void visit(Item item);
}
public class GeneralReport implements Visitor {
    private int customersNo;
    private int ordersNo;
    private int itemsNo;

    public void visit(Customer customer) {
        System.out.println(customer.getName());
        customersNo++;
    }

    public void visit(Order order) {
        System.out.println(order.getName());
        ordersNo++;
    }

    public void visit(Item item) {
        System.out.println(item.getName());
        itemsNo++;
    }

    public void displayResults() {
        System.out.println("Number of customers: " + customersNo);
        System.out.println("Number of orders:    " + ordersNo);
        System.out.println("Number of items:     " + itemsNo);
    }
}
public class Client {
    public static void main(String[] args) {
        Customer customer1 = new Customer("customer1");
        customer1.addOrder(new Order("order1", "item1"));
        customer1.addOrder(new Order("order2", "item1"));
        customer1.addOrder(new Order("order3", "item1"));

        Order order = new Order("order_a");
        order.addItem(new Item("item_a1"));
        order.addItem(new Item("item_a2"));
        order.addItem(new Item("item_a3"));
        Customer customer2 = new Customer("customer2");
        customer2.addOrder(order);

        CustomerGroup customers = new CustomerGroup();
        customers.addCustomer(customer1);
        customers.addCustomer(customer2);

        GeneralReport visitor = new GeneralReport();
        customers.accept(visitor);
        visitor.displayResults();
    }
}
customer1
order1
item1
order2
item1
order3
item1
customer2
order_a
item_a1
item_a2
item_a3
Number of customers: 2
Number of orders:    4
Number of items:     6

三. 优缺点

优点
1. 符合单一职责原则,即数据的存储和操作分别由对象结构类和访问者类实现。
2. 优秀的扩展性和灵活性。
缺点
1. 具体元素对访问者公布了其细节,违反了迪米特法则。
2. 具体元素的增加将导致访问者类的修改,违反了开闭原则。
3. 访问者类依赖了具体类而不是抽象,违反了依赖倒置原则。

JDK中的访问者模式
javax.lang.model.element.Element and javax.lang.model.element.ElementVisitor
javax.lang.model.type.TypeMirror and javax.lang.model.type.TypeVisitor

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1071858.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DCE/RPC协议详解之-数据包请求响应过程

在windows的域环境中有非常多的协议和服务是基于DCE/RPC协议进行实现的,例如NETLOGON,LSA,SAMR,DSSETUP等。因此在 windows的环境下会大量的遇到DCE/RPC协议,因此有必要对该协议有一个初步的了解,这样的话在遇到对应的数据包,则能够比较清楚的还原数据包中发生了什么。本…

长沙旅行见闻实用帖

最近趁着假期&#xff0c;来了趟长沙游&#xff0c;还是有很多值得记录下来的。 众所周知&#xff0c;长沙市是湖南省的省会城市&#xff0c;也是国务院批复确定的长江中游地区重要的中心城市和长株潭城市群中心城市。它位于湖南省中部偏东&#xff0c;湘江下游&#xff0c;辖6…

常见弯道输送机有哪些

提到弯道输送机您可能首先想到的就是弯道滚筒线&#xff0c;其实除了滚筒线之外&#xff0c;也有一些其他线体可以做弯道&#xff0c;下面就为您总结了4种常见的弯道输送机。 1、弯道皮带线&#xff1a;即线体转弯处设计成皮带输送机&#xff0c;这种形式的转弯设计可以实现不同…

Xcode 15 编译出错问题解决

正常升级xcode 15以后发现原来没有出现报错的代码&#xff0c;现在出现了编译错误。&#xff08;如果没有出现请忽略&#xff09;下面教你如何解决这个问题。 1、pod update更新cocoapods&#xff0c;因为其根据xcode15做了很多的更新&#xff0c;保证cocoapods是最新的。 千…

深入理解PKI

安全始终是网络通信的核心议题&#xff0c;PKI提供了一组标准的网络安全组件&#xff0c;可以为通信双方提供加密、完整性保护、认证等安全基础设施。原文: Public Key Infrastructure (PKI) Jacek DylagUnsplash 由于用户名和密码不足以验证用户的身份&#xff0c;因此PKI(公钥…

数据结构 | (二) List

什么是 List 在集合框架中&#xff0c; List 是一个接口&#xff0c;继承自 Collection 。 Collection 也是一个接口 &#xff0c;该接口中规范了后序容器中常用的一些方法&#xff0c;具体如下所示&#xff1a; Iterable 也是一个接口&#xff0c;表示实现该接口的类是可以逐个…

iPhone15手机拓展坞方案,支持手机快充+传输数据功能

手机拓展坞的组合有何意义&#xff1f;首先是数据存储场景&#xff0c;借助拓展坞扩展出的接口&#xff0c;可以连接U盘、移动硬盘等采用USB接口的设备&#xff0c;实现大文件的快速存储或者流转&#xff1b;其次是图片、视频的读取场景&#xff0c;想要读取相机、无人机SD/TF存…

阿里云ESS弹性伸缩的实例配置以及伸缩组规则配置

文章目录 1.配置伸缩组的实例来源信息1.1.创建伸缩组实例来源配置属性1.2.查看创建的伸缩来源配置信息 2.配置伸缩组的触发规则2.1.创建伸缩规则2.2.创建扩展实例的伸缩规则2.3.创建缩减实例的伸缩规则2.4.扩展缩减规则添加完成 1.配置伸缩组的实例来源信息 伸缩组的属性已经配…

自监督DINO论文笔记

论文名称&#xff1a;Emerging Properties in Self-Supervised Vision Transformers 发表时间&#xff1a;CVPR2021 作者及组织&#xff1a; Facebook AI Research GitHub&#xff1a;https://github.com/facebookresearch/dino/tree/main 问题与贡献 作者认为self-supervise…

【计算机网络黑皮书】传输层

【事先声明】 这是对于中科大的计算机网络的网课的学习笔记&#xff0c;感谢郑烇老师的无偿分享 书籍是《计算机网络&#xff08;自顶向下方法 第6版&#xff09;》 需要的可以私信我&#xff0c;无偿分享&#xff0c;课程简介下也有 课程链接 目录 传输服务与协议网络层与传输…

非局部均值滤波的指令集优化和加速(针对5*5的搜索特例,可达到单核1080P灰度图 28ms/帧的速度)。

非局部均值滤波(Non Local Means&#xff09;作为三大最常提起来的去燥和滤波算法之一&#xff08;双边滤波、非局部均值、BM3D&#xff09;&#xff0c;也是有着很多的论文作为研究和比较的对象&#xff0c;但是也是有着致命的缺点&#xff0c;速度慢&#xff0c;严重的影响了…

【Spring】Spring MVC 程序开发

Spring MVC 程序开发 一. 什么是 Spring MVC1. MVC2. Spring、Spring Boot 与 Spring MVC 二. 创建 Spring MVC 项目1. 创建项目2. 用户和程序的映射3. 获取用户请求参数①. 获取单个参数②. 获取多个参数③. 传递对象④. 后端参数重命名&#xff08;后端参数映射&#xff09;R…

谈谈Android Jetpack Compose中的状态提升

谈谈Android Jetpack Compose中的状态提升 在本文中&#xff0c;我们将了解Jetpack Compose中的状态提升&#xff08;State Hoisting&#xff09;。在深入研究这个主题之前&#xff0c;让我们先了解一下Jetpack Compose中的有状态&#xff08;Stateful&#xff09;和无状态&am…

如何快速查询众多未签收快递单号

在日常工作中&#xff0c;快递查询是一个常见的任务。无论是电商卖家、快递员还是收件人&#xff0c;都需要查询快递的状态和信息。然而&#xff0c;一个一个地查询快递单号不仅耗时&#xff0c;还容易出错。因此&#xff0c;使用固乔快递查询助手这样的工具可以大大提高查询效…

Polygon zkEVM递归证明技术文档(5)——附录:借助SNARKjs和PIL-STARK实现proof composition

前序博客有&#xff1a; Polygon zkEVM递归证明技术文档&#xff08;1&#xff09;【主要描述了相关工具 和 证明的组合、递归以及聚合】Polygon zkEVM递归证明技术文档&#xff08;2&#xff09;—— Polygon zkEVM架构设计Polygon zkEVM递归证明技术文档&#xff08;3&#…

【数据结构】计数排序 排序系列所有源代码 复杂度分析(终章)

目录 一&#xff0c;计数排序 1&#xff0c;基本思想 2&#xff0c;思路实现 3&#xff0c;计数排序的特性总结&#xff1a; 二&#xff0c;排序算法复杂度及稳定性分析 三&#xff0c;排序系列所有源代码 Sort.h Sort.c Stack.h Stack.c 一&#xff0c;计数排序 计数…

origin作图上下对开,修改颜色

一般上下对开后默认两幅图颜色相同&#xff0c;如果要修改成不同的颜。双击空白处&#xff0c;在图层栏里取消勾选绘图属性。

基于Java的在线文档编辑管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

BRISK: Binary Robust Invariant Scalable Keypoints全文翻译

pdf链接&#xff1a;https://pan.baidu.com/s/1gFAYMPJStl4cF0CswY9cMQ 提取码&#xff1a;yyds 摘要 从图像中有效和高效地生成关键点是文献中深入研究的问题&#xff0c;并形成了许多计算机视觉应用的基础。该领域的领导者是SIFT和SURF算法&#xff0c;它们在各种图像转换下…

图文结合丨Prometheus+Grafana+GreatSQL性能监控系统搭建指南(上)

一、环境介绍 本文环境&#xff0c;以及本文所采用数据库为GreatSQL 8.0.32-24 $ cat /etc/system-release Red Hat Enterprise Linux Server release 7.9 (Maipo) $ uname -a Linux gip 3.10.0-1160.el7.x86_64 #1 SMP Tue Aug 18 14:50:17 EDT 2020 x86_64 x86_64 x86_64 G…