定义"访问"意思是对对象元素的操作。访问者模式允许在不改变类的情况下,定义对元素新的操作。
使用频度:
低
UML 类图
参与者该模式参与的类或对象
- 为(要访问的)对象的每个元素定义Visit操作。操作的名称和签名标识了发送Visit操作到访问者的对象类型。这样访问者便能判断访问元素元素的具体类型。从而通过特定接口便能直接访问该元素。
- ConcreteVisitor(具体访问者,如收入访问,假期访问)
- 实现Visitor定义的每个操作。每个操作为相应的对象(类)实现一段算法,ConcreteVisitor为算法提供上下文并存储本地状态。
- 定义accept操作,以visitor对象作为参数。
- 能枚举其所有元素
- 能为其访问者提供高层次的接口
- 可能为Composit(模式)或容器如list
C# 示例代码
// Visitor pattern -- Structural example
using System;
using System.Collections.Generic;
namespace DoFactory.GangOfFour.Visitor.Structural
{
///
/// MainApp startup class for Structural
/// Visitor Design Pattern.
///
class MainApp
{
static void Main()
{
// Setup structure
ObjectStructure o = new ObjectStructure();
o.Attach(new ConcreteElementA());
o.Attach(new ConcreteElementB());
// Create visitor objects
ConcreteVisitor1 v1 = new ConcreteVisitor1();
ConcreteVisitor2 v2 = new ConcreteVisitor2();
// Structure accepting visitors
o.Accept(v1);
o.Accept(v2);
// Wait for user
Console.ReadKey();
}
}
///
/// The 'Visitor' abstract class
///
abstract class Visitor
{
public abstract void VisitConcreteElementA(
ConcreteElementA concreteElementA);
public abstract void VisitConcreteElementB(
ConcreteElementB concreteElementB);
}
///
/// A 'ConcreteVisitor' class
///
class ConcreteVisitor1 : Visitor
{
public override void VisitConcreteElementA(
ConcreteElementA concreteElementA)
{
Console.WriteLine("{0} visited by {1}",
concreteElementA.GetType().Name, this.GetType().Name);
}
public override void VisitConcreteElementB(
ConcreteElementB concreteElementB)
{
Console.WriteLine("{0} visited by {1}",
concreteElementB.GetType().Name, this.GetType().Name);
}
}
///
/// A 'ConcreteVisitor' class
///
class ConcreteVisitor2 : Visitor
{
public override void VisitConcreteElementA(
ConcreteElementA concreteElementA)
{
Console.WriteLine("{0} visited by {1}",
concreteElementA.GetType().Name, this.GetType().Name);
}
public override void VisitConcreteElementB(
ConcreteElementB concreteElementB)
{
Console.WriteLine("{0} visited by {1}",
concreteElementB.GetType().Name, this.GetType().Name);
}
}
///
/// The 'Element' abstract class
///
abstract class Element
{
public abstract void Accept(Visitor visitor);
}
///
/// A 'ConcreteElement' class
///
class ConcreteElementA : Element
{
public override void Accept(Visitor visitor)
{
visitor.VisitConcreteElementA(this);
}
public void OperationA()
{
}
}
///
/// A 'ConcreteElement' class
///
class ConcreteElementB : Element
{
public override void Accept(Visitor visitor)
{
visitor.VisitConcreteElementB(this);
}
public void OperationB()
{
}
}
///
/// The 'ObjectStructure' class
///
class ObjectStructure
{
private List<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 element in _elements)
{
element.Accept(visitor);
}
}
}
}
|
输出ConcreteElementA visited by ConcreteVisitor1
ConcreteElementB visited by ConcreteVisitor1
ConcreteElementA visited by ConcreteVisitor2
ConcreteElementB visited by ConcreteVisitor2
|
阅读(721) | 评论(0) | 转发(0) |