c#设计模式-行为型模式 之 访问者模式

news2024/11/28 14:53:23

🚀简介

封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。
访问者模式包含以下主要角色 :
  1. 抽象访问者(Visitor)角色:定义了对每一个元素 Element访问的行为,它的参数就是可以访问的元素,它的方法个数理论上来讲与元素类个数(Element的实现类个数)是一样的,从这点不难看出,访问者模式要求元素类的个数不能改变。
  2. 具体访问者(ConcreteVisitor)角色:给出对每一个元素类访问时所产生的具体行为。
  3. 抽象元素(Element)角色:定义了一个接受访问者的方法( accept ),其意义是指,每一个元素都要可以被访问者访问。
  4. 具体元素(ConcreteElement)角色: 提供接受访问方法的具体实现,而这个具体的实现,通常情况下是使用访问者提供的访问该元素类的方法。
  5. 对象结构(Object Structure)角色:定义当中所提到的对象结构,对象结构是一个抽象表述,具体点可以理解为一个具有容器性质或者复合对象特性的类,它会含有一组元素Element ),并且可以迭代这些元素,供访问者访问。

🚀案例

我们就以养宠物为例,宠物分别有狗和猫,要给宠物喂食的话,主人可以喂,其他人也可以喂食。
  • 访问者角色:给宠物喂食的人
  • 具体访问者角色:主人、其他人
  • 抽象元素角色:动物抽象类
  • 具体元素角色:宠物狗、宠物猫
  • 结构对象角色:主人家

🐤创建抽象访问者接口

public interface Person {
    void Feed(Cat cat);
    void Feed(Dog dog);
}
🐤创建不同的具体访问者角色(主人和其他人),都需要实现 Person 接口
//主人
public class Owner : Person
{
    public void Feed(Cat cat)
    {
        Console.WriteLine("主人喂食猫");
    }

    public void Feed(Dog dog)
    {
        Console.WriteLine("主人喂食狗");
    }
}

//其他人
public class Someone : Person
{
    public void Feed(Cat cat)
    {
        Console.WriteLine("其他人喂食猫");
    }


    public void Feed(Dog dog)
    {
        Console.WriteLine("其他人喂食狗");
    }
}
🐤定义抽象节点 -- 宠物
public interface IAnimal {
    void Accept(Person person);
}

🐤定义实现 Animal 接口的 具体节点(元素)

public class Dog:IAnimal
{
    public void Accept(Person person)
    {
        person.Feed(this);
        Console.WriteLine("好吃!汪汪汪");
    }
}

public class Cat:IAnimal
{
    public void Accept(Person person)
    {
        person.Feed(this);
        Console.WriteLine("好吃!喵喵喵");
    }
}
🐤定义对象结构,此案例中就是主人的家
public class Home
{
    private readonly List<IAnimal> _nodeList = new List<IAnimal>();

    public void Action(Person person)
    {
        foreach (var node in _nodeList)
        {
            node.Accept(person);
        }
    }

    //添加操作
    public void Add(IAnimal animal)
    {
        _nodeList.Add(animal);
    }
}

🐳测试类

class MyClass
{
    public static void Main(string[] args)
    {
        Home home = new Home();
        home.Add(new Dog());
        home.Add(new Cat());
        
        Owner owner = new Owner();
        home.Action(owner);
        
        Someone someone = new Someone();
        home.Action(someone);
    }
}

👻运行结果!

🚀优缺点

优点:
  • 扩展性好
    • 在不修改对象结构中的元素的情况下,为对象结构中的元素添加新的功能。
  • 复用性好
    • 通过访问者来定义整个对象结构通用的功能,从而提高复用程度。
  • 分离无关行为
    • 通过访问者来分离无关的行为,把相关的行为封装在一起,构成一个访问者,这样每一个访问者的功能都比较单一。
缺点:
  • 对象结构变化很困难
    • 在访问者模式中,每增加一个新的元素类,都要在每一个具体访问者类中增加相应的具体操作,这违背了开闭原则
  • 违反了依赖倒置原则
    • 访问者模式依赖了具体类,而没有依赖抽象类。
