当前位置: 首页 > article >正文

C# 23种设计模式(4)访问者模式(Visitor Pattern)

一、访问者模式介绍

访问者模式(Visitor Pattern)是一种行为设计模式,它允许你以一种新的方式来增加作用于一组对象的操作,而无需修改这些对象类的代码。访问者模式将数据操作与数据结构分离,适用于数据结构相对稳定但操作易于变化的情况。结构对象是使用访问者模式必备条件,而且这个结构对象必须存在遍历自身各个对象的方法。

优点:

  1. 扩展性好:在不修改对象结构中的元素的情况下,为对象结构中的元素添加新的功能。
  2. 复用性好:通过访问者来定义整个对象结构通用的功能,从而提高复用程度。
  3. 分离无关行为:通过访问者来分离无关的行为,把相关的行为封装在一起,构成一个访问者,这样每一个访问者的功能都比较单一。

访问者模式通常包含以下几个角色:

1、抽象访问者(Visitor)

为该对象结构中具体元素角色声明一个访问操作接口。
该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色,
这样访问者就可以通过该元素角色的特定接口直接访问它:

2、具体访问者(Concrete Visitor)

实现Visitor声明的接口:

3、抽象元素(Element)

定义一个接受访问操作,它以一个访问者(Visitor)作为参数:

4、具体元素(Concrete Element)

实现了抽象元素所定义的接受操作接口:

5、对象结构(Object Structure)

可以提供一个高层接口以允许访问者访问它的元素。

二、工厂模式代码实现

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

场景代码实现如下:


    //抽象元素
    public interface IAnimal
    {
        void Accept(IPerson person);
    }
    //抽象访问者
    public interface IPerson
    {
        //优点定义对象结构的通用功能
        void Feed(Cat animal);
        void Feed(Dog animal);

        //缺点:一是依赖了具体类,违反了依赖倒置原则:二是每增加一个元素(宠物),这里就要增加一个方法,违反了开闭原则
    }
    //具体元素角色:猫
    public class Cat : IAnimal
    {
        public void Accept(IPerson person)
        {
            person.Feed(this);
            Console.WriteLine("猫:好吃");
        }
    }
    //具体元素角色:狗
    public class Dog : IAnimal
    {
        public void Accept(IPerson person)
        {
            person.Feed(this);
            Console.WriteLine("狗:好吃");
        }
    }
    //具体访问者:主人
    public class Master : IPerson
    {
        public void Feed(Cat animal)
        {
            Console.WriteLine("主人喂猫");
        }

        public void Feed(Dog animal)
        {
            Console.WriteLine("主人喂狗");
        }
    }
    //具体访问者:朋友
    public class Friend : IPerson
    {
        public void Feed(Cat animal)
        {
            Console.WriteLine("朋友喂猫");
        }

        public void Feed(Dog animal)
        {
            Console.WriteLine("朋友喂狗");
        }
    }
    //结构对象角色
    public class Home
    {
        private readonly List<IAnimal> animals = new List<IAnimal>();

        public void Add(IAnimal animal)
        {
            animals.Add(animal);
        }

        public void Start(IPerson person)
        {
            foreach (var animal in animals)
            {
                animal.Accept(person);
            }
        }
    }

    public class Client2
    {
        public static void Start()
        {
            Home home = new Home();
            home.Add(new Dog());
            home.Add(new Cat());

            Master master = new Master();
            home.Start(master);
            //输出:
            //主人喂狗
            //狗:好吃
            //主人喂猫
            //猫:好吃


        }
    }


http://www.kler.cn/a/441444.html

相关文章:

  • vim在命令模式下的查找功能
  • 什么是稀疏 MoE?Doubao-1.5-pro 如何以少胜多?
  • 基于Springboot + vue实现的美发门店管理系统
  • AIGC视频生成国产之光:ByteDance的PixelDance模型
  • 微信小程序使用上拉加载onReachBottom。页面拖不动。一直无法触发上拉的事件。
  • wordpress付费查看隐藏内容插件的开发演示和记录
  • @pytest.fixture() 跟 @pytest.fixture有区别吗?
  • 机器学习实战31-基于机器学习算法对某年福州市各初中重点高中录取率进行数学分析,评估性价比较高的学校。
  • 探索 PIE 在 ESP32-P4 上的应用
  • 找出一个数组中出现次数最多的那个元素。:哈希表:JAVA
  • SQL, 将分段数不确定的字符串拆分成多列
  • Android之RecyclerView显示数据列表和网格
  • 2024-12-16 装有Ubuntu系统的移动硬盘使用windows系统对其进行格式化
  • SpringDataJpa-字段加解密存储
  • webpack打包流程及原理
  • LeetCode 283.移动零(超简单讲解)
  • 鸿蒙权限请求工具类
  • 力扣-图论-15【算法学习day.65】
  • 【PyTorch】实现在训练过程中自定义动态调整学习率
  • 测试工程师八股文04|计算机网络 和 其他
  • 【日常笔记】基本数据类型浅析 -int类型能存储哪些传感器数据
  • 减少 Flutter 应用体积的常用方法
  • 在线PDF合并工具 - 快速、免费、安全的文档处理解决方案 | Online PDF Merger Tool
  • 力扣--LCR 164.破解闯关密码
  • K8s 中Istio 的使用示例
  • ThinkPHP 5.1 的模板布局功能