将每个类中的相关操作封装到一个独立的对象(Visitor)中,使得数据和操作进行分离。从而在不改变各元素类的前提下,定义有关这些元素的新操作。
主要组成:
Visitor-访问者父类,为每个元素声明一个访问操作。
ConcreteVisitor-具体访问者,实现Visitor父类声明的访问操作。
Element-元素父类,定义Accept(接受访问)操作。
ConcreteElement-具体元素,实现Accept操作。
ObjectStructure-对象结构,能枚举它的元素。
相关类:
using System;
using System.Collections.Generic;
namespace Visitor
{
/// <summary>
/// 访问者
/// </summary>
class Visitor
{
//虚方法,提供缺省实现
public virtual void VisitFileElement(FileElement fileElement)
{
}
public virtual void VisitFolderElement(FolderElement folderElement)
{
}
}
/// <summary>
/// 复制操作(具体访问者)
/// </summary>
class CopyVisitor : Visitor
{
public override void VisitFileElement(FileElement fileElement)
{
Console.WriteLine("复制{0}", fileElement.FileName);
}
public override void VisitFolderElement(FolderElement folderElement)
{
Console.WriteLine("复制{0}及其所有文件", folderElement.FolderName);
}
}
/// <summary>
/// 删除操作(具体访问者)
/// </summary>
class DeleteVisitor : Visitor
{
public override void VisitFileElement(FileElement fileElement)
{
Console.WriteLine("删除{0}", fileElement.FileName);
}
public override void VisitFolderElement(FolderElement folderElement)
{
Console.WriteLine("删除{0}及其所有文件", folderElement.FolderName);
}
}
/// <summary>
/// 元素父类
/// </summary>
abstract class Element
{
public abstract void Accept(Visitor visitor);
}
/// <summary>
/// 文件(具体元素)
/// </summary>
class FileElement : Element
{
public string FileName { get; set; }
public FileElement(string name)
{
FileName = name;
}
public override void Accept(Visitor visitor)
{
visitor.VisitFileElement(this);
}
}
/// <summary>
/// 文件夹(具体元素)
/// </summary>
class FolderElement : Element
{
public string FolderName { get; set; }
public FolderElement(string name)
{
FolderName = name;
}
public override void Accept(Visitor visitor)
{
visitor.VisitFolderElement(this);
}
}
/// <summary>
/// 复合元素(对象结构)
/// </summary>
class CompositeElement : Element
{
List<Element> elements = new List<Element>();
public void Add(Element element)
{
elements.Add(element);
}
public void Remove(Element element)
{
elements.Remove(element);
}
public override void Accept(Visitor visitor)
{
foreach (Element element in elements)
{
element.Accept(visitor);
}
}
}
}
调用:
using System;
namespace Visitor
{
class Program
{
static void Main(string[] args)
{
//访问者
CopyVisitor copyVisitor = new CopyVisitor();
DeleteVisitor deleteVisitor = new DeleteVisitor();
//具体元素
FileElement fileElement = new FileElement("文件A");
FolderElement folderElement = new FolderElement("文件夹B");
//复合元素
CompositeElement compositeElement = new CompositeElement();
compositeElement.Add(fileElement);
compositeElement.Add(folderElement);
//复制操作
compositeElement.Accept(copyVisitor);
//删除操作
compositeElement.Accept(deleteVisitor);
Console.Read();
}
}
}
结果:
参考资料:《设计模式-可复用面对对象软件的基础》