使用场景:
  1. 对象结构相对稳定,但其操作算法经常变化的程序。
  2. 对象结构中的对象需要提供多种不同且不相关的操作,而且要避免让这些操作的变化影响对象的结构。

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

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

相关文章

英语——语法——从句——句型和句子成分——笔记

老师导言&#xff1a;易于理解。 三种句型&#xff1a;1、主系表&#xff1b;2.主谓*&#xff1b;3.there be 句型&#xff1a;句子构成的形式。句子用于相互沟通&#xff0c;需要表达自己意思&#xff0c;句子中就存在一个主语&#xff0c;一般对主语&#xff08;主要描述对象…

4.Mask R-CNN/YOLOV8/RTMDET三种实例分割方法推理逻辑对比

文章目录 Mask R-CNN/YOLOV8/RTMDET三种实例分割方法推理逻辑对比Mask R-CNNYOLOV5/8实例分割方法RTMDet中的实例分割 欢迎访问个人网络日志&#x1f339;&#x1f339;知行空间&#x1f339;&#x1f339; Mask R-CNN/YOLOV8/RTMDET三种实例分割方法推理逻辑对比 实例分割是同…

CLIP模型原理与代码实现详解

文章目录 前言一、CLIP模型原理1.背景介绍2.对比训练方式3.prompt推理方式4.图像与文本编码结构5.特征CLS token结构vit划分patch原理cls token原理 二、CLIP环境安装1.官方环境安装2.CLIP环境安装3.CLIP运行结果 三.CLIP的Transformer结构代码解读四、CLIP模型主函数代码解读五…

相似性搜索:第 4 部分--分层可导航小世界 (HNSW)

SImilarity 搜索是一个问题&#xff0c;给定一个查询的目标是在所有数据库文档中找到与其最相似的文档。 一、介绍 在数据科学中&#xff0c;相似性搜索经常出现在NLP领域&#xff0c;搜索引擎或推荐系统中&#xff0c;其中需要检索最相关的文档或项目以进行查询。在大量数据中…

从0开始学go第八天

gin获取URL路径参数 package main//获取path&#xff08;URL&#xff09;参数 import ("net/http""github.com/gin-gonic/gin" )func main() {r : gin.Default()r.GET("/:name/:age", func(c *gin.Context) {//获取路径参数name : c.Param(&quo…

15 | JPA 对 Web MVC 开发者做了哪些支持

我们使用 Spring Data JPA 的时候&#xff0c;一般都会用到 Spring MVC&#xff0c;Spring Data 对 Spring MVC 做了很好的支持&#xff0c;体现在以下几个方面&#xff1a; 支持在 Controller 层直接返回实体&#xff0c;而不使用其显式的调用方法&#xff1b;对 MVC 层支持标…

如何通过Photoshop将视频转换成GIF图片

一、应用场景 1、将视频转有趣动图发朋友圈 2、写CSDN无法上传视频&#xff0c;而可以用GID动图替代 3、其他 二、实现步骤 1、打开Photoshop APP 2、点击文件——导入——视频帧到图层 3、选择视频文件 4、配置视频信息&#xff0c;按照图片提示配置完毕之后&#xff0c;…

gma 2.0.2 (2023.10.15) 更新日志

安装 gma 2.0.2 pip install gma2.0.2新增 0.1、矢量提取&#xff08;重要更新&#xff09; &#xff08;见简单示例&#xff09;   现在&#xff0c;你可以像 numpy 或 pandas 一样直接对 Layer 进行切片提取。 0.2、修改属性表&#xff08;重要更新&#xff09; &#xff…

数电第一次实验

四选一&#xff0c;信号选择器 三位4选1多路选择器 要求输入信号有4个&#xff0c;且每个信号宽3位 如果是直接根据选择信号选 选择的是信号&#xff0c;选择的是编号&#xff0c;与信号具体是什么内容无关&#xff0c;信号的内容与其是否被选择无关&#xff0c;信号的编号…

E034-服务漏洞利用及加固-利用CVE-2016-5195漏洞实现Linux系统本地提权

