員工集合接受不同訪問者處理:IncomeVisitor 調薪 10%,VacationVisitor 增加 3 天假期。
using System;
using System.Collections;
// 訪問者抽象介面
abstract class Visitor
{
public abstract void Visit(Element element);
}
// 具體訪問者:調薪
class IncomeVisitor : Visitor
{
public override void Visit(Element element)
{
Employee emp = (Employee)element;
emp.Income *= 1.10;
Console.WriteLine($"{emp.Name}'s new income: {emp.Income:C}");
}
}
// 具體訪問者:加假
class VacationVisitor : Visitor
{
public override void Visit(Element element)
{
Employee emp = (Employee)element;
emp.VacationDays += 3;
Console.WriteLine($"{emp.Name}'s new vacation days: {emp.VacationDays}");
}
}
// 元素抽象介面
abstract class Element
{
public abstract void Accept(Visitor visitor);
}
// 具體元素:員工
class Employee : Element
{
public string Name { get; set; }
public double Income { get; set; }
public int VacationDays { get; set; }
public Employee(string name, double income, int vacationDays)
{
Name = name; Income = income; VacationDays = vacationDays;
}
public override void Accept(Visitor visitor) => visitor.Visit(this);
}
// 物件結構:員工集合
class Employees
{
private ArrayList employees = new ArrayList();
public void Attach(Employee emp) => employees.Add(emp);
public void Detach(Employee emp) => employees.Remove(emp);
public void Accept(Visitor visitor)
{
foreach (Employee e in employees) e.Accept(visitor);
}
}
// 客戶端測試
public class VisitorApp
{
public static void Main()
{
Employees emps = new Employees();
emps.Attach(new Employee("Hank", 25000.0, 14));
emps.Attach(new Employee("Elly", 35000.0, 16));
emps.Attach(new Employee("Dick", 45000.0, 21));
IncomeVisitor v1 = new IncomeVisitor();
VacationVisitor v2 = new VacationVisitor();
emps.Accept(v1); // 所有員工調薪 10%
emps.Accept(v2); // 所有員工加 3 天假
}
}
Hank's new income: $27,500.00 Elly's new income: $38,500.00 Dick's new income: $49,500.00 Hank's new vacation days: 17 Elly's new vacation days: 19 Dick's new vacation days: 24
Employees.Accept(visitor) 遍歷集合employee.Accept(visitor) → 將自己傳給訪問者visitor.Visit(employee) → 執行具體操作**雙重分派本質**:操作取決於**訪問者類型**與**節點類型**雙重決定,而非單一方。