访问者模式(Visitor)

1.    定义

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

2.      UML 类图

 

3.      结构代码

// Visitor pattern -- Structural example

using System;

using System.Collections.Generic;

 

namespace DoFactory.GangOfFour.Visitor.Structural

{

  ///<summary>

  /// MainApp startup class for Structural

  /// Visitor Design Pattern.

  ///</summary>

  classMainApp

  {

    staticvoid Main()

    {

      // Setup structure

      ObjectStructure o =new ObjectStructure();

      o.Attach(newConcreteElementA());

      o.Attach(newConcreteElementB());

 

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

    }

  }

 

  ///<summary>

  /// The 'Visitor' abstract class

  ///</summary>

  abstractclass Visitor

  {

    publicabstract void VisitConcreteElementA(

      ConcreteElementA concreteElementA);

    publicabstract void VisitConcreteElementB(

      ConcreteElementB concreteElementB);

  }

 

  ///<summary>

  /// A 'ConcreteVisitor' class

  ///</summary>

  classConcreteVisitor1 : Visitor

  {

    publicoverride void VisitConcreteElementA(

      ConcreteElementA concreteElementA)

    {

      Console.WriteLine("{0} visited by {1}",

        concreteElementA.GetType().Name,this.GetType().Name);

    }

 

    publicoverride void VisitConcreteElementB(

      ConcreteElementB concreteElementB)

    {

      Console.WriteLine("{0} visited by {1}",

        concreteElementB.GetType().Name,this.GetType().Name);

    }

  }

 

  ///<summary>

  /// A 'ConcreteVisitor' class

  ///</summary>

  classConcreteVisitor2 : Visitor

  {

    publicoverride void VisitConcreteElementA(

      ConcreteElementA concreteElementA)

    {

      Console.WriteLine("{0} visited by {1}",

        concreteElementA.GetType().Name,this.GetType().Name);

    }

 

    publicoverride void VisitConcreteElementB(

      ConcreteElementB concreteElementB)

    {

      Console.WriteLine("{0} visited by {1}",

        concreteElementB.GetType().Name,this.GetType().Name);

    }

  }

 

  ///<summary>

  /// The 'Element' abstract class

  ///</summary>

  abstractclass Element

  {

    publicabstract void Accept(Visitor visitor);

  }

 

  ///<summary>

  /// A 'ConcreteElement' class

  ///</summary>

  classConcreteElementA : Element

  {

    publicoverride void Accept(Visitor visitor)

    {

      visitor.VisitConcreteElementA(this);

    }

 

    publicvoid OperationA()

    {

    }

  }

 

  ///<summary>

  /// A 'ConcreteElement' class

  ///</summary>

  classConcreteElementB : Element

  {

    publicoverride void Accept(Visitor visitor)

    {

      visitor.VisitConcreteElementB(this);

    }

 

    publicvoid OperationB()

    {

    }

  }

 

  ///<summary>

  /// The 'ObjectStructure' class

  ///</summary>

  classObjectStructure

  {

    privateList<Element> _elements =new List<Element>();

 

    publicvoid Attach(Element element)

    {

      _elements.Add(element);

    }

 

    publicvoid Detach(Element element)

    {

      _elements.Remove(element);

    }

 

    publicvoid Accept(Visitor visitor)

    {

      foreach (Element elementin _elements)

      {

        element.Accept(visitor);

      }

    }

  }

}


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

4.      实例代码

// Visitor pattern -- Real World example

using System;

using System.Collections.Generic;

 

namespace DoFactory.GangOfFour.Visitor.RealWorld

{

  ///<summary>

  /// MainApp startup class for Real-World

  /// Visitor Design Pattern.

  ///</summary>

  classMainApp

  {

    ///<summary>

    /// Entry point into console application.

    ///</summary>

    staticvoid Main()

    {

      // Setup employee collection

      Employees e =new Employees();

      e.Attach(newClerk());

      e.Attach(newDirector());

      e.Attach(newPresident());

 

      // Employees are 'visited'

      e.Accept(newIncomeVisitor());

      e.Accept(newVacationVisitor());

 

      // Wait for user

      Console.ReadKey();

    }

  }

 

  ///<summary>

  /// The 'Visitor' interface

  ///</summary>

  interfaceIVisitor

  {

    void Visit(Element element);

  }

 

  ///<summary>

  /// A 'ConcreteVisitor' class

  ///</summary>

  classIncomeVisitor : IVisitor

  {

    publicvoid Visit(Element element)

    {

      Employee employee = elementas Employee;

 

      // Provide 10% pay raise

      employee.Income *= 1.10;

      Console.WriteLine("{0} {1}'s new income: {2:C}",

        employee.GetType().Name, employee.Name,

        employee.Income);

    }

  }

 

  ///<summary>

  /// A 'ConcreteVisitor' class

  ///</summary>

  classVacationVisitor : IVisitor

  {

    publicvoid Visit(Element element)

    {

      Employee employee = elementas Employee;

 

      // Provide 3 extra vacation days

      Console.WriteLine("{0} {1}'s new vacation days: {2}",

        employee.GetType().Name, employee.Name,

        employee.VacationDays);

    }

  }

 

  ///<summary>

  /// The 'Element' abstract class

  ///</summary>

  abstractclass Element

  {

    publicabstract void Accept(IVisitor visitor);

  }

 

  ///<summary>

  /// The 'ConcreteElement' class

  ///</summary>

  classEmployee : Element

  {

    privatestring _name;

    privatedouble _income;

    privateint _vacationDays;

 

    // Constructor

    public Employee(string name,double income,

      int vacationDays)

    {

      this._name = name;

      this._income = income;

      this._vacationDays = vacationDays;

    }

 

    // Gets or sets the name

    publicstring Name

    {

      get {return _name; }

      set { _name =value; }

    }

 

    // Gets or sets income

    publicdouble Income

    {

      get {return _income; }

      set { _income =value; }

    }

 

    // Gets or sets number of vacation days

    publicint VacationDays

    {

      get {return _vacationDays; }

      set { _vacationDays =value; }

    }

 

    publicoverride void Accept(IVisitor visitor)

    {

      visitor.Visit(this);

    }

  }

 

  ///<summary>

  /// The 'ObjectStructure' class

  ///</summary>

  classEmployees

  {

    privateList<Employee> _employees =new List<Employee>();

 

    publicvoid Attach(Employee employee)

    {

      _employees.Add(employee);

    }

 

    publicvoid Detach(Employee employee)

    {

      _employees.Remove(employee);

    }

 

    publicvoid Accept(IVisitor visitor)

    {

      foreach (Employee ein _employees)

      {

        e.Accept(visitor);

      }

      Console.WriteLine();

    }

  }

 

  // Three employee types

 

  classClerk : Employee

  {

    // Constructor

    public Clerk()

      : base("Hank", 25000.0, 14)

    {

    }

  }

 

  classDirector : Employee

  {

    // Constructor

    public Director()

      : base("Elly", 35000.0, 16)

    {

    }

  }

 

  classPresident : Employee

  {

    // Constructor

    public President()

      : base("Dick", 45000.0, 21)

    {

    }

  }

}


Output
Clerk Hank's new income: $27,500.00
Director Elly's new income: $38,500.00
President Dick's new income: $49,500.00

Clerk Hank's new vacation days: 14
Director Elly's new vacation days: 16
President Dick's new vacation days: 21

该文章来自:http://www.dofactory.com/Patterns/PatternVisitor.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值