访问者模式-Visitor Pattern

设计模式之访问者模式详解(Visitor Pattern) 最复杂的设计模式,并且使用频率不高,《设计模式》的作者评价为:大多情况下,你不需要使用访问者模式,但是一旦需要使用它时,那就真的需要使用了。 访问者模式是一种将数据操作和数据结构分离的设计模式。(觉得太抽象,可以看下面的例子)。 模式的定义与特点 访问者(Visitor)模式的定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的... 阅读详情

1.访问者模式简介

访问者模式(Visitor Pattern)模式是行为型(Behavioral)设计模式,提供一个作用于某种对象结构上的各元素的操作方式,可以使我们在不改变元素结构的前提下,定义作用于元素的新操作。

换言之,如果系统的数据结构是比较稳定的,但其操作(算法)是易于变化的,那么使用访问者模式是个不错的选择;如果数据结构是易于变化的,则不适合使用访问者模式。

访问者模式一共有五种角色:

(1) Vistor(抽象访问者):为该对象结构中具体元素角色声明一个访问操作接口。

(2) ConcreteVisitor(具体访问者):每个具体访问者都实现了Vistor中定义的操作。

(3) Element(抽象元素):定义了一个accept操作,以Visitor作为参数。

(4) ConcreteElement(具体元素):实现了Element中的accept()方法,调用Vistor的访问方法以便完成对一个元素的操作。

(5) ObjectStructure(对象结构):可以是组合模式,也可以是集合;能够枚举它包含的元素;提供一个接口,允许Vistor访问它的元素。

访问者模式类图如下:

 

Visitor Pattern.png

2. 访问者模式举例

如果老师教学反馈得分大于等于85分、学生成绩大于等于90分,则可以入选成绩优秀奖;如果老师论文数目大于8、学生论文数目大于2,则可以入选科研优秀奖。

在这个例子中,老师和学生就是Element,他们的数据结构稳定不变。从上面的描述中,我们发现,对数据结构的操作是多变的,一会儿评选成绩,一会儿评选科研,这样就适合使用访问者模式来分离数据结构和操作。

序号类名角色说明
1VisitorVisitor抽象访问者
2GradeSelectionConcreteVisitor具体访问者
3ResearcherSelectionConcreteVisitor具体访问者
4ElementElement抽象元素
5TeacherConcreteElement具体元素
6StudentConcreteElement具体元素
7ObjectStructureObjectStructure对象结构
8VisitorClient客户端演示调用

举例的类图如下:

 

Award Selection.png

1. Visitor 抽象访问者

/**
 * 抽象访问者,为该对象结构中具体元素角色声明一个访问操作接口。
 */
public interface Visitor {

    void visit(Student element);

    void visit(Teacher element);

}

2. GradeSelection 选拔优秀成绩者

/**
 * 具体访问者,实现了Vistor中定义的操作。
 */
public class GradeSelection implements Visitor {

    private String awardWords = "[%s]的分数是%d,荣获了成绩优秀奖。";

    @Override
    public void visit(Student element) {
        // 如果学生考试成绩超过90,则入围成绩优秀奖。
        if (element.getGrade() >= 90) {
            System.out.println(String.format(awardWords, 
                    element.getName(), element.getGrade()));
        }
    }

    @Override
    public void visit(Teacher element) {
        // 如果老师反馈得分超过85,则入围成绩优秀奖。
        if (element.getScore() >= 85) {
            System.out.println(String.format(awardWords, 
                    element.getName(), element.getScore()));
        }
    }
}

3. ResearcherSelection,选拔优秀科研者

/**
 * 具体访问者,实现了Vistor中定义的操作。
 */
public class ResearcherSelection implements Visitor {

    private String awardWords = "[%s]的论文数是%d,荣获了科研优秀奖。";

    @Override
    public void visit(Student element) {
        // 如果学生发表论文数超过2,则入围科研优秀奖。
        if(element.getPaperCount() > 2){
            System.out.println(String.format(awardWords,
                    element.getName(),element.getPaperCount()));
        }
    }

    @Override
    public void visit(Teacher element) {
        // 如果老师发表论文数超过8,则入围科研优秀奖。
        if(element.getPaperCount() > 8){
            System.out.println(String.format(awardWords,
                    element.getName(),element.getPaperCount()));
        }
    }
}

