14_访问者模式

访问者模式是一种行为型设计模式,它允许在不改变被访问对象结构的前提下,定义对这些对象的新操作。访问者模式将操作和对象结构分离,使得可以在不修改对象结构的情况下添加新的操作。

访问者模式有四个主要角色:

  1. 抽象访问者(Visitor):定义了访问者可以访问的对象的接口,包含了一系列的访问方法,每个方法对应一种对象的访问操作。

  2. 具体访问者(Concrete Visitor):实现了抽象访问者接口,对具体的对象结构进行访问操作。

  3. 抽象元素(Element):定义了对象结构的公共接口,包含了一个接受访问者的方法。

  4. 具体元素(Concrete Element):实现了抽象元素接口,提供了具体的对象结构。

访问者模式的工作原理如下:

  1. 抽象访问者定义了一系列的访问方法,每个方法对应一种对象的访问操作。

  2. 具体访问者实现了抽象访问者接口,并实现了对具体对象的访问操作。

  3. 抽象元素定义了对象结构的公共接口,并包含了一个接受访问者的方法。

  4. 具体元素实现了抽象元素接口,提供了具体的对象结构,并实现了接受访问者的方法。

  5. 客户端通过调用访问者的方法,对对象进行访问操作。

访问者模式的优点包括:

  1. 可以对对象结构进行新的操作,而无需修改对象结构本身。

  2. 可以将相关操作封装到一个访问者中,提高了代码的可维护性和扩展性。

  3. 可以将对象结构和操作进行解耦,使得代码更加清晰。

访问者模式适用于以下场景:

  1. 当需要对一个复杂对象结构进行一系列不相关或独立的操作时,可以使用访问者模式。

  2. 当对象结构的类层次比较稳定,但经常需要定义新的操作时,可以使用访问者模式。

总结而言,访问者模式通过将操作和对象结构分离,可以在不修改对象结构的情况下定义新的操作。它提供了一种灵活的方式来对复杂对象结构进行访问和操作,并提高了代码的可维护性和扩展性。

 

案例:

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

 

Visitor

 public interface IPerson
    {
        //优点 定义对象结构的通用功能
        void Feed(Cat animal);// 给谁投喂?
        void Feed(Dog animal);// 给谁投喂?
        void Feed(Fish animal);// 给谁投喂?

        //缺点:一是依赖了具体类 ,违反了依赖倒置原则; 二是每增加一个元素(宠物),这里就要增加一个方法,违反了开闭原则
    }

 

Element

public interface IAnimal
    {
        void Accept(IPerson person);
    }

 

Concrete Element

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 Fish : IAnimal
    {
        public void Accept(IPerson person)
        {
            person.Feed(this);
            Console.WriteLine("咕噜噜.....");

        }
    }

 

Concrete Visitor

public class Master : IPerson
    {

        public void Feed(Cat animal)
        {
            Console.WriteLine("主人自已喂猫");
        }

        public void Feed(Dog animal)
        {
            Console.WriteLine("主人自已喂狗");
        }

        public void Feed(Fish animal)
        {
            Console.WriteLine("主人自已喂鱼");
        }
    }
public class Friend : IPerson
    {
        public void Feed(Cat animal)
        {
            Console.WriteLine("好朋友帮主人喂猫");
        }

        public void Feed(Dog animal)
        {
            Console.WriteLine("好朋友帮主人喂狗");
        }

        public void Feed(Fish animal)
        {
            Console.WriteLine("好朋友帮主人喂鱼");
        }
    }

 

Object Structure

/// <summary>
    /// 结构对象角色
    /// </summary>
    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);
            }
        }
    }

 

调用

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

            Master master=new Master();
            home.Start(master);

            home.Add(new Fish());
            Friend friend=new Friend();
            home.Start(friend);

        }

    }
static void Main(string[] args)
        {
            new Client().Start();

            Console.ReadKey();
        }

 

posted @ 2024-03-12 10:45  野码  阅读(2)  评论(0编辑  收藏  举报