65.9K
CodeProject 正在变化。 阅读更多。
Home

访问者模式

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.89/5 (2投票s)

2008 年 10 月 1 日

CPOL

1分钟阅读

viewsIcon

9320

访问者设计模式使我们能够为现有的结构创建新的操作。这些新操作不会改变

访问者设计模式使我们能够为现有的结构创建新的操作。这些新操作不会改变类/节点。
使用这种模式,你定义两个类层次结构。第一个是操作将要操作的元素,第二个是定义在这些元素上操作的访问者。
这种模式很少使用,但它在编译器实现中很常见。

访问者模式的使用场景

您应该在以下情况下使用该模式

  • 你有一个具有许多不同操作的类层次结构。
  • 对象结构中定义的类很少改变,但你 有时需要定义对象结构上的新操作。

UML 图

C# 示例

以下代码展示了如何实现该模式的示例

#region Visitor
    public interface IVisitor
    { 
        #region Methods
        void Visit(Element element);
        #endregion
    }
    #endregion

    #region Visitor Concrete
    public class VisitorConcreteA : IVisitor
    {
        #region IVisitor Members
        public void Visit(Element element)
        {
            Console.WriteLine("{0} Visited {1}", this.GetType().Name, element.GetType().Name); 
        }
        #endregion
    }

    public class VisitorConcreteB : IVisitor
    {
        #region IVisitor Members
        public void Visit(Element element)
        {
            Console.WriteLine("{0} Visited {1}", this.GetType().Name, element.GetType().Name); 
        }
        #endregion
    }
    #endregion

    #region Element
    public interface IElement
    {
        #region Methods
        void Accept(IVisitor visitor);
        #endregion
    }

    public abstract class Element : IElement
    {
        #region IElement Members
        public void Accept(IVisitor visitor)
        {
            visitor.Visit(this);
        }
        #endregion
    }
    #endregion

    #region Concrete Element
    public class ElementConcreteA : Element
    {
        // implement whatever you need
    }

    public class ElementConcreteB : Element
    {
        // implement whatever you need
    }
    #endregion

    #region Object Structure
    public class ObjectStructure
    {
        #region Members
        private List<Element> _elements;
        #endregion

        #region Ctor
        /// <summary>
        /// Construct a new object structure
        /// </summary>
        public ObjectStructure()
        {
            _elements = new List<Element>();
        }
        #endregion

        #region Methods
        /// <summary>
        /// Attach the given element to the object structure
        /// </summary>
        /// <param name="element">The element to attach</param>
        public void AttachElement(Element element)
        {
            _elements.Add(element);
        }

        /// <summary>
        /// Detaches the given element from the object structure
        /// </summary>
        /// <param name="element">The element to detach</param>
        public void DetachElement(Element element)
        {
            _elements.Remove(element);
        }

        /// <summary>
        /// Perform accept operation on all the object structure
        /// with the given visitor
        /// </summary>
        /// <param name="visitor">The given visitor</param>
        public void Accept(IVisitor visitor)
        {
            foreach (Element element in _elements)
            {
                element.Accept(visitor);
            }
        }
        #endregion

    }
    #endregion

在示例中,我使用一个用内部列表实现的结构。你可以根据模式的需要使用任何对象结构。
如示例所示,我使用两个主要接口来实现该模式 – IVisitorIElement
IElement 接口将 Accept 方法添加到 Element 抽象类,每个具体元素都实现该方法(我可以删除 IElement 接口或 Element 类,但我选择不这样做)。
每个访问者都实现 Visit 操作以执行所需的操作(在我的实现中,两个具体类中的 Visit 方法实现相同)。

以下代码显示了如何使用上述类的示例

   // Build the structure 
   ObjectStructure structure = new ObjectStructure();
   structure.AttachElement(new ElementConcreteA());
   structure.AttachElement(new ElementConcreteB());

   // Create visitor objects
   VisitorConcreteA visitorA = new VisitorConcreteA();
   VisitorConcreteB visitorB = new VisitorConcreteB();

   // Structure accepting visitors
   structure.Accept(visitorA);
   structure.Accept(visitorB);

   Console.Read();

摘要 

总而言之,你已经了解了访问者设计模式。该模式用于在无需更改元素的情况下,通过新的操作扩展对象结构的元素。
如前所述,该模式很少使用。

© . All rights reserved.