实验等级: 中级 任务场景: 【任务场景】 小王接到磐石公司的邀请&#xff0c;对该公司内部网络进行渗透测试&#xff0c;经过对局域网被操作系统进行全面的维护中&#xff0c;发现了一台内核版本为4.2.0-27的Linux服务器&#xff0c;低权限用户利用该漏洞技术可以在全版本L…

【笔记整理】软考-软件设计师

一、计算机系统 计算机基本单位 单位名称简称换算位bitb字节byteB1B8b千字节KB1KB1024B兆字节MB1MB1024KB吉字节GB1GB1024MB太字节TB1TB1024GB 带宽单位Mbps的b是指Bit&#xff08;位&#xff09; 速度单位MB/s的B是指Byte&#xff08;字节&#xff09; 1MB/s&#xff1d;8M…

Android 10.0 禁止弹出系统simlock的锁卡弹窗功能实现

1.前言 在10.0的系统开发中,在一款产品中,需要实现simlock锁卡功能,在系统实现锁卡功能以后,在开机的过程中,或者是在插入sim卡 后,当系统检测到是禁用的sim卡后,就会弹出simlock锁卡弹窗,要求输入puk 解锁密码,功能需求禁用这个弹窗,所以就需要看是 哪里弹的,禁用…

04-React脚手架

04-React脚手架 1. react脚手架入门 1).脚手架的介绍 xxx脚手架: 用来帮助程序员快速创建一个基于xxx库的模板项目 包含了所有需要的配置&#xff08;语法检查、jsx编译、devServer…&#xff09;下载好了所有相关的依赖可以直接运行一个简单效果 react提供了一个用于创建rea…

R/d2及S/C4估计总体标准差,比较其CPK及规格限概率的差异

R/d2 和 S/C4 是用于估计总体标准差的无偏估计方法&#xff0c;通常用于控制图中。这些估计方法的主要目的是通过样本数据来估计总体标准差&#xff0c;以便监测过程的稳定性和变异性&#xff0c;而不需要收集整个总体的数据。 具体来说&#xff1a; R图中的 R/d2 和 S图中的…

【JAVA】有关包的概念

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️初识JAVA】 前言 Java包是用于组织和管理Java类的方式。它们提供了一种命名空间&#xff0c;以避免名称冲突&#xff0c;并使程序的组织更加有效和可维护。今天我们接着来学习有关包的概念。 包 …

faster lio 回环 加入GTSAM优化的记录

首先感谢这位博主的文章&#xff1a;https://blog.csdn.net/weixin_41281151/article/details/125371285&#xff0c;其中部分代码参考于改博主中的github&#xff1a; https://github.com/kahowang/FAST_LIO_SAM 不同的是&#xff0c;我使用的是faster lio进行更改&#xff0c…

vscode键盘输入不进去

二话不说&#xff0c;直接把输入切换到终端输出即可&#xff01; 打开设置&#xff0c;搜索terminal&#xff0c;切换到run in terminal 即可&#xff01;

C语言-指针相关使用

指针是 C语言的重要组成部分&#xff0c;是 C语言的核心、精髓。 在 C语言中&#xff0c;指针使用得当&#xff0c;能显著提高某些程序的效率&#xff0c;使用不当&#xff0c;则很容易造成系统错误、 一、指针使用 编译系统为每个变量都分配了一个能满足其类型大小的内存单…

vqvae简单实战,利用vqvae来提升模型向量表达

最近CV领域各种大模型在图像生成领域大发异彩&#xff0c;比如这两年大火的dalle系列模型。在这些模型中用到一个基础模型vqvae&#xff0c;今天我们写个简单实现来了解一下vqvae的工作原理。vqvae原始论文连接https://arxiv.org/pdf/1711.00937.pdf 1&#xff0c;代码 首先我们…

机器学习——奇异值分解二(特征分解+SVD纯理解)

矩阵的特征分解 特征值和特征向量的定义 抄来的&#xff1a;奇异值分解 困惑1&#xff1a;特征值和特征向量&#xff0c;和原矩阵是怎样的关系&#xff0c;需要一个栗子进行更具象的认识 困惑2&#xff1a;为什么多个特征向量组合成的矩阵&#xff0c;可以构成矩阵A的特征分解…