模式介绍
访问者模式允许我们通过将该操作表示为对象来操作对象。 因此,我们可以对所述对象进行操作而不改变那些对象的类或定义。
示例
我们有一家全市最好的餐馆,各种表现良好。领导决定给员工加薪放假,但由于某些原因,表示员工的类不能被修改。
员工类:
/// <summary> /// The Element abstract class. All this does is define an Accept operation, which needs to be implemented by any class that can be visited. /// </summary> abstract class Element { public abstract void Accept(IVisitor visitor); } /// <summary> /// The ConcreteElement class, which implements all operations defined by the Element. /// </summary> class Employee : Element { public string Name { get; set; } public double AnnualSalary { get; set; } public int PaidTimeOffDays { get; set; } public Employee(string name, double annualSalary, int paidTimeOffDays) { Name = name; AnnualSalary = annualSalary; PaidTimeOffDays = paidTimeOffDays; } public override void Accept(IVisitor visitor) { visitor.Visit(this); } }
访问者接口:
/// <summary> /// The Visitor interface, which declares a Visit operation for each ConcreteVisitor to implement. /// </summary> interface IVisitor { void Visit(Element element); }
具体的访问者:
/// <summary> /// A Concrete Visitor class. /// </summary> class IncomeVisitor : IVisitor { public void Visit(Element element) { Employee employee = element as Employee; // We've had a great year, so 10% pay raises for everyone! employee.AnnualSalary *= 1.10; Console.WriteLine("{0} {1}'s new income: {2:C}", employee.GetType().Name, employee.Name, employee.AnnualSalary); } } /// <summary> /// A Concrete Visitor class /// </summary> class PaidTimeOffVisitor : IVisitor { public void Visit(Element element) { Employee employee = element as Employee; // And because you all helped have such a great year, all my employees get three extra paid time off days each! employee.PaidTimeOffDays += 3; Console.WriteLine("{0} {1}'s new vacation days: {2}", employee.GetType().Name, employee.Name, employee.PaidTimeOffDays); } }
新的组合类:
/// <summary> /// The Object Structure class, which is a collection of Concrete Elements. This could be implemented using another pattern such as Composite. /// </summary> 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(); } } class LineCook : Employee { public LineCook() : base("Dmitri", 32000, 7) { } } class HeadChef : Employee { public HeadChef() : base("Jackson", 69015, 21) { } } class GeneralManager : Employee { public GeneralManager() : base("Amanda", 78000, 24) { } }
客户端调用:
static void Main(string[] args) { // Who are my employees? Employees e = new Employees(); e.Attach(new LineCook()); e.Attach(new HeadChef()); e.Attach(new GeneralManager()); // Employees are visited, giving them 10% raises and 3 extra paid time off days. e.Accept(new IncomeVisitor()); e.Accept(new PaidTimeOffVisitor()); Console.ReadKey(); }
总结
访问者模式允许我们修改对象现有的实例而不修改原有类。所有这些实例都需要接受访问者对象并处理其内容。
源代码
https://github.com/exceptionnotfound/DesignPatterns/tree/master/Visitor
原文
https://www.exceptionnotfound.net/visitor-the-daily-design-pattern/
来源:https://www.cnblogs.com/talentzemin/p/9981613.html