Chinaunix首页 | 论坛 | 博客
  • 博客访问: 666251
  • 博文数量: 220
  • 博客积分: 10487
  • 博客等级: 上将
  • 技术积分: 2072
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-09 00:25
文章分类

全部博文(220)

文章存档

2012年(5)

2011年(38)

2010年(135)

2009年(42)

我的朋友

分类:

2009-10-17 13:42:12

定义

"访问"意思是对对象元素的操作。访问者模式允许在不改变类的情况下,定义对元素新的操作。

使用频度:


UML 类图


参与者

该模式参与的类或对象

  • Visitor(访问者)
    • 为(要访问的)对象的每个元素定义Visit操作。操作的名称和签名标识了发送Visit操作到访问者的对象类型。这样访问者便能判断访问元素元素的具体类型。从而通过特定接口便能直接访问该元素。
  • ConcreteVisitor(具体访问者,如收入访问,假期访问)
    • 实现Visitor定义的每个操作。每个操作为相应的对象(类)实现一段算法,ConcreteVisitor为算法提供上下文并存储本地状态。
  • Element(元素)
    • 定义accept操作,以visitor对象作为参数。
  • ConcreteElement(具体元素)
    • 具体实现accept操作
  • ObjectStructure(对象结构)
    • 能枚举其所有元素
    • 能为其访问者提供高层次的接口
    • 可能为Composit(模式)或容器如list


C# 示例代码

// Visitor pattern -- Structural example


using System;

using System.Collections.Generic;

 

namespace DoFactory.GangOfFour.Visitor.Structural

{

  ///




  /// MainApp startup class for Structural


  /// Visitor Design Pattern.


  ///



  class MainApp

  {

    static void Main()

    {

      // Setup structure


      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);

 

      // Wait for user


      Console.ReadKey();

    }

  }

 

  ///


  /// The 'Visitor' abstract class


  ///



  abstract class Visitor

  {

    public abstract void VisitConcreteElementA(

      ConcreteElementA concreteElementA);

    public abstract void VisitConcreteElementB(

      ConcreteElementB concreteElementB);

  }

 

  ///


  /// A 'ConcreteVisitor' class


  ///



  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);

    }

  }

 

  ///


  /// A 'ConcreteVisitor' class


  ///



  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);

    }

  }

 

  ///


  /// The 'Element' abstract class


  ///



  abstract class Element

  {

    public abstract void Accept(Visitor visitor);

  }

 

  ///


  /// A 'ConcreteElement' class


  ///



  class ConcreteElementA : Element

  {

    public override void Accept(Visitor visitor)

    {

      visitor.VisitConcreteElementA(this);

    }

 

    public void OperationA()

    {

    }

  }

 

  ///


  /// A 'ConcreteElement' class


  ///



  class ConcreteElementB : Element

  {

    public override void Accept(Visitor visitor)

    {

      visitor.VisitConcreteElementB(this);

    }

 

    public void OperationB()

    {

    }

  }

 

  ///


  /// The 'ObjectStructure' class


  ///



  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);

      }

    }

  }

}


输出

ConcreteElementA visited by ConcreteVisitor1
ConcreteElementB visited by ConcreteVisitor1
ConcreteElementA visited by ConcreteVisitor2
ConcreteElementB visited by ConcreteVisitor2


阅读(721) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~