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

news/2024/5/19 22:25:46 标签: 设计模式, 访问者模式, c#, .netcore, 行为型模式

🚀简介

封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。
访问者模式包含以下主要角色 :
  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.niftyadmin.cn/n/5092046.html

相关文章

CSS之实现线性渐变背景

1. background: linear-gradient() background: linear-gradient是CSS中用于创建线性渐变背景的属性&#xff0c;这个属性允许你定义一个在元素的背景中进行渐变的效果&#xff0c;可以从一个颜色过渡到另一个颜色。 基本语法 background: linear-gradient(direction, color-…

基于Springboot宠物医院管理系统

项目环境&#xff1a; mysql5.7 jdk1.8

ubuntu20 安装 cmake 3.27

1. 下载cmake3.27 建议从cmake官网下载安装&#xff0c;虽然比较慢&#xff0c;但从清华镜像里下载的cmake文件不全。 我下载的是&#xff1a;cmake-3.27.7.tar.gz 博客 ubuntu安装cmake的三种方法&#xff08;超方便&#xff01;&#xff09;-CSDN博客 里面提供了三种方法&am…

P34~36第八章相量法

8.1复数 复数可表示平面矢量、也可表示正弦量。特别是: 当复数表示正弦量的时候&#xff0c;此时复数称为相量。 8.2复数运算 复数除法也可看做乘法&#xff0c;乘法的几何意义是旋转&#xff08;辐角相加&#xff09;( e^x e^y e^xy)&#xff0c;同时伸缩&#xff08;模变…

【opencv】windows10下opencv4.8.0-cuda Python版本源码编译教程

【opencv】windows10下opencv4.8.0-cuda Python版本源码编译教程 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【opencv】windows10下opencv4.8.0-cuda Python版本源码编译教程前言准备工具anaconda/cuda/cudnnanaconda创建环境(选做)安装原…

树莓派:64位 RPI OS(Bookworm) 更换国内源

几天前新的RPI OS发布了。官方的发版说明里明确注明已经基于Debian Bookworm了。总的来说切到国内源&#xff08;清华&#xff09;跟Bullseye差不多&#xff0c;细节上只有一丢丢不同&#xff08;non-free变成了non-free-firmware&#xff09;。 老规矩&#xff0c;仍然是修改…

零的0次方 , 零的2次方 3次方 n次方各是多少

零的0次方 , 零的2次方 3次方 n次方各是多少 在标准数学中&#xff0c;零的任何正整数次方都等于0&#xff0c;即&#xff1a; 0^0 10^2 00^3 00^n 0&#xff0c;其中 n 是任何正整数 这是因为零的任何正整数次方都等于零&#xff0c;这是数学中的基本规则。这与零的零次…

线性判别分析的多分类情况

线性判别分析的多分类情况 情况一 若存在超平面 d i ( x ) w i x d_i(x)w_ix di​(x)wi​x可以将属于 w i w_i wi​与不属于 w i w_i wi​范围的划开 d i ( x ) w i T x { > 0 , i f x ∈ w i < 0 , i f x ∉ w i (1) d_i(x)w_i^Tx \begin{cases}> 0 ,\quad if …