访问者模式(Visitor Pattern)

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值