4. Element,抽象元素角色

/**
 * 抽象元素角色,定义了一个accept操作,以Visitor作为参数。
 */
public interface Element {

    //接受一个抽象访问者访问
    void accept(Visitor visitor);

}

5.Teacher,具体元素

/**
 * 具体元素,允许visitor访问本对象的数据结构。
 */
public class Teacher implements Element {

    private String name; // 教师姓名
    private int score; // 评价分数
    private int paperCount; // 论文数

    // 构造器
    public Teacher(String name, int score, int paperCount) {
        this.name = name;
        this.score = score;
        this.paperCount = paperCount;
    }

    // visitor访问本对象的数据结构
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    public int getPaperCount() {
        return paperCount;
    }

    public void setPaperCount(int paperCount) {
        this.paperCount = paperCount;
    }
}

6. Student,具体元素

/**
 * 具体元素,允许visitor访问本对象的数据结构。
 */
public class Student implements Element {

    private String name; // 学生姓名
    private int grade; // 成绩
    private int paperCount; // 论文数

    // 构造器
    public Student(String name, int grade, int paperCount) {
        this.name = name;
        this.grade = grade;
        this.paperCount = paperCount;
    }

    // visitor访问本对象的数据结构
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getGrade() {
        return grade;
    }

    public void setGrade(int grade) {
        this.grade = grade;
    }

    public int getPaperCount() {
        return paperCount;
    }

    public void setPaperCount(int paperCount) {
        this.paperCount = paperCount;
    }
}

7.ObjectStructure, 对象结构

/**
 * 对象结构,是元素的集合,提供元素的访问入口。
 */
public class ObjectStructure {

    // 使用集合保存Element元素,示例没有考虑多线程的问题。
    private ArrayList<Element> elements = new ArrayList<>();

    /**
     * 访问者访问元素的入口
     *
     * @param visitor 访问者
     */
    public void accept(Visitor visitor) {
        for (int i = 0; i < elements.size(); i++) {
            Element element = elements.get(i);
            element.accept(visitor);
        }
    }

    /**
     * 把元素加入到集合
     *
     * @param element 待添加的元素
     */
    public void addElement(Element element) {
        elements.add(element);
    }

    /**
     * 把元素从集合中移除
     *
     * @param element 要移除的元素
     */
    public void removeElement(Element element) {
        elements.remove(element);
    }
}

8.VisitorClient 客户端

/**
 * 如果教师发表论文数超过8篇或者学生论文超过2篇可以评选科研优秀奖,
 * 如果教师教学反馈分大于等于85分或者学生成绩大于等于90分可以评选成绩优秀奖。
 */
public class VisitorClient {

    public static void main(String[] args) {
        // 初始化元素
        Element stu1 = new Student("Student Jim", 92, 3);
        Element stu2 = new Student("Student Ana", 89, 1);
        Element t1 = new Teacher("Teacher Mike", 83, 10);
        Element t2 = new Teacher("Teacher Lee", 88, 7);
        // 初始化对象结构
        ObjectStructure objectStructure = new ObjectStructure();
        objectStructure.addElement(stu1);
        objectStructure.addElement(stu2);
        objectStructure.addElement(t1);
        objectStructure.addElement(t2);
        // 定义具体访问者,选拔成绩优秀者
        Visitor gradeSelection = new GradeSelection();
        // 具体的访问操作,打印输出访问结果
        objectStructure.accept(gradeSelection);
        System.out.println("----结构不变,操作易变----");
        // 数据结构是没有变化的,如果我们还想增加选拔科研优秀者的操作,那么如下。
        Visitor researcherSelection = new ResearcherSelection();
        objectStructure.accept(researcherSelection);
    }
}

结果输出

[Student Jim]的分数是92,荣获了成绩优秀奖。
[Teacher Lee]的分数是88,荣获了成绩优秀奖。
----结构不变,操作易变----
[Student Jim]的论文数是3,荣获了科研优秀奖。
[Teacher Mike]的论文数是10,荣获了科研优秀奖。

3. 总结

