编辑
2025-09-28
C#
00

目录

摘要
正文
应用场景
示例:购物车结算

摘要

访问者模式是一种行为型设计模式,它允许你在不修改对象结构的情况下定义新的操作。通过将操作封装在访问者对象中,可以在不改变对象结构的情况下,为对象结构中的每个元素提供新的操作。

正文

应用场景

访问者模式适用于以下情况:

  • 当一个对象结构包含多种类型的对象,并且希望对这些对象进行不同的操作时。
  • 当需要为一个对象结构添加新的操作,但不希望修改每个对象的类时。
  • 当对象结构中的对象类很少发生变化,但经常需要执行不同的操作时。

示例:购物车结算

假设我们正在开发一个在线购物系统,需要计算购物车中商品的总金额。商品分为三类:图书、电子产品和服装。不同类型的商品有不同的计算方式。

首先,我们创建一个访问者接口IShoppingCartVisitor,定义了访问不同类型商品的方法:

C#
public interface IShoppingCartVisitor { double Visit(Book book); double Visit(Electronics electronics); double Visit(Clothing clothing); }

然后,我们创建一个具体访问者类ShoppingCartVisitor,实现了对不同类型商品的访问操作:

C#
public class ShoppingCartVisitor : IShoppingCartVisitor { public double Visit(Book book) { Console.WriteLine($"Book - Price: {book.Price}, Discounted Price: {book.Price}"); return book.Price; } public double Visit(Electronics electronics) { double discountedPrice = electronics.Price * (1 - electronics.Discount); Console.WriteLine($"Electronics - Price: {electronics.Price}, Discounted Price: {discountedPrice}"); return discountedPrice; } public double Visit(Clothing clothing) { Console.WriteLine($"Clothing - Price: {clothing.Price}, Discounted Price: {clothing.Price}"); return clothing.Price; } }

接下来,我们创建一个元素接口IItem,定义了接受访问者对象的方法:

C#
public interface IItem { double Accept(IShoppingCartVisitor visitor); }

然后,我们创建三个具体元素类,分别实现了元素接口:

C#
public class Book : IItem { public string Title { get; set; } public double Price { get; set; } public double Accept(IShoppingCartVisitor visitor) { return visitor.Visit(this); } } public class Electronics : IItem { public string Name { get; set; } public double Price { get; set; } public double Discount { get; set; } public double Accept(IShoppingCartVisitor visitor) { return visitor.Visit(this); } } public class Clothing : IItem { public string Type { get; set; } public double Price { get; set; } public double Accept(IShoppingCartVisitor visitor) { return visitor.Visit(this); } }

最后,我们创建一个对象结构类ShoppingCart,它包含了一组商品,并提供了遍历商品的方法:

C#
public class ShoppingCart { private List<IItem> _items = new List<IItem>(); public void AddItem(IItem item) { _items.Add(item); } public double CalculateTotal(IShoppingCartVisitor visitor) { double total = 0; foreach (var item in _items) { total += item.Accept(visitor); } return total; } }

现在,我们可以在客户端代码中使用访问者模式来计算购物车的总金额:

C#
static void Main(string[] args) { var shoppingCart = new ShoppingCart(); shoppingCart.AddItem(new Book { Title = "Design Patterns", Price = 50 }); shoppingCart.AddItem(new Electronics { Name = "Smartphone", Price = 500, Discount = 0.1 }); shoppingCart.AddItem(new Clothing { Type = "Shirt", Price = 80 }); shoppingCart.AddItem(new Clothing { Type = "Pants", Price = 120 }); var visitor = new ShoppingCartVisitor(); double total = shoppingCart.CalculateTotal(visitor); Console.WriteLine($"Total amount: {total}"); }

image.png

通过使用访问者模式,我们可以根据不同的商品类型,计算出购物车的总金额,而无需修改购物车类的代码。访问者模式可以用于各种场景,例如编译器中的语法分析、文档解析等。

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!