23种设计模式之访问者模式

访问者模式的定义

定义: 封装一些作用于某种数据结构中的各元素的操作, 它可以在不改变数据结构的前提下定义作用于这些元素的新的操作

通俗的说, 就是定义一个访问者角色, 当对指定角色进行访问时要通过访问者进行访问

其类图如下:

23种设计模式之访问者模式

 

各角色说明:

  1. Vistor 抽象访问者: 抽象类或接口, 声明访问者可以访问哪些元素, 具体到程序中就是 visit 方法的参数定义哪些对象是可以被访问的
  2. ConcreteVistor 具体访问者: 它影响访问者访问到一个类后该怎么干, 要做什么事
  3. Element 抽象元素: 接口或抽象类, 声明接受哪一类访问者访问, 程序上是通过 accept 方法中的参数来定义的
  4. ConcreteElement 具体元素: 实现 accept方法, 通常是 visitor.visit(this); 基本上都形成一种模式了
  5. ObjectStruture 结构对象: 元素的生成者, 一般容纳在多个不同类、不同接口的容器, 项目中一般很少抽象出这个角色

抽象元素代码:

23种设计模式之访问者模式

 

具体元素代码:

23种设计模式之访问者模式

 

抽象访问者代码:

23种设计模式之访问者模式

 

具体访问者代码:

23种设计模式之访问者模式

 

结构对象用来产生不同的元素对象, 代码如下:

23种设计模式之访问者模式

 

场景类代码:

23种设计模式之访问者模式

 

通过增加访问者, 这要是具体元素就非常容易访问, 对元素的遍历就更加容易了, 甭管它是什么对象, 只要它在一个容器中, 都可以通过访问者来访问, 任务集中化.

访问者模式的应用

访问者模式的优点:

  1. 符合单一职责原则. 具体元素角色负责数据的加载, 而访问者角色负责报表的展现, 两个不同的职责非常明确的分离开来, 各自演绎变化
  2. 优秀的扩展. 由于职责分开,继续增加 对数据的操作是非常快捷的.
  3. 灵活性非常高. 例如, 当需要对不同的具体元素进行分别统计时, 使用 instanceof 循环判断当然也可以, 但是现在有一个好办法, 那就是把它丢给访问者,由访问者来进行统计计算

访问者模式的缺点:

  1. 具体元素对访问者公布细节. 访问者要访问一个类就必然要求这个类公布一些方法和数据, 也就是说访问者关注了其他类的内部细节, 这也是迪米特法则所不建议的
  2. 具体元素变更比较困难. 具体元素角色的增加、删除、修改是比较困难的
  3. 违背了依赖倒置原则. 访问者依赖的是具体元素, 而不是抽象元素, 这破坏了依赖倒置原则, 特别是在面向对象的编程中, 抛弃了对 接口的依赖,而直接依赖实现类, 扩展比较难

访问者模式的应用场景:

  1. 一个对象结构包含很多类对象, 它们有不同的接口, 而你想对这些对象实施一些依赖于其具体类的操作, 也就是说用迭代器模式已经不能胜任的情景
  2. 需要对一个对象结构中的对象进行很多不同并且不相关的操作, 而你想避免让这些操作"污染"这些对象的类
  3. 业务规则要求遍历多个不同的对象. 这本身也是访问者模式的出发点, 访问者模式是对迭代器模式的扩充, 可以便利不同的对象, 然后执行不同的操作, 也就是针对访问的对象不同,执行不同的操作.
  4. 访问者模式还有一个 用途, 充当拦截器角色

访问者模式的扩展

1.统计功能

对不同的具体元素进行统计, 针对不同的具体元素针对性统计

比如统计员工工资, 经理和员工的工资情况不同, 使用访问者进行分别计算, 然后可以计算总额等

2.多个访问者

可以定义多个访问者, 每个访问者实现不同的功能

在IVistor 下再定义 接口继承 IVistor, 分别实现各自功能, 使用时传递不同的访问者有不同的表现


访问者模式是一种集中规整模式,特别使用于大规模重构的项目, 在这一个阶段需求已经非常清晰, 原系统的功能点也已经明确, 通过访问者模式可以很容易把一些功能进行梳理, 达到最终目的--功能集中化, 如一个统一的报表运算、UI展现等, 我们还可以与其它模式混编建立一套自己的过滤器或者拦截器

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

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

相关文章

23种设计模式之解释器模式

解释器模式的定义 定义: 给定一门语言,定义它的文法的一种表示, 并定义一个解释器, 该解释器使用该表示来解释语言中的句子. 其类图如下: 其中的角色说明: AbstractExpression 抽象解释器: 具体的解释任务由各个实现类完成TerminalExpression 终结符表达式: 实现与文法中的元…

23种设计模式之备忘录模式

备忘录模式的定义 定义: 在不破坏封装性的前提下, 捕获一个对象的内部状态, 并在该对象之外保存这个状态. 这样以后就可将该对象回复到原先保存的状态 通俗的说, 就是记录下类的当前状态, 当需要的时候恢复 类图如下: 其中各角色如下: Originator 发起人角色: 记录当前时刻…

23种设计模式之状态模式

状态模式的定义 定义: 当一个对象内在状态改变时允许其改变行为, 这个对象看起来像改变了其类 通俗的说, 就是一个事物有不同的状态,在不同状态下执行各个方法时有不同的表现, 将每个状态都封装成一个类, 然后通过上下文对象统一管理 其类图如下: 其中的三个角色如下: Stat…

二维码的纠错码原理及细节

参考文档: https://www.thonky.com/qr-code-tutorial/error-correction-coding 1. 消息多项式 消息多项式的系数组成:数字码字。如“hello world” ,利用二维码的编码原理,转换成十进制数字为“32, 91, 11, 120, 209, 114, 220, 77, 67, 64…

