访问者模式






4.89/5 (2投票s)
访问者设计模式使我们能够为现有的结构创建新的操作。这些新操作不会改变
访问者设计模式使我们能够为现有的结构创建新的操作。这些新操作不会改变类/节点。
使用这种模式,你定义两个类层次结构。第一个是操作将要操作的元素,第二个是定义在这些元素上操作的访问者。
这种模式很少使用,但它在编译器实现中很常见。
访问者模式的使用场景
您应该在以下情况下使用该模式
- 你有一个具有许多不同操作的类层次结构。
- 对象结构中定义的类很少改变,但你 有时需要定义对象结构上的新操作。
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
在示例中,我使用一个用内部列表实现的结构。你可以根据模式的需要使用任何对象结构。
如示例所示,我使用两个主要接口来实现该模式 – IVisitor
和 IElement
。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();
摘要
总而言之,你已经了解了访问者设计模式。该模式用于在无需更改元素的情况下,通过新的操作扩展对象结构的元素。
如前所述,该模式很少使用。