码迷,mamicode.com
首页 > 其他好文 > 详细

OO设计模式_访问者模式

时间:2015-01-06 15:16:21      阅读:102      评论:0      收藏:0      [点我收藏+]

标签:

Motivation:

在软件构建过程中,由于需求的改变,某些类层次结构中常常需要增加新的行为(方法),如果直接在基类中做这样的更改,将会给子类带来很繁重的变更负担,甚至破坏原有的设计。

如果在不更改类层次结构的前提下,在运行时根据需要透明地为类层次结构上的各个类动态添加新的操作,从而避免上述问题?

Intent:

表示一个作用于某个对象结构中各个元素的操作。它可以在不改变各元素的类的前提下定义作用于这些元素的新的操作。

Main point:

Visitor模式通过所谓双重分发(double dispatch)来实现在不更改Element类层次结构的前提下,在运行时透明地为类层次结构上的各个类动态添加新的操作。

所谓double dispatch即Visitor模式中间包括两个多态分发(注意其中的多态机制):第一个为Accept方法的多态辨析;第二个为Visit方法的多态辨析。

Visitor模式的最大缺点在于扩展类层次结构(增加新的Element子类),会导致Visitor类的改变。因此Visitor模式适用于"Element"类层次结构稳定,而其中的操作却经常面临频繁改动。

 

技术分享

 

namespace 访问者模式
{
    class Program
    {
        static void Main(string[] args)
        {
            //ObjectStructure o = new ObjectStructure();
            //o.Attach(new ConcreteElementA());
            //o.Attach(new ConcreteElementB());

            //ConcreteVisitor1 v1 = new ConcreteVisitor1();
            //ConcreteVisitor2 v2 = new ConcreteVisitor2();

            //o.Accept(v1);
            //o.Accept(v2);

            //Console.Read();
            Element e= new ConcreteElementA();
            Console.WriteLine(e.GetType().Name);
            Visitor v = new ConcreteVisitor1();
            App a = new App(v);
            a.Process(e);
            Console.ReadLine();
        }
    }
    class App
    {
        Visitor vistor;
        public App (Visitor v)
        {
            this.vistor = v;
        }
        public void Process(Element e)
        {
            e.Accept(vistor);
        }
    }

    abstract class Visitor
    {
        public abstract void VisitConcreteElement(ConcreteElementA concreteElementA);

        public abstract void VisitConcreteElement(ConcreteElementB concreteElementB);
    }

    class ConcreteVisitor1 : Visitor
    {
        public override void VisitConcreteElement(ConcreteElementA concreteElementA)
        {
            Console.WriteLine("{0}被{1}访问", concreteElementA.GetType().Name, this.GetType().Name);
        }

        public override void VisitConcreteElement(ConcreteElementB concreteElementB)
        {
            Console.WriteLine("{0}被{1}访问", concreteElementB.GetType().Name, this.GetType().Name);
        }
    }

    class ConcreteVisitor2 : Visitor
    {
        public override void VisitConcreteElement(ConcreteElementA concreteElementA)
        {
            Console.WriteLine("{0}被{1}访问", concreteElementA.GetType().Name, this.GetType().Name);
        }

        public override void VisitConcreteElement(ConcreteElementB concreteElementB)
        {
            Console.WriteLine("{0}被{1}访问", concreteElementB.GetType().Name, this.GetType().Name);
        }
    }

    abstract class Element
    {
        public abstract void Accept(Visitor visitor);
    }

    class ConcreteElementA : Element
    {
        public override void Accept(Visitor visitor)
        {
            visitor.VisitConcreteElement(this);
        }

        public void OperationA()
        { }
    }
        
    class ConcreteElementB : Element
    {
        public override void Accept(Visitor visitor)
        {
            visitor.VisitConcreteElement(this);
        }

        public void OperationB()
        { }
    }

    class ObjectStructure
    {
        private IList<Element> elements = new List<Element>();

        public void Attach(Element element)
        {
            elements.Add(element);
        }

        public void Detach(Element element)
        {
            elements.Remove(element);
        }

        public void Accept(Visitor visitor)
        {
            foreach (Element e in elements)
            {
                e.Accept(visitor);
            }
        }
    }
}

 

 

技术分享

OO设计模式_访问者模式

标签:

原文地址:http://www.cnblogs.com/xanadu123/p/4205848.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!