1应用:
访问者模式的目的是封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变。
2:角色:
* 抽象访问者(Visitor)角色:声明了一个或者多个访问操作,形成所有的具体元素角色必须实现的接口。
* 具体访问者(ConcreteVisitor)角色:实现抽象访问者角色所声明的接口,也就是抽象访问者所声明的各个访问操作。
* 抽象节点(Node)角色:声明一个接受操作,接受一个访问者对象作为一个参量。
* 具体节点(Node)角色:实现了抽象元素所规定的接受操作。
* 结构对象(ObiectStructure)角色:有如下的一些责任,可以遍历结构中的所有元素;如果需要,提供一个高层次的接口让访问者对象可以访问每一个元素;如果需要,可以设计成一个复合对象或者一个聚集,如列(List)或集合(Set)。
3:故事:
此时悟空摘了桃子,手托钵盂,一个筋斗翻了回来。睁开火眼金睛观看,认得这女子是个妖精,二话不说,掣出铁棒,当头就要打下。
唐僧急忙扯住悟空:“徒儿,你这是做什么?”
“师父,这女子是个妖怪。她这是要来骗你哩!”
“悟空,这女子一心向善,适才还要将送她丈夫的饭菜斋与我等,怎说她是个妖精?”
“师父,你哪里知道,妖精惯用假象骗人。老孙若晚来一刻,只恐你已遭她的毒手了。”
唐僧口中不住念佛,只是不信。悟空趁唐僧一个疏神,当头一棒打中了那女子。
白骨精也真了得,悟空棍棒落下,她早巳化作一缕轻烟逃走,地上只剩下一具假尸首。
三藏一见,只吓得战战兢兢:“悟空,你好大胆!我屡次劝你,怎可无故伤人性命!"
“师父莫怪,你来看看这罐子里是什么?”
唐僧近前一看,哪里来的香米饭、炒面筋。不过是一罐子拖尾巴的长蛆和几个青蛙、癞蛤蟆。
4:分析
具体节点
女子--白骨精
香米饭--拖尾巴的长蛆
炒面筋--青蛙、癞蛤蟆
抽象节点
被看
具体访问者:
孙悟空 看本质
唐僧 看假象
抽象访问者
看
结构对象:
包含具体节点的集合
接待访问者
5实现:
// Visitor pattern -- Real World example
using System;
using System.Collections;
/// <summary>
/// 争执的原因就是因为"它们"--女子,面筋
/// 在不同的观察者那儿看起来不一样,所以它们都能被看到
/// </summary>
public interface 抽象事物 {
void 被看(访问者 具体的访问者);
}
/// <summary>
/// 这儿可以更细的补充事物的细节,除了名字,本质
/// 还可以是"拖尾巴的"长蛆.....
/// </summary>
public class 事物 : 抽象事物
{
public string 本质;
public string 假象;
public 事物(string 假象, string 本质)
{
this.本质 = 本质;
this.假象 = 假象;
}
public void 被看(访问者 具体的访问者) {
具体的访问者.看(this);
}
}
/// <summary>
/// 抽象的观察者
/// </summary>
public interface 访问者 {
void 看(事物 具体的事物);
}
/// <summary>
/// 专业看假象的观察者
/// </summary>
public class 唐三藏 : 访问者 {
public void 看(事物 具体的事物) {
Console.WriteLine("唐三藏:我看到这是一个"+具体的事物.假象);
}
}
/// <summary>
/// 专业看本质的观察者
/// </summary>
public class 孙悟空 : 访问者
{
public void 看(事物 具体的事物)
{
Console.WriteLine("孙悟空:我看到这是一个" + 具体的事物.本质);
}
}
public class 事物集 {
/// <summary>
/// 访问者模式实现的是一种 倾斜的可扩展性
/// 它必须知道所有的内部元素
/// 如果以后要修改或增加元素个数都会导致需要修改源码
/// </summary>
private 抽象事物[] 事物集合;
public 事物集() {
事物集合 = new 抽象事物[]{new 事物("女子","白骨精"),
new 事物("香米饭","拖尾巴的长蛆"),
new 事物("炒面筋","青蛙、癞蛤蟆")
};
}
/// <summary>
/// 但是如果内部元素恒定,可以很方便的护充观察者
/// 比如猪八戒也可以实现"访问者"接口来看看事物集中的元素到底是什么
/// </summary>
/// <param name="具体的访问者"></param>
public void 接待访问者(访问者 具体的访问者) {
foreach (抽象事物 事物集合成员 in 事物集合) {
事物集合成员.被看(具体的访问者);
}
}
}
public class 应用
{
public static void Main( string[] args )
{
//初始化事物集
事物集 事物集合 = new 事物集();
//接待来访者,让大家看看这倒底是什么?
事物集合.接待访问者(new 唐三藏());
事物集合.接待访问者(new 孙悟空());
Console.Read();
}
}
6:结果
唐三藏:我看到这是一个女子
唐三藏:我看到这是一个香米饭
唐三藏:我看到这是一个炒面筋
孙悟空:我看到这是一个白骨精
孙悟空:我看到这是一个拖尾巴的长蛆
孙悟空:我看到这是一个青蛙、癞蛤蟆
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/blackant2/archive/2006/10/07/1324192.aspx