[索引页]
[×××]


乐在其中设计模式(C#) - 访问者模式(Visitor Pattern)


作者: webabcd


介绍
表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。


示例
有一个Message实体类,某些对象对它的操作有Insert()和Get()方法,现在要针对其中某一方法进行操作。
 
 
 
MessageModel
InBlock.gif using System;
InBlock.gif using System.Collections.Generic;
InBlock.gif using System.Text;
InBlock.gif
InBlock.gif namespace Pattern.Visitor
InBlock.gif{
InBlock.gif         /// <summary>
InBlock.gif         /// Message实体类
InBlock.gif         /// </summary>
InBlock.gif         public class MessageModel
InBlock.gif        {
InBlock.gif                 /// <summary>
InBlock.gif                 /// 构造函数
InBlock.gif                 /// </summary>
InBlock.gif                 /// <param name="msg">Message内容</param>
InBlock.gif                 /// <param name="pt">Message发布时间</param>
InBlock.gif                 public MessageModel( string msg, DateTime pt)
InBlock.gif                {
InBlock.gif                         this._message = msg;
InBlock.gif                         this._publishTime = pt;
InBlock.gif                }
InBlock.gif
InBlock.gif                 private string _message;
InBlock.gif                 /// <summary>
InBlock.gif                 /// Message内容
InBlock.gif                 /// </summary>
InBlock.gif                 public string Message
InBlock.gif                {
InBlock.gif                        get { return _message; }
InBlock.gif                        set { _message = value; }
InBlock.gif                }
InBlock.gif
InBlock.gif                 private DateTime _publishTime;
InBlock.gif                 /// <summary>
InBlock.gif                 /// Message发布时间
InBlock.gif                 /// </summary>
InBlock.gif                 public DateTime PublishTime
InBlock.gif                {
InBlock.gif                        get { return _publishTime; }
InBlock.gif                        set { _publishTime = value; }
InBlock.gif                }
InBlock.gif        }
InBlock.gif}
 
AbstractElement
InBlock.gif using System;
InBlock.gif using System.Collections.Generic;
InBlock.gif using System.Text;
InBlock.gif
InBlock.gif namespace Pattern.Visitor
InBlock.gif{
InBlock.gif         /// <summary>
InBlock.gif         /// 抽象元素(Element)
InBlock.gif         /// </summary>
InBlock.gif         public abstract class AbstractElement
InBlock.gif        {
InBlock.gif                 /// <summary>
InBlock.gif                 /// 执行抽象访问者的Visit()方法(从而执行抽象元素的方法)
InBlock.gif                 /// </summary>
InBlock.gif                 /// <param name="abstractVisitor">抽象访问者</param>
InBlock.gif                 /// <returns></returns>
InBlock.gif                 public abstract string Accept(AbstractVisitor abstractVisitor);
InBlock.gif        }
InBlock.gif}
 
Message
InBlock.gif using System;
InBlock.gif using System.Collections.Generic;
InBlock.gif using System.Text;
InBlock.gif
InBlock.gif namespace Pattern.Visitor
InBlock.gif{
InBlock.gif         /// <summary>
InBlock.gif         /// 操作Message抽象类(Element)
InBlock.gif         /// </summary>
InBlock.gif         public abstract class Message : AbstractElement
InBlock.gif        {
InBlock.gif                 private MessageModel _messageModel;
InBlock.gif
InBlock.gif                 /// <summary>
InBlock.gif                 /// 构造函数
InBlock.gif                 /// </summary>
InBlock.gif                 /// <param name="mm">Message实体对象</param>
InBlock.gif                 public Message(MessageModel mm)
InBlock.gif                {
InBlock.gif                         this._messageModel = mm;
InBlock.gif                }
InBlock.gif
InBlock.gif                 /// <summary>
InBlock.gif                 /// Message实体对象
InBlock.gif                 /// </summary>
InBlock.gif                 public MessageModel MessageModel
InBlock.gif                {
InBlock.gif                        get { return _messageModel; }
InBlock.gif                        set { _messageModel = value; }
InBlock.gif                }
InBlock.gif
InBlock.gif                 /// <summary>
InBlock.gif                 /// 执行抽象访问者的Visit()方法(从而执行抽象元素的方法)
InBlock.gif                 /// </summary>
InBlock.gif                 /// <param name="abstractVisitor">抽象访问者</param>
InBlock.gif                 /// <returns></returns>
InBlock.gif                 public override string Accept(AbstractVisitor abstractVisitor)
InBlock.gif                {
InBlock.gif                         return abstractVisitor.Visit( this);
InBlock.gif                }
InBlock.gif
InBlock.gif                 /// <summary>
InBlock.gif                 /// 获取Message
InBlock.gif                 /// </summary>
InBlock.gif                 /// <returns></returns>
InBlock.gif                 public abstract List<MessageModel> Get();
InBlock.gif
InBlock.gif                 /// <summary>
InBlock.gif                 /// 插入Message
InBlock.gif                 /// </summary>
InBlock.gif                 /// <returns></returns>
InBlock.gif                 public abstract bool Insert();
InBlock.gif        }
InBlock.gif}
 
SqlMessage
InBlock.gif using System;
InBlock.gif using System.Collections.Generic;
InBlock.gif using System.Text;
InBlock.gif
InBlock.gif namespace Pattern.Visitor
InBlock.gif{
InBlock.gif         /// <summary>
InBlock.gif         /// Sql方式操作Message(ConcreteElement)
InBlock.gif         /// </summary>
InBlock.gif         public class SqlMessage : Message
InBlock.gif        {
InBlock.gif                 /// <summary>
InBlock.gif                 /// 构造函数
InBlock.gif                 /// </summary>
InBlock.gif                 /// <param name="mm">Message实体对象</param>
InBlock.gif                 public SqlMessage(MessageModel mm)
InBlock.gif                        : base(mm)
InBlock.gif                {
InBlock.gif                        
InBlock.gif                }
InBlock.gif
InBlock.gif                 /// <summary>
InBlock.gif                 /// 获取Message
InBlock.gif                 /// </summary>
InBlock.gif                 /// <returns></returns>
InBlock.gif                 public override List<MessageModel> Get()
InBlock.gif                {
InBlock.gif                        List<MessageModel> l = new List<MessageModel>();
InBlock.gif                        l.Add( new MessageModel( "SQL方式获取Message", DateTime.Now));
InBlock.gif
InBlock.gif                         return l;
InBlock.gif                }
InBlock.gif
InBlock.gif                 /// <summary>
InBlock.gif                 /// 插入Message
InBlock.gif                 /// </summary>
InBlock.gif                 /// <returns></returns>
InBlock.gif                 public override bool Insert()
InBlock.gif                {
InBlock.gif                         // 代码略
InBlock.gif                         return true;
InBlock.gif                }
InBlock.gif        }
InBlock.gif}
 
XmlMessage
InBlock.gif using System;
InBlock.gif using System.Collections.Generic;
InBlock.gif using System.Text;
InBlock.gif
InBlock.gif namespace Pattern.Visitor
InBlock.gif{
InBlock.gif         /// <summary>
InBlock.gif         /// Xml方式操作Message(ConcreteElement)
InBlock.gif         /// </summary>
InBlock.gif         public class XmlMessage : Message
InBlock.gif        {
InBlock.gif                 /// <summary>
InBlock.gif                 /// 构造函数
InBlock.gif                 /// </summary>
InBlock.gif                 /// <param name="mm">Message实体对象</param>
InBlock.gif                 public XmlMessage(MessageModel mm)
InBlock.gif                        : base(mm)
InBlock.gif                {
InBlock.gif    
InBlock.gif                }
InBlock.gif
InBlock.gif                 /// <summary>
InBlock.gif                 /// 获取Message
InBlock.gif                 /// </summary>
InBlock.gif                 /// <returns></returns>
InBlock.gif                 public override List<MessageModel> Get()
InBlock.gif                {
InBlock.gif                        List<MessageModel> l = new List<MessageModel>();
InBlock.gif                        l.Add( new MessageModel( "XML方式获取Message", DateTime.Now));
InBlock.gif
InBlock.gif                         return l;
InBlock.gif                }
InBlock.gif
InBlock.gif                 /// <summary>
InBlock.gif                 /// 插入Message
InBlock.gif                 /// </summary>
InBlock.gif                 /// <returns></returns>
InBlock.gif                 public override bool Insert()
InBlock.gif                {
InBlock.gif                         // 代码略
InBlock.gif                         return true;
InBlock.gif                }
InBlock.gif        }
InBlock.gif}
 

AbstractVisitor
InBlock.gif using System;
InBlock.gif using System.Collections.Generic;
InBlock.gif using System.Text;
InBlock.gif
InBlock.gif namespace Pattern.Visitor
InBlock.gif{
InBlock.gif         /// <summary>
InBlock.gif         /// 抽象访问者(Visitor)
InBlock.gif         /// </summary>
InBlock.gif         public abstract class AbstractVisitor
InBlock.gif        {
InBlock.gif                 /// <summary>
InBlock.gif                 /// 执行抽象元素的方法
InBlock.gif                 /// </summary>
InBlock.gif                 /// <param name="abstractElement">抽象元素</param>
InBlock.gif                 /// <returns></returns>
InBlock.gif                 public abstract string Visit(AbstractElement abstractElement);
InBlock.gif        }
InBlock.gif}
 
InsertVisitor
InBlock.gif using System;
InBlock.gif using System.Collections.Generic;
InBlock.gif using System.Text;
InBlock.gif
InBlock.gif namespace Pattern.Visitor
InBlock.gif{
InBlock.gif         /// <summary>
InBlock.gif         /// Insert访问者(ConcreteVisitor)
InBlock.gif         /// </summary>
InBlock.gif         public class InsertVisitor : AbstractVisitor
InBlock.gif        {
InBlock.gif                 /// <summary>
InBlock.gif                 /// 执行Message的Insert()方法
InBlock.gif                 /// </summary>
InBlock.gif                 /// <param name="abstractElement">抽象元素</param>
InBlock.gif                 /// <returns></returns>
InBlock.gif                 public override string Visit(AbstractElement abstractElement)
InBlock.gif                {
InBlock.gif                        Message m = abstractElement as Message;
InBlock.gif
InBlock.gif                         return m.Insert().ToString() + "<br />";
InBlock.gif                }
InBlock.gif        }
InBlock.gif}
 
GetVisitor
InBlock.gif using System;
InBlock.gif using System.Collections.Generic;
InBlock.gif using System.Text;
InBlock.gif
InBlock.gif namespace Pattern.Visitor
InBlock.gif{
InBlock.gif         /// <summary>
InBlock.gif         /// Get访问者(ConcreteVisitor)
InBlock.gif         /// </summary>
InBlock.gif         public class GetVisitor : AbstractVisitor
InBlock.gif        {
InBlock.gif                 /// <summary>
InBlock.gif                 /// 执行Message的Get()方法
InBlock.gif                 /// </summary>
InBlock.gif                 /// <param name="abstractElement">抽象元素</param>
InBlock.gif                 /// <returns></returns>
InBlock.gif                 public override string Visit(AbstractElement abstractElement)
InBlock.gif                {
InBlock.gif                        Message m = abstractElement as Message;
InBlock.gif
InBlock.gif                         return m.Get()[0].Message + " " + m.Get()[0].PublishTime.ToString() + "<br />";
InBlock.gif                }
InBlock.gif        }
InBlock.gif}
 
Messages
InBlock.gif using System;
InBlock.gif using System.Collections.Generic;
InBlock.gif using System.Text;
InBlock.gif
InBlock.gif namespace Pattern.Visitor
InBlock.gif{
InBlock.gif         /// <summary>
InBlock.gif         /// Message集合(ObjectStructure)
InBlock.gif         /// </summary>
InBlock.gif         public class Messages
InBlock.gif        {
InBlock.gif                 private List<Message> _list = new List<Message>();
InBlock.gif
InBlock.gif                 /// <summary>
InBlock.gif                 /// 添加一个Message对象
InBlock.gif                 /// </summary>
InBlock.gif                 /// <param name="message">Message对象</param>
InBlock.gif                 public void Attach(Message message)
InBlock.gif                {
InBlock.gif                        _list.Add(message);
InBlock.gif                }
InBlock.gif
InBlock.gif                 /// <summary>
InBlock.gif                 /// 移除一个Message对象
InBlock.gif                 /// </summary>
InBlock.gif                 /// <param name="message">Message对象</param>
InBlock.gif                 public void Detach(Message message)
InBlock.gif                {
InBlock.gif                        _list.Remove(message);
InBlock.gif                }
InBlock.gif
InBlock.gif                 /// <summary>
InBlock.gif                 /// 执行集合内所有Message对象的Accept()方法(执行抽象访问者的Visit()方法(从而执行抽象元素的方法))
InBlock.gif                 /// </summary>
InBlock.gif                 /// <param name="abstractVisitor">抽象访问者</param>
InBlock.gif                 /// <returns></returns>
InBlock.gif                 public string Accept(AbstractVisitor abstractVisitor)
InBlock.gif                {
InBlock.gif                         string s = "";
InBlock.gif                         foreach (Message m in _list)
InBlock.gif                        {
InBlock.gif                                s += m.Accept(abstractVisitor);
InBlock.gif                        }
InBlock.gif
InBlock.gif                         return s;
InBlock.gif                }
InBlock.gif        }
InBlock.gif}
 
Test
InBlock.gif using System;
InBlock.gif using System.Data;
InBlock.gif using System.Configuration;
InBlock.gif using System.Collections;
InBlock.gif using System.Web;
InBlock.gif using System.Web.Security;
InBlock.gif using System.Web.UI;
InBlock.gif using System.Web.UI.WebControls;
InBlock.gif using System.Web.UI.WebControls.WebParts;
InBlock.gif using System.Web.UI.HtmlControls;
InBlock.gif
InBlock.gif using Pattern.Visitor;
InBlock.gif
InBlock.gif public partial class Visitor : System.Web.UI.Page
InBlock.gif{
InBlock.gif         protected void Page_Load( object sender, EventArgs e)
InBlock.gif        {
InBlock.gif                Pattern.Visitor.Messages m = new Pattern.Visitor.Messages();
InBlock.gif
InBlock.gif                m.Attach( new SqlMessage( new MessageModel( "插入", DateTime.Now)));
InBlock.gif                m.Attach( new XmlMessage( new MessageModel( "插入", DateTime.Now)));
InBlock.gif
InBlock.gif                Response.Write(m.Accept( new InsertVisitor()));
InBlock.gif                Response.Write(m.Accept( new GetVisitor()));
InBlock.gif        }
InBlock.gif}
 
 
运行结果
True
True
SQL方式获取Message 2007-5-27 15:01:53
XML方式获取Message 2007-5-27 15:01:53


参考
http://www.dofactory.com/Patterns/PatternVisitor.aspx


OK
[×××]