implement a visitor pattern for basket in csharp

The Visitor pattern is a design pattern that allows adding new behaviors to an existing class without modifying it. It separates the data structure and the algorithms to work on this data structure. In this answer, we will see how to implement the Visitor pattern for a shopping basket in C#.

Let's say that we have a shopping basket that contains a list of products, and we want to calculate the total price of the basket. We can use the Visitor pattern to calculate the total price of the basket without modifying the basket class.

We start by defining an interface for our visitor:

main.cs
public interface IVisitor
{
    void Visit(Product product);
}
63 chars
5 lines

This interface defines a Visit method that takes a Product object as a parameter. The Visit method will be implemented by the visitor to perform some operation on the Product object.

We then define the Product class:

main.cs
public class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
    public void Accept(IVisitor visitor)
    {
        visitor.Visit(this);
    }
}
183 chars
10 lines

The Product class has a Name and Price property, and an Accept method that takes a visitor as a parameter. The Accept method calls the Visit method on the visitor and passes itself as a parameter.

We can now define our shopping basket class:

main.cs
public class ShoppingBasket
{
    public List<Product> Products { get; set; }
    public void Accept(IVisitor visitor)
    {
        foreach (var product in Products)
        {
            product.Accept(visitor);
        }
    }
}
232 chars
12 lines

The ShoppingBasket class has a List of Products and an Accept method that takes a visitor as a parameter. The Accept method loops through the list of Products and calls the Accept method on each of them, passing the visitor as a parameter.

Finally, we can create our visitor class to calculate the total price of the basket:

main.cs
public class TotalPriceVisitor : IVisitor
{
    public decimal TotalPrice { get; set; }
    public void Visit(Product product)
    {
        TotalPrice += product.Price;
    }
}
178 chars
9 lines

The TotalPriceVisitor class implements the IVisitor interface and has a TotalPrice property that will hold the total price of the basket. The Visit method implementation adds the price of the product to the TotalPrice property.

We can now use the Visitor pattern to calculate the total price of the basket:

main.cs
var basket = new ShoppingBasket();
basket.Products = new List<Product>
{
    new Product { Name = "Product 1", Price = 10 },
    new Product { Name = "Product 2", Price = 20 }
};
var totalPriceVisitor = new TotalPriceVisitor();
basket.Accept(totalPriceVisitor);
var totalPrice = totalPriceVisitor.TotalPrice;
309 chars
10 lines

We create a shopping basket with two products, create a TotalPriceVisitor object, pass it to the Accept method of the basket, and finally retrieve the total price from the TotalPrice property of the visitor object.

This is how the Visitor pattern can be used to add new behaviors to an existing class without modifying it.

gistlibby LogSnag