访问者(Visitor Pattern )模式

主要用途是对聚集采取某种操作,统一执行。

访问者模式适用于数据结构相对未定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化。

比如雇员对象,我们先只有名称、年龄、工资这些属性,可以先定义访问者类来分离结构和操作

 

 

participants

    The classes and/or objects participating in this pattern are:

  • Visitor  (Visitor)
    • declares a Visit operation for each class of ConcreteElement in the object structure. The operation's name and signature identifies the class that sends the Visit request to the visitor. That lets the visitor determine the concrete class of the element being visited. Then the visitor can access the elements directly through its particular interface
  • ConcreteVisitor  (IncomeVisitor, VacationVisitor)
    • implements each operation declared by Visitor. Each operation implements a fragment of the algorithm defined for the corresponding class or object in the structure. ConcreteVisitor provides the context for the algorithm and stores its local state. This state often accumulates results during the traversal of the structure.
  • Element  (Element)
    • defines an Accept operation that takes a visitor as an argument.
  • ConcreteElement  (Employee)
    • implements an Accept operation that takes a visitor as an argument
  • ObjectStructure  (Employees)
    • can enumerate its elements
    • may provide a high-level interface to allow the visitor to visit its elements
    • may either be a Composite (pattern) or a collection such as a list or a set

 

 

 

using System;

using System.Collections.Generic;

 

namespace DoFactory.GangOfFour.Visitor.RealWorld

{

  ///

  /// MainApp startup class for Real-World

  /// Visitor Design Pattern.

  ///

  class MainApp

  {

    ///

    /// Entry point into console application.

    ///

    static void Main()

    {

      // Setup employee collection

      Employees e = new Employees();

      e.Attach(new Clerk());

      e.Attach(new Director());

      e.Attach(new President());

 

      // Employees are 'visited'

      e.Accept(new IncomeVisitor());

      e.Accept(new VacationVisitor());

 

      // Wait for user

      Console.ReadKey();

    }

  }

 

  ///

  /// The 'Visitor' interface

  ///

  interface IVisitor

  {

    void Visit(Element element);

  }

 

  ///

  /// A 'ConcreteVisitor' class

  ///

  class IncomeVisitor : IVisitor

  {

    public void Visit(Element element)

    {

      Employee employee = element as 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);

    }

  }

 

  ///

  /// A 'ConcreteVisitor' class

  ///

  class VacationVisitor : IVisitor

  {

    public void Visit(Element element)

    {

      Employee employee = element as Employee;

 

      // Provide 3 extra vacation days

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

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

        employee.VacationDays);

    }

  }

 

  ///

  /// The 'Element' abstract class

  ///

  abstract class Element

  {

    public abstract void Accept(IVisitor visitor);

  }

 

  ///

  /// The 'ConcreteElement' class

  ///

  class Employee : Element

  {

    private string _name;

    private double _income;

    private int _vacationDays;

 

    // Constructor

    public Employee(string name, double income,

      int vacationDays)

    {

      this._name = name;

      this._income = income;

      this._vacationDays = vacationDays;

    }

 

    // Gets or sets the name

    public string Name

    {

      get { return _name; }

      set { _name = value; }

    }

 

    // Gets or sets income

    public double Income

    {

      get { return _income; }

      set { _income = value; }

    }

 

    // Gets or sets number of vacation days

    public int VacationDays

    {

      get { return _vacationDays; }

      set { _vacationDays = value; }

    }

 

    public override void Accept(IVisitor visitor)

    {

      visitor.Visit(this);

    }

  }

 

  ///

  /// The 'ObjectStructure' class

  ///

  class Employees

  {

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

 

    public void Attach(Employee employee)

    {

      _employees.Add(employee);

    }

 

    public void Detach(Employee employee)

    {

      _employees.Remove(employee);

    }

 

    public void Accept(IVisitor visitor)

    {

      foreach (Employee e in _employees)

      {

        e.Accept(visitor);

      }

      Console.WriteLine();

    }

  }

 

  // Three employee types

 

  class Clerk : Employee

  {

    // Constructor

    public Clerk()

      : base("Hank", 25000.0, 14)

    {

    }

  }

 

  class Director : Employee

  {

    // Constructor

    public Director()

      : base("Elly", 35000.0, 16)

    {

    }

  }

 

  class President : Employee

  {

    // Constructor

    public President()

      : base("Dick", 45000.0, 21)

    {

    }

  }

}

你可能感兴趣的:(访问者(Visitor Pattern )模式)