如果一个对象结构比较复杂,同时结构稳定不易变化,但却需要经常在此结构上定义新的操作,那就非常合适使用访问者模式,比如复杂的集合对象、XML文档解析、编译器的设计等。

访问者模式使我们更加容易的增加访问操作,但增加元素比较困难,需要我们修改抽象访问类和所有的具体访问类。

(完)

 

注:简单理解,就是抽象类为接口,具体类为类的实现,然后一个在一个对象类里面创建元素,并然元素接收访问者,这样就可以调用访问者的visit方法。

设计模式 -- 访问者模式(Visitor Pattern) 封装一些作用于某些数据结构中的各元素的操作,它可以在不改变数据结构的前提下赋予这些元素新的操作。 应用场景 对象结构比较稳定,但是需要在对象结构的基础上定义新的操作。 需要对同一个类的不同对象执行不不同的操作,但是不希望增加操作的时候改变这些类。 总结 准确识别出Visitor实用的场景,如果一个对象结构不稳定决不可使用,不然在增删元素时改动将非常巨大。 对象结构中的元素要可以迭代访问 Visitor里一般存在与元素个数相同的visit方法。 元 阅读详情

相关推荐

【设计模式】——访问者模式(Visitor Pattern)

访问者模式(Visitor Pattern)是一种行为型设计模式,用于在不改变现有对象结构的情况下,定义对对象结构中各个元素的访问操作。本文将详细探讨访问者模式在C++中的应用,并通过示例代码进行说明。

J^T的博客 1071

7.9 访问者模式 (Visitor Pattern)

访问者模式

NorthStar的博客 805

【DesignMode】访问者模式(Visitor Pattern)

访问者模式(Visitor Pattern),封装一些作用于某种数据结构的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。主要将数据结构与数据操作分离,解决 数据结构和操作耦合性问题访问者模式的基本工作原理是:在被访问的类里面加一个对外提供接待访问者的接口访问者模式主要应用场景是:需要对一个对象结构中的对象进行很多不同操作(这些操作彼此没有关联),同时需要避免让这些操作"污染"这些对象的类,可以选用访问者模式解决。...

红尘道,红尘练心 167

23种设计模式之访问者模式(Visitor Pattern)

本篇文章将23种设计模式中的访问者模式,此篇文章为一天学习一个设计模式系列文章,后面会分享其他模式知识。

小威的博客 1万+

手把手教你用Python+GDAL处理0.5米吉林一号卫星影像(附代码)

本文详细介绍了如何使用Python和GDAL处理吉林一号0.5米高分辨率卫星影像,包括环境配置、数据预处理、分辨率融合、植被指数计算及地物分类等关键步骤。通过实战代码示例,帮助开发者高效处理大尺寸遥感数据,解决资源崩溃和算法选择问题,提升遥感影像分析能力。

weixin_30892037的博客 128

从零到一:EHB-电机复合制动系统的Simulink仿真实战指南

本文详细介绍了EHB-电机复合制动系统在纯电动汽车中的Simulink仿真实战指南。通过系统概述、建模核心模块解析、控制策略开发及典型问题排查,帮助读者掌握从零到一的开发流程。重点讲解了液压子系统建模、电机再生制动模型及整车动力学集成,为开发者提供了一套完整的解决方案。

hh234的博客 1008

Design Pattern: Visitor and Acyclic Visitor and their differences

DesignPatter: 访问者和无环访问者模式及它们的区别

weixin_43558927的博客 336

EtherCAT主站SOEM -- 18 --Qt-Soem通过CSV模式(周期同步速度模式)控制一个电机转圈圈

以上就是 EtherCAT主站SOEM – 18 --Qt-Soem通过CSV模式(周期同步速度模式)控制一个电机转圈圈 的内容。有不明白的地方欢迎留言;有建议欢迎留言,我后面编写文档好改进。创作不容,如果文档对您有帮助,记得给个赞。

常驻客栈的博客--嵌入式EtherCAT 1212

访问者模式(Visitor Pattern)详解

