23种设计模式-22-访问者模式

对象抽象类(被访问者):

/// <summary>
    /// 老师抽象类
    /// </summary>
    public abstract class Teacher
    {
        public Teacher(string name, List<Student> students)
        {
            this.Name = name;
            this.Students = students;
        }

        /// <summary>
        /// 老师名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 每个老师都有自己的学生
        /// </summary>
        public List<Student> Students { get; set; }

        /// <summary>
        /// 每个老师可以接受访问者的访问
        /// </summary>
        /// <param name="visitor"></param>
        public abstract void Accept(IVisit visitor);

        /// <summary>
        /// 老师布置的家庭作业
        /// </summary>
        public string Homework { get; set; }

        /// <summary>
        /// 每个老师都可以布置作业
        /// </summary>
        /// <param name="homeworkContent"></param>
        public abstract void AssignHomeword(string homeworkContent);
    }

访问者接口:

/// <summary>
    /// 访问者接口,用于访问老师
    /// </summary>
    public interface IVisit
    {
        void Visit(Teacher teacher);
    }

老师实现类:语文老师

/// <summary>
    /// 语文老师
    /// </summary>
    public class ChineseTeacher : Teacher
    {
        public ChineseTeacher(string name, List<Student> students) : base(name, students)
        {

        }

        public override void Accept(IVisit visitor)
        {
            visitor.Visit(this);
        }

        public override void AssignHomeword(string homeworkContent)
        {
            this.Homework = homeworkContent;
            Console.WriteLine("{0}给他的学生布置的作业是:{1},{0}有{2}个学生,分别叫:{3}", this.Name, homeworkContent, this.Students.Count,
                string.Join(",", this.Students.Select(r => string.Format("{0}({1})", r.Name, r.Sex))));
        }
    }

访问者实现类:

/// <summary>
    /// 访问者:通知学生父母的访问者
    /// </summary>
    public class NotifyStudentParentVisitor : IVisit
    {
        public void Visit(Teacher teacher)
        {
            teacher.Students.ForEach(r => Console.WriteLine("{0}通知{1}{2}记得晚上抽空检查{1}{3}。", teacher.Name, r.Name,
                CoreService.Ran.Next(10) % 2 == 0 ? "爸爸" : "妈妈", teacher.Homework));
        }
    }

测试:

class Program
    {
        /// <summary>
        /// 访问者模式:
        /// 访问者模式解决的问题是:
        /// 将一个对象的数据结构保持不变,针对不同的业务,该对象可以接受不同访问者的调用,而展示出不同的形态,执行不同的业务
        /// 而访问者访问了这个对象之后,也可以反过来执行该对象的某些操作
        /// 这样将数据和业务分离开,降低了耦合性,也增强了系统的扩展性
        ///
        /// 访问者模式更多的运用于数据结构相对稳定的系统
        /// 
        /// 如果需要修改数据结构(如增添字段),那就必须要修改对象了
        /// 但是如果只是修改业务操作,那么我们可以不用修改对象,而编写一个新的访问者去访问这个对象,即可完成我们新的业务逻辑操作
        ///
        /// 此文中的例子:
        /// 学校每天放学的时候会给学生布置作业,学生回家完成,这是一个固定的业务,老师给学生布置作业
        /// 突然有一天,今天老师给学生布置的作业是回家背书,但是背会了之后,希望可以背诵给家长听,然后家长签字
        /// 此时我就需要在给学生布置完作业之后,也需要给每个学生的家长发送一条通知,告诉他们晚上回家抽空检查孩子背书
        ///
        /// 按照正常的业务逻辑,我们需要修改老师布置作业的业务逻辑,
        /// 但是使用访问者模式,我们只需要新添加一个访问者,去访问这个业务,然后将自己的新业务加进去就可以啦
        ///
        /// ok,let's coding
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            //初始化学生集合
            var studentNames = "张三,李四,王武,赵柳,小明,小红,小李,小王";
            var students = studentNames.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)
                .Select(r => new Student(r)).ToList();
            //初始化老师对象
            var chineseTeacher = new ChineseTeacher("语文老师", students);
            //老师给学生布置作业
            chineseTeacher.AssignHomeword("练字");
            Console.WriteLine("----------------------------------------------------");
            //现在老师给学生布置一个新的作业:回家背书,还需要告诉学生的家长:晚上抽空检查孩子背书
            chineseTeacher.AssignHomeword("背诵古诗《静夜诗》");

            Console.WriteLine("----------------------------------------------------");
            //需要通知学生家长,此时就需要使用访问者模式了

            //初始化访问者
            var visitor = new NotifyStudentParentVisitor();
            //通知家长
            visitor.Visit(chineseTeacher);

            Console.ReadKey();
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值