访问者模式是一种行为型设计模式,它允许你在不修改对象结构的情况下定义新的操作。通过将操作封装在访问者对象中,可以在不改变对象结构的情况下,为对象结构中的每个元素提供新的操作。
访问者模式适用于以下情况:
假设我们正在开发一个在线购物系统,需要计算购物车中商品的总金额。商品分为三类:图书、电子产品和服装。不同类型的商品有不同的计算方式。
首先,我们创建一个访问者接口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}");
}
通过使用访问者模式,我们可以根据不同的商品类型,计算出购物车的总金额,而无需修改购物车类的代码。访问者模式可以用于各种场景,例如编译器中的语法分析、文档解析等。
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!