行为型设计模式——访问者模式
访问者模式是一种行为型设计模式,表示一个作用于某对象结构中的各元素的操作。它允许在不改变各元素的类的前提下定义作用于这些元素的新操作(通过将数据结构和操作逻辑解耦,实现在不修改元素类的前提下扩展功能)
适用于
①一个对象结构包含很多类的对象,它们有不同的接口,而用户想对这些对象实施一些依赖于其具体类的操作。
②需要对一个结构中的对象进行很多不同的并且不相关的操作,而又想避免这些操作“污染”这些对象的类。Visitor使得用户可以将相关的操作集中起来定义在一个类中。当该对象结构被很多应用共享时,用Visitor模式让每个应用仅包含需要用到的操作。
③定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口,这可能需要很大的代价。如果对象结构类经常变化,那么可能还是在这些类中定义这些操作较好。
类图如下

1 internal class Program 2 { 3 static void Main(string[] args) 4 { 5 ShoppingCart cart = new ShoppingCart(); 6 7 cart.Add(new Book(8)); 8 cart.Add(new Book(12.5)); 9 cart.Add(new Book(20)); 10 //计算总价 11 double total = cart.CalulatePrice(); 12 13 Console.WriteLine(total); 14 15 } 16 }
1 /// <summary> 2 /// 元素(Element)接口类,接收访问者 3 /// </summary> 4 internal interface Item 5 { 6 public void Accept(Visitor visitor); 7 public double GetPrice(); 8 }
1 internal class Book : Item 2 { 3 private double Price; 4 5 public Book(double price) 6 { 7 this.Price = price; 8 } 9 10 public void Accept(Visitor visitor) 11 { 12 visitor.Visit(this);//传递自己 13 } 14 15 public double GetPrice() 16 { 17 return Price; 18 } 19 }
1 /// <summary> 2 /// 访问者接口,所有要访问的对象方法都放在这里 3 /// </summary> 4 internal interface Visitor 5 { 6 //访问Book元素类 7 public void Visit(Book book); 8 //可以定义访问其他元素方法 9 }
1 internal class Cashier : Visitor 2 { 3 private double TotalPrice; 4 //访问具体的元素,主要访问具体的操作 5 public void Visit(Book book) 6 { 7 //访问Book类型的物品价格并累加,超过十元打8折 8 if (book.GetPrice() < 10.0) 9 { 10 TotalPrice += book.GetPrice(); 11 } 12 else 13 { 14 TotalPrice += book.GetPrice() * 0.8; 15 } 16 } 17 18 public double GetTotalPrice() 19 { 20 return TotalPrice; 21 } 22 }
1 /// <summary> 2 /// 对象结构类,用来管理所有Item列表 3 /// </summary> 4 internal class ShoppingCart 5 { 6 private List<Item> Items = new List<Item>(); 7 8 public void Add(Item item) 9 { 10 Items.Add(item); 11 } 12 13 public double CalulatePrice() 14 { 15 Cashier visitor = new Cashier(); 16 17 foreach (var item in Items) 18 { 19 //接收具体访问者 20 item.Accept(visitor); 21 } 22 23 double total = visitor.GetTotalPrice(); 24 return total; 25 } 26 }

浙公网安备 33010602011771号