• 访问者模式 -- 大话设计模式


    在今天,读书有时是件“麻烦”事。它需要你付出时间,付出精力,还要付出一份心境。--仅以《大话设计模式》来祭奠那逝去的……

    访问者模式:表示作用于某对象结构中的各元素操作。它使你可以在不改变各元素类的前提下作用于这些元素的新操作

    大多时候你并不需要访问者模式,但当你一旦需要访问者模式时,那就真的需要它了

    1.男人和女人的区别

      男人成功时,背后往往有一个伟大的女人;女人成功时,背后往往有一个不成功的男人;

      将成功、失败和结婚等抽象成状态类,再定义一个人类抽象类(该抽象类,并非真正的人类抽象类,并不包含人类所具有的属性和行为)

        /// <summary>
        /// 人类抽象类(并非真正的人类抽象类,并不包含人类所具有的属性和行为)
        /// </summary>
        public abstract class PersonElement
        {
            /// <summary>
            /// 定义一个accept操作,它以一个访问者为参数
            /// </summary>
            public abstract void Accept(Action visitor);
        }
    
        /// <summary>
        /// 状态抽象类(将男人或者女人的结论、反应抽象为状态)
        /// </summary>
        public abstract class Action
        {
            public abstract void GetManConclusion(ManElement elementA);
    
            public abstract void GetWomanConclusion(WomanElement elementB);
        }
    

       定义成功、失败和结婚等状态类

        /// <summary>
        /// 成功(PersonElement成功的Action)
        /// </summary>
        public class Success : Action
        {
            public override void GetManConclusion(ManElement elementA)
            {
                Console.WriteLine("男人成功时,背后多半有一个伟大的女人");
            }
    
            public override void GetWomanConclusion(WomanElement elementB)
            {
                Console.WriteLine("女人成功时,背后多半有一个不成功的男人");
            }
        }
    

       定义“男人”和“女人”,当他们接受Actoin所访问时,做出相应处理(这里包含一个双分派技术,首先客户端程序中将具体的Action作为参数传给了“男人”完成了一次分派,然后“男人”调用参数所拥有的获取男人反应行为,将自己this作为参数传递了进去,完成第二次分派)

        /// <summary>
        /// 男人类
        /// </summary>
        public class ManElement : PersonElement
        {
            public override void Accept(Action visitor)
            {
                visitor.GetManConclusion(this);
            }
        }
    
        /// <summary>
        /// 女人类
        /// </summary>
        public class WomanElement : PersonElement
        {
            public override void Accept(Action visitor)
            {
                visitor.GetWomanConclusion(this);
            }
        }
    

       由于总是需要“男人”和”女人“在不同的状态对比,因此定义该类进行遍历,得到不同的反应(客户端调用时,可以使用也可以不使用)

        /// <summary>
        /// 对象结构类(由于总是需要“男人”和”女人“在不同的状态对比,因此定义该类进行遍历,得到不同的反应)
        /// </summary>
        public class ObjectStructure
        {
            private IList<PersonElement> elements = new List<PersonElement>();
    
            /// <summary>
            /// 添加元素
            /// </summary>
            public void Attach(PersonElement element)
            {
                elements.Add(element);
            }
    
            /// <summary>
            /// 移除元素
            /// </summary>
            public void Detach(PersonElement element)
            {
                elements.Remove(element);
            }
    
            /// <summary>
            /// 查看显示
            /// </summary>
            public void Display(Action visitor)
            {
                foreach (var v in elements)
                {
                    v.Accept(visitor);
                }
            }
        }
    

       开启场景模拟

            static void Main(string[] args)
            {
                //面对成功
                Success v1 = new Success();
    
                //男人的结果
                new ManElement().Accept(v1);
                //女人的结果
                new WomanElement().Accept(v1);
    
                //使用结构对象进行遍历
                ObjectStructure o = new ObjectStructure();
                o.Attach(new ManElement());
                o.Attach(new WomanElement());
    
                o.Display(v1);
            }
    
  • 相关阅读:
    新式类、经典类与多继承
    实现抽象类之方式二
    实现抽象类之方式一
    re模块
    28个高频Linux命令
    Git使用教程
    编程语言介绍
    编码
    进制
    操作系统简史
  • 原文地址:https://www.cnblogs.com/amywechat/p/4942211.html
Copyright © 2020-2023  润新知