zoukankan      html  css  js  c++  java
  • 访问者模式(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()));
    		}
    	}
    
  • 相关阅读:
    timer使用方法
    基于开源库jsoncpp的json字符串解析
    jsoncpp构造json字符串和json数组
    通过wifi连接android设备的方法
    Linux 利用管道父子进程间传递数据
    Mac OS X 下部分Android手机无法连接adb问题之解决方案
    android studio 慢的问题
    forever让nodejs后台运行
    js里面如何才能让成员方法去调用类中其他成员
    让Windows Server 2008 + IIS 7+ ASP.NET 支持10万并发请求
  • 原文地址:https://www.cnblogs.com/LoveTomato/p/8459758.html
Copyright © 2011-2022 走看看