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

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

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

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

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);
        }

 

posted @ 2015-11-06 12:02  荒古禁地  阅读(230)  评论(0编辑  收藏  举报