学习C#设计模式(十六)访问者模式

  • Post author:
  • Post category:其他




访问者者模式

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Visitor
{
    //抽象果农类
    public abstract class Orchardist
    {

        public abstract void VisitApple(Apple apple);        //果农种植苹果树抽象方法
        public abstract void VisitOrange(Orange orange);     //果农种植橘子树抽象方法
    }
    //负责松土的果农
    public class LoosenOrchardist : Orchardist
    {
        public override void VisitApple(Apple apple)         //果农为苹果树松土
        {
            apple.PlantApple();
            Console.WriteLine("果农为苹果树松土!");
        }
        public override void VisitOrange(Orange orange)      //果农为橘子树松土
        {
            orange.PlantOrange();
            Console.WriteLine("果农为橘子树松土");
        }
    }
    //负责浇水的果农
    public class ManureOrchardist : Orchardist
    {
        public override void VisitApple(Apple myClassA)      //果农为苹果树浇水
        {
            myClassA.PlantApple();
            Console.WriteLine("果农为苹果树浇水");
        }
        public override void VisitOrange(Orange myClassB)    //果农为橘子树浇水
        {
            myClassB.PlantOrange();
            Console.WriteLine("果农为橘子树浇水");
        }
    }
    //抽象水果类
    public abstract class Fruit
    {
        public abstract void Accept(Orchardist orchardist);
    }
    //抽象苹果类
    public class Apple : Fruit
    {
        public override void Accept(Orchardist orchardist) //果农种植苹果树
        {
            orchardist.VisitApple(this);
        }
        public void PlantApple()                         //种植苹果树
        {
            Console.WriteLine("培育苹果树!");
        }
    }
    //抽象橘子类
    public class Orange : Fruit
    {
        public override void Accept(Orchardist orchardist)
        {
            orchardist.VisitOrange(this);
        }
        public void PlantOrange()                            //种植橘子树
        {

            Console.WriteLine("培育橘子树!");
        }
    }
    public class Orchard
    {
        List<Fruit> fruits = new List<Fruit>();          //果园种植的果树
        public void Attach(Fruit fruit)                  //添加果树
        {
            fruits.Add(fruit);
        }
        public void Detach(Fruit fruit)                  //移除果树
        {
            fruits.Remove(fruit);
        }
        public void Accept(Orchardist orchardist)        //果树接受果农的培育
        {
            foreach (Fruit fruit in fruits)
            {
                fruit.Accept(orchardist);
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Orchard orchard = new Orchard();                    //创建果园实例
            orchard.Attach(new Apple());                        //向果园中添加苹果树
            orchard.Attach(new Orange());                       //向果园中添加橘子树
            orchard.Accept(new LoosenOrchardist());             //松土果农为果树松土
            orchard.Accept(new ManureOrchardist());             //浇水果农为果树浇水
            Console.ReadKey();
        }
    }
}


代码解析:


本实例代码实现了访问者模式,首先创建了抽象果农类Orchardist,该类实现了两个接口方法VisitApple和VisitOrange,实现对苹果树Apple和橘子树Orange的访问。然后创建了抽象水果类Fruit及其派生类Apple和Orange。最后创建了果园类Orchard,该类保存了Fruit对象的集合,通过Attach方法和Detach方法来添加和删除果树对象,通过Accept方法实例对果园中所有果树的Accept方法的调用,从而实现果农对所有果树的访问。

实例代码中,Apple 类的 Accept 方法传入了 Orchardist 对象,并将自身作为参数调用了Orchardist对象的VisitApple方法,而VisitApple方法又反过来调用了Apple类的PlantApple方法。这一过程实现了调用方式的选择,Apple类选择了VisitApple方法,同样,Orange类选择了PlantOrange方法,整个过程对数据结构是透明的。这样就实现了访问者模式。


说明:


访问者模式的主要功能是将数据结构与对数据结构中元素方法的调用进行分离,当对数据结构中元素的调用方式发生改变时,不需要修改数据结构本身。其中数据结构中的元素类型可能不同,根据元素的类型,元素会自动判断访问者所调用的方法。



版权声明:本文为wangxuewen990129原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。