访问者模式是一种行为型设计模式,它允许在不改变各元素类的前提下定义作用于这些元素的新操作。访问者模式通过将操作与对象结构分离,使得我们可以在不修改对象结构的情况下向现有对象结构添加新的操作。访问者模式是一种强大的设计模式,特别适用于需要在不修改现有类结构的情况下添加新操作的场景。它通过将数据结构与操作分离,实现了良好的扩展性和职责分离。利用"双重分派"机制,根据元素和访问者的实际类型来确定执行的具体方法适合元素类结构稳定但操作多变的场景。

yk_dflkg的博客 1613

基于FPGA的多通道音频信号采样系统设计

FPGA是随着数字集成电路的发展而逐步演变而来的。从早期的电子管、晶体管、小规模集成电路,到超大规模集成电路(VLSIC),数字集成电路的集成度和性能不断提升。FPGA的出现为系统设计师提供了灵活的设计平台,使其能够在不依赖半导体厂商的情况下快速设计专用集成电路(ASIC)。FPGA具有设计周期短、成本低、开发工具先进等优点,广泛应用于原型设计和产品生产中。VHDL是一种用于描述数字系统的硬件描述语言,其语言形式类似于计算机高级语言,但包含了许多硬件特征语句。

qq_62634009的博客 709

请举手回答,LDO和DC-DC有什么不同?

文章目录1 LDO是什么2 LDO典型电路3 DC-DC是什么4 DC-DC典型电路5 LDO和DC-DC区别10.2.6 小结一下 大家好,我是记得诚。 DC-DC和LDO都是电源芯片,两者差异很大,用法也不同,这篇博客讲述LDO和DC-DC的一些差异,帮助更好的认识LDO和DC-DC并进行选型。 1 LDO是什么 LDO是low dropout regulator的简称,即低压差线性稳压器,这是相对于传统的线性稳压器来说的,传统的稳压器,输入比输出要高出很多,否则无法工作,LDO可能输入比输出高1~2V

记得诚 1万+

访问者模式【Visitor Pattern】

今天天气不错,绝对是晴空万里,骄阳似火呀,好,我们今天来讲访问者模式,我们在前面讲了组合模式和迭代器模式,通过组合模式我们能够把一个公司的人员组织机构树搭建起来,给管理带来非常大的便利,通过迭代器模式我们可以把每一个员工都遍历一遍,看看是不是有“人去世了还在领退休金”,“拿高工资而不干活的尸位素餐”等情况,那我们今天的要讲访问者模式是做什么用的呢?        我们公司有七百多技术人员,分布在

admin1973的专栏 1062

DB文件在编程中的作用及示例代码

通过使用DB文件,我们可以实现数据的持久化存储,并能够高效地进行数据的增删改查操作。在本文中,我们以SQLite数据库为例,演示了如何使用Python语言创建和操作DB文件的示例代码。在实际的编程中,我们可以根据具体的需求和使用的数据库系统来进行更复杂的操作和优化。通过使用DB文件,我们可以实现数据的持久化存储,确保数据在程序关闭后也能被保留,并且能够高效地进行数据检索和更新。在本文中,我们将探讨DB文件的作用,并提供一些示例代码展示如何在编程中使用DB文件。上述代码中,我们使用SQLite提供的。

CodeSpark的博客 1822

访问者模式(Visitor Pattern)