Android 二维码扫码功能实现(Zxing集成,避坑启示)

这两天想要实现一个能扫码的app,找了一下,发现zxing用的比较多,就在网上找了找怎么用zxing。我主要是按照宇宝守护神的博文“Android 二维码的扫码功能实现(一)”的步骤完成的,博文链接在此:htt…

23种设计模式之桥梁模式

桥梁模式的定义 定义: 将抽象和实现解耦, 使得两者可以独立的变化 通俗的说, 就是一个类调用另一个类中的方法, 需要一个桥梁, 通过聚合的关系调用 其类图如下: 其中角色说明如下: Abstraction 抽象化角色: 它的主要职责是定义出该角色的行为, 同时保存一个对实现化角色的引…

23种设计模式之享元模式

享元模式的定义 定义: 使用共享对象可有效的支持大量的细粒度的对象 通俗的说, 就是将类的通用属性抽出来,建立对象池,以达到限制对象数量的效果 上面定义中要求细粒度对象, 那么不可避免的使得对象数量多且性质相近, 我们将这些对象的信息分为两个部分: 内部状态和外部状态…

射频(RF)基本理论:定义、特性、调制、扩频

参考: INTRO TO SDR AND RF SIGNAL ANALYSIS 一文让你读懂调幅、调相、调频、 与 I/Q 调制?它们的区别详解 无线网络技术教程(第二版) 金光、江先亮编 数字调制系列:IQ调制基本理论 1. 什么是射频? …

设计模式之规格模式

规格模式 规格模式 使用了策略模式,组合模式. 只不过将模式具体化了 规格模式将 与或非 操作进行了封装, 实现了类似 SQL查询语句的操作. 类图如下: 其中的角色如下: ISpecification 抽象规格书: 对规格书的抽象定义CompositeSpecification 组合规格书: 抽象类, 对规格书进…

设计模式之雇工模式

雇工模式 雇工模式也叫仆人模式, 其意图为: 雇工模式是行为模式的一种, 它为一组类提供通用的功能,而不需要类实现这些功能,它是命令模式的一种扩展. 其类图如下: 其中角色如下: IServiced : 用于定义服务内容的接口Serviced1 : 具体的服务提供者Servant : 执行者,即雇工类,…

设计模式之对象池模式

对象池模式 对象池模式, 或者称为对象池服务, 其意图为: 通过循环使用对象, 减少资源在初始化和释放时的昂贵损耗(这里的"昂贵"可能是时间效益(如性能), 也可能是空间效益(如并行处理), 在大多情况下, 指性能) 简单的说, 在需要时,从池中提取,不用时,放回池中,等待…

WiFi的基本调制过程

参考:Parallel Inclusive Communication for Connecting Heterogeneous IoT Devices at the Edge 基本的WiFi调制分为以下三个步骤: 1. 将信号调制到正弦波上。 WiFi采用QAM(正交振幅调制),用I/Q信号表示的话&#…

设计模式之黑板模式

黑板模式的意图 黑板模式是观察者模式的一个扩展,知名度并不高,但使用的范围却非常广. 其意图为: 允许消息的读写同时进行, 广泛的交互消息. 简单的说, 黑板模式允许多个消息读写者同时存在, 消息的生产者和消费者完全分开. 这就像一个黑板, 任何一个老师(消息的生产者)都可以…

蓝牙调制

参考:Parallel Inclusive Communication for Connecting Heterogeneous IoT Devices at the Edge 《从创意到原型:物联网应用快速开发》 董玮,高艺编著 详解蓝牙标准中的GFSK调制:https://blog.csdn.net/lovehua365/article/detai…

设计模式之空对象模式

空对象模式 空对象模式是通过实现一个默认的无意义对象来避免null值出现, 简单地说,就是为了避免在程序中出现null值判断而诞生的一种常用设计方法. 举个简单的例子, 一个听动物叫声的模拟程序: 动物代码: 听叫声的人: 现在我们想, 能不能把 animal 的空值判断去掉呢?我们增…

UML类图基础说明

UML类图主要由类和关系组成. 类: 什么具有相同特征的对象的抽象, 具体我也记不住, 反正有官方定义 关系: 指各个类之间的关系 类图 类就使用一个方框来表示, 把方框分成几层, 来表示不同的信息,如下图所示: 当然, 类图也不一定每一次都长这样, 比如你只分析各个类之间的关系…

J-flash 烧写cc2538教程

1. 打开J-falsh,所示如下界面 2. 配置相关参数。 菜单栏 Options → Project settings。按照如下框图选择。 3. 打开要烧写的文件。File → Open data file,选择要烧写的文件(一般为hex或bin文件) 4. 连接板子。Target → Connec…

跳表

概述 线性表中的链表是我们都很熟悉的结构了, 链表的增删优于数组, 但是不支持随机访问, 链表在查找时, 只能从头节点向后遍历, 那么针对链表, 能不能解决其访问效率的问题呢? 跳表来了, 顾名思义, 跳表就是可以跳跃的表, 我简单画了张图: 在原来链表的基础上, 建立一个新的…

论文写作——用excel和ppt做好看的论文图

论文写作——用excel和ppt做好看的论文图Excel 作图PPT保存前言:用matlab或者python作图,门槛较高,熟悉比较难。用excel和ppt就比较容易上手了。最近的论文全用ppt和excel作图,看着也不赖,在此记录一下一般的方法。 co…

Arduino Uno + Lora shield rf95_server 提示错误“Init failed!”

错误描述 在使用原始的Arduino提供的示例rf95_server和rf95_client的时候,烧了rf96_server的板子会出现“init failed!”的错误,如下。 问题解决 经过排查,初始化失败由Led相干代码引起,因此将它们注释掉就好了&…