访问者模式(Visitor Pattern)

Posted LoveTomato

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了访问者模式(Visitor Pattern)相关的知识,希望对你有一定的参考价值。

模式定义

封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。

UML类图

  • 抽象访问者(Vistor) 声明一个或多个访问抽象节点类型的抽象方法(参数为抽象节点类型),依赖抽象节点类型。
  • 具体访问者(ConcreteElement) 实现抽象访问者角色中所有声明的接口。
  • 抽象元素(Element) 声明节点被访问者访问的方法,依赖与访问者。
  • 具体元素(ConcreteElement) 实现抽象元素所规定的接受操作。
  • 对象结构(ObjectStructure) 节点的容器,可以包含多个不同类或接口的容器。

代码结构

	public static class VisitorApp
	{
		public static void Run()
		{
			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);
		}
	}

	abstract class Visitor
	{
		public abstract void VisitConcreteElementA(ConcreteElementA concreteElementA);
		public abstract void VisitConcreteElementB(ConcreteElementB concreteElementB);
	}
	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);
		}
	}
	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);

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

	class ConcreteElementA : Element
	{
		public override void Accept(Visitor visitor)
		{
			visitor.VisitConcreteElementA(this);
		}
	}
	class ConcreteElementB : Element
	{
		public override void Accept(Visitor visitor)
		{
			visitor.VisitConcreteElementB(this);
		}
	}
	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);
			}
		}
	}

情景案例

这种模式在.Net 框架中没必要按部就班的这么麻烦的用了。.Net 框架中ForEach(Action<T> action)遍历集合执行每个元素执行委托。

	public static class VisitorRealWorldApp
	{
		public static void Run()
		{
			List<string> lst = new List<string>() { "Item1", "Item2", "Item3" };
			lst.ForEach(i => Console.WriteLine("方法一 " + i.ToString()));
			lst.ForEach(i => Console.WriteLine("方法二 " + i.ToString()));
		}
	}

以上是关于访问者模式(Visitor Pattern)的主要内容,如果未能解决你的问题,请参考以下文章

访问者模式(Visitor Pattern)

访问者模式(Visitor Pattern)

22访问者模式(Visitor Pattern)

秒懂设计模式之访问者模式(Visitor Pattern)

尚硅谷设计模式学习(16)---[访问者模式(Visitor Pattern)]

二十三种设计模式[23] - 访问者模式(Visitor Pattern)