设计模式 - 吕震宇 .NET设计模式系列文章 薛敬明的专栏 乐在其中设计模式(C#) 设计模式(20)-Visitor Pattern 一、 访问者(Visitor)模式 访问者模式的目的是封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变。 问题提出 System.Collection命名空间下提供了

jiangxinyu的专栏 1378

万字长文带你由浅入深夯实ARM汇编基础——汇编指令及寻址方式最全梳理(附示例)!

见到汇编就害怕?读完这篇,扫除汇编拦路虎!!(示例丰富,可做手册,随手查阅!)

车载系统攻城狮 1万+

SAN存储与协议,了解SCSI、FC和ISCSI

在前面我们介绍SAN存储及iSCSI协议的时候了解到SAN存储其实是一个CS架构的系统。存储系统本身就是整个系统的服务端。以IP-SAN(也就是基于iSCSI的SAN存储)为例,其整体架构如图1所示。 图1 CS架构 对于存储系统来说,通常是由专业的存储厂商提供,比较知名的如EMC、NetAPP、IBM和日立等等。国内存储厂商也迅速崛起,比较知名的如华为、宏杉、浪潮和同友等等。另外,还有一些小的存储厂商,他们往往集中在某个领域,比如专注文件系统或者块存储等等。 除了专业的存储设备外,其实Linux

shuningzhang的专栏 2685

Java访问者模式(Visitor Pattern)

一、完成测评系统需求 将观众分为男人和女人,对歌手进行测评,当看完某个歌手表演后,得到他们对该歌手不同的评价(评价 有不同的种类,比如 成功、失败 等)。 传统方案 传统方式的问题分析 如果系统比较小,还是ok的,但是考虑系统增加越来越多新的功能时,对代码改动较大,违反了ocp原则, 不利于维护。 扩展性不好,比如 增加了 新的人员类型,或者管理方法,都不好做。 引出我们会使用新的设计模式 ,访问者模式。 二、访问者模式基本介绍 访问者模式(Visitor Pattern),封装一些作用于某

weixin_44256581的博客 816

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

设计模式之Visitor Pattern(访问者模式)

Visitor Pattern 是一种行为设计模式,它允许你在不修改已有类结构的情况下定义新的操作。该模式将算法与其操作的对象结构分离,是解决"双重分发"问题的经典方案。

gwndjsh的博客 338

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

秒懂设计模式之访问者模式(Visitor Pattern)

[版权申明] 非商业目的注明出处可自由转载 博文地址: 出自:shusheng007 设计模式汇总篇,一定要收藏: 永不磨灭的设计模式(有这一篇真够了,拒绝标题党) 文章目录概述类型难度定义使用场景UML 类图实例第一步:构建Element第二步:构建ObjectStructure第三步:构建Visitor客户端使用访问者模式要点总结双分派(dispatch)优缺点优点缺点总结 概述 访问者模式可以说是GOF23中设计模式中最复杂的一个,但日常开发中使用频率却不高,所以说上帝喜欢简洁!增删改查虽然简单,.

ShuSheng007的程序人生 3312

访问者模式 Visitor Pattern

一、模式介绍 1.1、定义 将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方法。 它将对数据的操作与数据结构进行分离,是行为模式中最复杂的一种模式。 1.2、优点 扩展性好。能够在不修改对象结构中的元素的情况下,为对象结构中的元素添加新的功能 复用性好。可以通过访问者来定义整个对象结构通用的功能,从而提高系统的复用程度 灵活性好。访问者模式将数据结构与作用于结构上的操作解耦,使得操作集合可相对自由

木易 288

访问者模式(Visitor Pattern)

访问者模式 在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。 优点: 符合单一职责原则。 秀的扩展性。 灵活性。 缺点: 具体元素对访问者公布细节,违反了迪米特原则。 具体元素...

qq_21344887的博客 334

设计模式-访问者模式(Visitor pattern)理解

马上期末了,一直没看懂访问者模式,今天查了好多资料,算是搞明白了。在这分享一下自己的理解。访问者模式,顾名思义就是遍历集合时,用来访问集合中元素的。这个集合中元素的类型不同,但类型都是已知的,且未来不会改变。访问单个元素的方式有多种,每种方式在访问不同类型的元素时所做的操作不同,并且未来可能会有新的访问方式。举例来说:一个班级里有学霸和学渣两种类型的学生。当出成绩时,学霸开心,学渣不开心。当放假时...

__Eric__的博客 4651

JAVA设计模式之 访问者模式【Visitor Pattern】

一、概述     访问者模式是一种较为复杂的行为型设计模式,它包含访问者和被访问元素两个主要组成部分,这些被访问的元素通常具有不同的类型,且不同的访问者可以对它们进行不同的访问操作。在使用访问者模式时,被访问元素通常不是单独存在的,它们存储在一个集合中,这个集合被称为“对象结构”,访问者通过遍历对象结构实现对其中存储的元素的逐个操作。访问者模式是一种对象行为型模式。 二、适用场景

小吕丶Code阶区 6090

访问者模式 (Visitor Pattern)

行为型设计模式

qq_35861084的博客 1346
上一篇: 浅析 Kubernetes 控制器的工作原理
下一篇: k8s源码分析——kubectl主要框架
cbmljs
博客等级 码龄10年 329粉丝 130原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值