# Software Design Patterns: Behavioural

*2024-02-14*

> Behavioural design patterns by Gang of Four


*This post continues [my series]({{< relref "software-design-patterns" >}}) on the Gang of Four design patterns. Having covered the [creational]({{< relref "software-design-patterns-creational" >}}) and [structural]({{< relref "software-design-patterns-structural" >}}) patterns previously, this post turns to the behavioural patterns – those concerned with how objects communicate with one another and how responsibilities are distributed between them. All the accompanying source code for this series can be found in my design patterns repository on GitHub:*

[maceage/design-patterns](https://github.com/maceage/design-patterns)

Each pattern has its own console application project, so you can clone the repository and step through the code as you read.

The behavioural patterns covered in this post are:

- [Chain of Responsibility pattern](#chain-of-responsibility-pattern)
- [Command pattern](#command-pattern)
- [Event Aggregator pattern](#event-aggregator-pattern)
- [Interpreter pattern](#interpreter-pattern)
- [Iterator pattern](#iterator-pattern) ([Iterator example](#iterator-iterator-example), [Tree example](#iterator-tree-example))
- [Mediator pattern](#mediator-pattern)
- [Memento pattern](#memento-pattern)
- [Null Object pattern](#null-object-pattern)
- [Observer pattern](#observer-pattern) ([Traditional](#observer-traditional-pattern), [IObserver](#observer-iobserver-pattern), [EventDelegate](#observer-event-delegate))
- [Rules pattern](#rules-pattern)
- [State pattern](#state-pattern)
- [Strategy pattern](#strategy-pattern)
- [Template Method pattern](#template-method-pattern)
- [Visitor pattern](#visitor-pattern)

---

## [Chain of Responsibility pattern](https://github.com/maceage/design-patterns/tree/master/ChainOfResponsibilityPattern){#chain-of-responsibility-pattern}

The Chain of Responsibility pattern decouples the sender of a request from the object that ultimately handles it. Rather than the sender knowing exactly which object should process a request, the request is passed along a chain of potential handlers until one of them takes responsibility for it. The easiest way to understand this pattern is with a real-world example using the expense workflow within an organisation. In this example, there is an `ExpenseReport` class that represents an expense report with a constructor parameter that takes in the expense amount:

```csharp
public class ExpenseReport : IExpenseReport
{
    public ExpenseReport(decimal total)
    {
        Total = total;
    }

    public decimal Total
    {
        get;
    }
}
```

There are four levels of approval - Manager, Director, Vice President and President - all instances of the `ExpenseHandler` class:

```csharp
private static ExpenseHandler CreateReportingChain()
{
    ExpenseHandler manager = new ExpenseHandler(new Employee("Manager", decimal.Zero));
    ExpenseHandler director = new ExpenseHandler(new Employee("Director", new decimal(1000)));
    ExpenseHandler vicePresident = new ExpenseHandler(new Employee("Vice President", new decimal(5000)));
    ExpenseHandler president = new ExpenseHandler(new Employee("President", new decimal(20000)));

    manager.RegisterNext(director);
    director.RegisterNext(vicePresident);
    vicePresident.RegisterNext(president);

    return manager;
}
```

The `ExpenseHandler` class itself has an `Approve()` and `RegisterNext` methods. `Approve()` is used to approve the expense report, while `RegisterNext` is used to register the next handler in the chain:

```csharp
public class ExpenseHandler : IExpenseHandler
{
    private readonly IExpenseApprover _approver;
    private IExpenseHandler _next;

    public ExpenseHandler(IExpenseApprover expenseApprover)
    {
        _approver = expenseApprover;
        _next = EndOfChainExpenseHandler.Instance;
    }

    public ApprovalResponse Approve(IExpenseReport expenseReport)
    {
        ApprovalResponse response = _approver.ApproveExpense(expenseReport);

        if (response == ApprovalResponse.BeyondApprovalLimit)
        {
            return _next.Approve(expenseReport);
        }

        return response;
    }

    public void RegisterNext(IExpenseHandler next)
    {
        _next = next;
    }
}
```

Whether an instance of the `Employee` class can approve the expense report depends on their level of authority. For example, a Manager can approve expenses up to a certain amount, while a Director can approve expenses up to a higher amount, and so on. This is achieved through the `approvalLimit` parameter in the `Employee` class constructor:

```csharp
public class Employee : IExpenseApprover
{
    private readonly decimal _approvalLimit;

    public Employee(string name, decimal approvalLimit)
    {
        Name = name;
        _approvalLimit = approvalLimit;
    }

    public string Name { get; private set; }

    public ApprovalResponse ApproveExpense(IExpenseReport expenseReport)
    {
        return expenseReport.Total > _approvalLimit
                ? ApprovalResponse.BeyondApprovalLimit
                : ApprovalResponse.Approved;
    }
}
```

An instance of an `IExpenseReport` is passed to the `ApproveExpense` method of the `Employee` class, which then returns an `ApprovalResponse` indicating whether the expense report was approved or not. Requests of increasing amounts exercise the whole chain – a 500 request is approved by the Director, a 1,250 request by the Vice President, a 5,500 request by the President, and a 25,000 request falls off the end of the chain and is denied:

```csharp
private static void RequestCheapExpense(ExpenseHandler manager)
{
    IExpenseReport cheapExpenseReport = new ExpenseReport(500);
    ApprovalResponse cheapExpenseResponse = manager.Approve(cheapExpenseReport);
    Console.WriteLine("The request for {0} was {1}.", cheapExpenseReport.Total, cheapExpenseResponse);
    // The request for 500 was Approved.
}

private static void RequestMildlyCheapExpense(ExpenseHandler manager)
{
    IExpenseReport mildlyCheapExpenseReport = new ExpenseReport(1250);
    ApprovalResponse mildlyCheapExpenseResponse = manager.Approve(mildlyCheapExpenseReport);
    Console.WriteLine("The request for {0} was {1}.", mildlyCheapExpenseReport.Total, mildlyCheapExpenseResponse);
    // The request for 1250 was Approved. (amended: output comments corrected to match each request)
}

private static void RequestRatherExpensiveExpense(ExpenseHandler manager)
{
    IExpenseReport ratherExpensiveExpenseReport = new ExpenseReport(5500);
    ApprovalResponse ratherExpensiveExpenseResponse = manager.Approve(ratherExpensiveExpenseReport);
    Console.WriteLine("The request for {0} was {1}.", ratherExpensiveExpenseReport.Total, ratherExpensiveExpenseResponse);
    // The request for 5500 was Approved.
}

private static void RequestStupidlyExpensiveExpense(ExpenseHandler manager)
{
    IExpenseReport stupidlyExpensiveExpenseReport = new ExpenseReport(25000);
    ApprovalResponse stupidlyExpensiveResponse = manager.Approve(stupidlyExpensiveExpenseReport);
    Console.WriteLine("The request for {0} was {1}.", stupidlyExpensiveExpenseReport.Total, stupidlyExpensiveResponse);
    // The request for 25000 was Denied. (25000 exceeds the President's 20000 limit, so the
    // request reaches the EndOfChainExpenseHandler)
}
```

**Benefits of the Chain of Responsibility pattern:**

- **Decoupling** – the sender of a request does not need to know which object will ultimately handle it.
- **Flexibility** – new handlers can be added to (or removed from) the chain without changing the code that issues requests.
- **Single responsibility** – each handler only contains the logic for its own level of authority, making handlers easy to test in isolation.
- **Configurable processing order** – the chain itself can be composed at runtime rather than hard-coded into the caller.

In short, the Chain of Responsibility pattern is a good fit whenever a request needs to travel through a sequence of potential handlers, such as approval workflows, logging pipelines or middleware-style processing.

## [Command pattern](https://github.com/maceage/design-patterns/tree/master/CommandPattern){#command-pattern}

The Command pattern encapsulates a request as an object, thereby allowing you to parameterise clients with different requests, queue or log requests, and support undoable operations. Crucially, it separates the object that *invokes* an operation from the object that *knows how to perform* it. In this example, there are four command classes - `DiveCommand`, `LaunchNukeCommand`, `MakeItSoCommand` and `NotFoundCommand`:

```csharp
// DiveCommand
public class DiveCommand : ICommand, ICommandFactory
{
    public int NumberOfMetres { get; set; }

    public string CommandName
    {
        get { return "Dive"; }
    }

    public string Description
    {
        get { return "Dive [NumberOfMetres]"; }
    }

    public void Execute()
    {
        Console.WriteLine("Diving to {0} metres...", NumberOfMetres);
    }

    public ICommand MakeCommand(string[] arguments)
    {
        return new DiveCommand
        {
            NumberOfMetres = int.Parse(arguments[1])
        };
    }
}

// LaunchNukeCommand
public class LaunchNukeCommand : ICommand, ICommandFactory
{
    public int NumberOfNukes { get; set; }

    public string CommandName
    {
        get
        {
            return "LaunchNuke";
        }
    }

    public string Description
    {
        get
        {
            return "LaunchNuke [NumberOfNukes]";
        }
    }

    public void Execute()
    {
        for (int i = 0; i < NumberOfNukes; i++)
        {
            Console.WriteLine("Launching nuke {0}", i + 1);
        }
    }

    public ICommand MakeCommand(string[] arguments)
    {
        return new LaunchNukeCommand
        {
            NumberOfNukes = int.Parse(arguments[1])
        };
    }
}

// MakeItSoCommand
public class MakeItSoCommand : ICommand, ICommandFactory
{
    public string CommandName
    {
        get { return "MakeItSo"; }
    }

    public string Description
    {
        get { return CommandName; }
    }

    public void Execute()
    {
        Console.WriteLine("Made it so!");
    }

    public ICommand MakeCommand(string[] arguments)
    {
        return new MakeItSoCommand();
    }
}

// NotFoundCommand
public class NotFoundCommand : ICommand
{
    public string Name { get; set; }

    public void Execute()
    {
        Console.WriteLine("Command not found: " + Name);
    }
}
```

The `CommandParser` class has an `IEnumerable<ICommandFactory>` of `_availableCommands` which is populated by the constructor:

```csharp
public class CommandParser
{
    private readonly IEnumerable<ICommandFactory> _availableCommands;

    public CommandParser(IEnumerable<ICommandFactory> availableCommands)
    {
        _availableCommands = availableCommands;
    }

    internal ICommand ParseCommand(string[] args)
    {
        var requestedCommandName = args[0];

        var command = FindRequestedCommand(requestedCommandName);

        if (command == null)
        {
            return new NotFoundCommand { Name = requestedCommandName };
        }

        return command.MakeCommand(args);
    }

    private ICommandFactory FindRequestedCommand(string commandName)
    {
        return _availableCommands
            .FirstOrDefault(cmd => cmd.CommandName == commandName);
    }
}
```

A command is then invoked by the `ParseCommand` method which finds the requested command in the list if it exists and then invokes the `ICommandFactory.MakeCommand()` method. This method then returns the newly created command to the calling method, which then invokes the `ICommand.Execute()` method, implemented by the respective command class implementation.

```csharp
public static void Main(string[] args)
{
    var availableCommands = GetAvailableCommands();

    if (args.Length == 0)
    {
        PrintUsage(availableCommands);
        return;
    }

    var parser = new CommandParser(availableCommands);
    var command = parser.ParseCommand(args);

    command.Execute();
}

private static IEnumerable<ICommandFactory> GetAvailableCommands()
{
    return new ICommandFactory[]
        {
            new DiveCommand(),
            new LaunchNukeCommand(),
            new MakeItSoCommand()
        };
}

private static void PrintUsage(IEnumerable<ICommandFactory> availableCommands)
{
    Console.WriteLine("Usage: CommandPattern CommandName Arguments");
    Console.WriteLine("Commands:");

    foreach (var command in availableCommands)
    {
        Console.WriteLine("  {0}", command.Description);
    }
}
```

**Benefits of the Command pattern are:**

- **Separation of concerns** – the invoker knows nothing about how a command is carried out, only that it can be executed.
- **Extensibility** – new commands can be added without touching existing parsing or dispatch logic.
- **Composability** – because commands are objects, they can be queued, logged, scheduled, serialised or grouped into macros.
- **Graceful degradation** - unknown commands can be handled uniformly, as shown by the `NotFoundCommand`.

In short, the Command pattern shines wherever you need to turn actions into first-class objects – from menu systems and job queues to undo/redo stacks.

## [Event Aggregator pattern](https://github.com/maceage/design-patterns/tree/master/EventAggregatorPattern){#event-aggregator-pattern}

Quite possibly one of the more complex patterns, the Event Aggregator pattern is used to decouple publishers and subscribers. Rather than components holding direct references to each other in order to raise notifications, they publish and subscribe through a central aggregator, which routes events to any interested parties. In this example, the `SimpleEventAggregator` class has a `Dictionary<Type, List<WeakReference>>` of `_eventSubscriberLists`:

```csharp
public class SimpleEventAggregator : IEventAggregator
{
    private readonly Dictionary<Type, List<WeakReference>> _eventSubscriberLists = new Dictionary<Type, List<WeakReference>>();
    private readonly object _lock = new object();

    public void Subscribe(object subscriber)
    {
        lock (_lock)
        {
            var subscriberTypes =
                subscriber.GetType().GetInterfaces().Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ISubscriber<>));

            var weakReference = new WeakReference(subscriber);
            foreach (var subscriberType in subscriberTypes)
            {
                var subscribers = GetSubscribers(subscriberType);
                subscribers.Add(weakReference);
            }
        }
    }

    public void Publish<TEvent>(TEvent eventToPublish)
    {
        var subscriberType = typeof(ISubscriber<>).MakeGenericType(typeof(TEvent));
        var subscribers = GetSubscribers(subscriberType);
        List<WeakReference> subscribersToRemove = new List<WeakReference>();

        foreach (var weakSubscriber in subscribers)
        {
            if (weakSubscriber.IsAlive)
            {
                var subscriber = (ISubscriber<TEvent>)weakSubscriber.Target;
                var syncContext = SynchronizationContext.Current ?? new SynchronizationContext();

                syncContext.Post(s => subscriber.OnEvent(eventToPublish), null);
            }
            else
            {
                subscribersToRemove.Add(weakSubscriber);
            }
        }

        if (subscribersToRemove.Any())
        {
            lock (_lock)
            {
                foreach (var remove in subscribersToRemove)
                {
                    subscribers.Remove(remove);
                }
            }
        }
    }

    private List<WeakReference> GetSubscribers(Type subscriberType)
    {
        List<WeakReference> subscribers;

        lock (_lock)
        {
            var found = _eventSubscriberLists.TryGetValue(subscriberType, out subscribers);
            if (!found)
            {
                subscribers = new List<WeakReference>();
                _eventSubscriberLists.Add(subscriberType, subscribers);
            }
        }

        return subscribers;
    }
}
```

A subscriber is then added to the list via the `Subscribe` method which adds the subscriber to the list if it implements the `ISubscriber<T>` interface.

Events on orders are represented by the `OrderCreated`, `OrderSaved` and `OrderSelected` classes:

```csharp
public class OrderCreated
{
    public Order Order { get; set; }
}

public class OrderSaved
{
    public Order Order { get; set; }
}

public class OrderSelected
{
    public Order Order { get; set; }
}
```

Whenever the `OrdersListView.SelectOrder()` method is invoked, the `IEventAggregator.Publish()` method is invoked:

```csharp
public class OrdersListView
{
    private IList<Order> _orders;

    public IEventAggregator EventAggregator { get; set; }

    public void SelectOrder(int orderNumber)
    {
        Order order = _orders.SingleOrDefault(o => o.OrderNumber == orderNumber);

        if (order != null)
        {
            EventAggregator.Publish(new OrderSelected { Order = order });
        }
    }

    public void SetOrders(IList<Order> orders)
    {
        _orders = orders;
    }
}
```

This, in turn, retrieves all the subscribers, checks the `WeakReference.IsAlive` property to determine whether the referenced object has not been garbage collected, and then uses [`SynchronizationContext.Post()`](https://learn.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/executioncontext-synchronizationcontext) to invoke the `ISubscriber.OnEvent()` method, activating any subscribers - in this case `OrderDetailView` and `OrderHistoryView`:

```csharp
// OrderDetailView
public class OrderDetailView : ISubscriber<OrderSelected>, ISubscriber<OrderSaved>
{
    public OrderDetailView(IEventAggregator eventAggregator)
    {
        eventAggregator.Subscribe(this);
    }

    public void OnEvent(OrderSelected e)
    {
        Console.WriteLine("OrderDetailView -> OrderSelected Event -> {0}", e.Order);
    }

    public void OnEvent(OrderSaved e)
    {
        Console.WriteLine("OrderSavedView -> OrderSaved Event -> {0}", e.Order);
    }
}

// OrderHistoryView
public class OrderHistoryView : ISubscriber<OrderSelected>, ISubscriber<OrderSaved>
{
    public OrderHistoryView(IEventAggregator eventAggregator)
    {
        eventAggregator.Subscribe(this);
    }

    public void OnEvent(OrderSelected e)
    {
        Console.WriteLine("OrderHistoryView -> OrderSelected Event -> {0}", e.Order);
    }

    public void OnEvent(OrderSaved e)
    {
        Console.WriteLine("OrderHistoryView -> OrderSaved Event -> {0}", e.Order);
    }
}
```

These are initially wired up to the `SimpleEventAggregator` via their respective constructor methods:

```csharp
_eventAggregator = new SimpleEventAggregator();

_orderListView = new OrdersListView();

_orderDetailView = new OrderDetailView(_eventAggregator);
_orderHistoryView = new OrderHistoryView(_eventAggregator);
_orderView = new OrderView(_eventAggregator);

var orders = GenerateOrders();
_orderListView.EventAggregator = _eventAggregator;
_orderListView.SetOrders(orders);
```

**Benefits of the Event Aggregator pattern:**

- **Loose coupling** – publishers and subscribers never reference each other directly; they only know about the aggregator.
- **Memory safety** - the use of `WeakReference` means subscribers that are garbage collected are silently dropped rather than leaking.
- **Centralised eventing** – the routing logic lives in one place rather than being scattered across every component.
- **Cross-thread delivery** - dispatching via `SynchronizationContext` allows events to arrive on the correct thread for UI consumers.

In short, the Event Aggregator pattern is invaluable in complex applications – particularly UI-heavy ones such as [WPF](https://learn.microsoft.com/en-us/dotnet/desktop/wpf/overview/) or [Prism](https://learn.microsoft.com/en-us/windows/arm/apps-on-arm-x86-emulation) applications – where many components need to react to events without becoming entangled with each other.

## [Interpreter pattern](https://github.com/maceage/design-patterns/tree/master/InterpreterPattern){#interpreter-pattern}

The Interpreter pattern is used to simplify complex expressions by breaking them down into smaller, more manageable parts. A grammar is represented as a hierarchy of expression classes, each of which knows how to interpret its own piece of the language, and evaluating the full expression becomes a matter of recursing through that hierarchy. It is often used in compilers, rule engines and query languages to parse and evaluate expressions.

In this example we have a `CondimentList` and an `IngredientList`:

```csharp
// CondimentList
public class CondimentList : IExpression
{
    private readonly List<ICondiment> _condiments;

    public CondimentList(List<ICondiment> condiments)
    {
        _condiments = condiments;
    }

    public void Interpret(Context context)
    {
        foreach (var condiment in _condiments)
        {
            condiment.Interpret(context);
        }
    }
}

// IngredientList
public class IngredientList : IExpression
{
    private readonly List<IIngredient> _ingredients;

    public IngredientList(List<IIngredient> ingredients)
    {
        _ingredients = ingredients;
    }

    public void Interpret(Context context)
    {
        foreach (var ingredient in _ingredients)
        {
            ingredient.Interpret(context);
        }
    }
}
```

An `IBread` interface that extends the `IExpression` interface with two concrete implementations - `WhiteBread` and `WheatBread`:

```csharp
// IExpression
public interface IExpression
{
    void Interpret(Context context);
}

// IBread
public interface IBread : IExpression
{
}

// WhiteBread
public class WhiteBread : IBread
{
    public void Interpret(Context context)
    {
        context.Output += string.Format(" {0} ", "White-IBread");
    }
}

// WheatBread
public class WheatBread : IBread
{
    public void Interpret(Context context)
    {
        context.Output += string.Format(" {0} ", "Wheat-IBread");
    }
}
```

Each of these classes implements the `IExpression` interface which has one method: `Interpret()` which takes a parameter of type `Context`.

All of this is then glued together with a `Sandwich` class which itself implements the `IExpression` interface and has a corresponding `Interpret()` method:

```csharp
// BNF:
// <sandwhich> ::= <bread> <condimentList> <ingredientList> <condimentList> <bread>
// <condimentList> ::= { <condiment> }
// <ingredientList> ::= { <ingredient> }
// <bread> ::= <whiteBread> | <wheatBread>
// <condiment> ::= <mayoCondiment> | <mustardCondiment> | <ketchupCondiment>
// <ingredient> ::= <lettuceIngredient> | <tomatoIngredient> | <chickenIngredient>
public class Sandwich : IExpression
{
    private readonly IBread _topBread;
    private readonly CondimentList _topCondiments;
    private readonly IngredientList _ingredients;
    private readonly CondimentList _bottomCondiments;
    private readonly IBread _bottomBread;

    public Sandwich(IBread topBread, CondimentList topCondiments, IngredientList ingredients, CondimentList bottomCondiments, IBread bottomBread)
    {
        _topBread = topBread;
        _topCondiments = topCondiments;
        _ingredients = ingredients;
        _bottomCondiments = bottomCondiments;
        _bottomBread = bottomBread;
    }

    public void Interpret(Context context)
    {
        context.Output += "|";

        _topBread.Interpret(context);

        context.Output += "|";
        context.Output += "<--";

        _topCondiments.Interpret(context);

        context.Output += "-";

        _ingredients.Interpret(context);

        context.Output += "-";

        _bottomCondiments.Interpret(context);

        context.Output += "-->";
        context.Output += "|";

        _bottomBread.Interpret(context);

        context.Output += "|";

        Console.WriteLine(context.Output);
    }
}
```

The `Interpret()` method is then responsible for invoking the `Interpret()` method on each of the `IExpression` objects in order for the respective `CondimentList` and `IngredientList` instances and then returning the result:

```csharp
var sandwich = new Sandwich(
    new WheatBread(),
    new CondimentList(
        new List<ICondiment> { new MayoCondiment(), new MustardCondiment() }),
    new IngredientList(
        new List<IIngredient> { new LettuceIngredient(), new ChickenIngredient() }),
    new CondimentList(new List<ICondiment> { new KetchupCondiment() }),
    new WheatBread());

sandwich.Interpret(new Context());
```

**Benefits of the Interpreter pattern:**

- **Grammar as code** – each rule of the language maps to a small class, keeping individual pieces simple.
- **Easy extension** – new vocabulary (new breads, condiments or ingredients) can be added without altering the interpretation machinery.
- **Composability** - complex expressions are built by composing simpler ones, mirroring the grammar itself.
- **Testability** – each terminal expression can be tested in isolation against a known `Context`.

In short, reach for the Interpreter pattern when you need to evaluate a simple, well-defined language – but recognise that grammars of any size quickly favour parser generators or dedicated engines instead.

## [Iterator pattern](https://github.com/maceage/design-patterns/tree/master/IteratorPattern){#iterator-pattern}

The Iterator pattern provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation. By externalising traversal into its own object, the same aggregate can be traversed in multiple ways – or the same traversal applied to different structures – without duplicating looping logic everywhere.

In my example this particular pattern is split into two implementations: `IteratorExample` and `TreeExample`.

### [IteratorExample](https://github.com/maceage/design-patterns/blob/master/IteratorPattern/IteratorExamples.cs){#iterator-iterator-example}

This example uses a flat list of stock symbols which are stored in different data structures and then iterated over differently depending on the data structure:

```csharp
public static void ArrayIterationExample()
{
    Console.WriteLine("--- Array iteration example start ---");

    var stocks = new[] { "MSFT", "GOOG", "AAPL" };

    for (int i = 0; i < stocks.Length; i++)
    {
        Console.WriteLine(stocks[i]);
    }

    Console.WriteLine("--- Array iteration example end ---");
}

public static void EnumeratorExample()
{
    Console.WriteLine("--- Enumeration iteration example start ---");

    var stocks = new[] { "MSFT", "GOOG", "AAPL" };
    IEnumerator enumerator = stocks.GetEnumerator();

    while (enumerator.MoveNext())
    {
        Console.WriteLine(enumerator.Current);
    }

    Console.WriteLine("--- Enumeration iteration example end ---");
}

public static void ForEachExample()
{
    Console.WriteLine("--- For each iteration example start ---");

    var stocks = new[] { "MSFT", "GOOG", "AAPL" };

    foreach (string stock in stocks)
    {
        Console.WriteLine(stock);
    }

    Console.WriteLine("--- For each iteration example end ---");
}

public static void ListIterationExample()
{
    Console.WriteLine("--- List iteration example start ---");

    var stocks = new SuperCollection { "MSFT", "GOOG", "AAPL" };

    for (int i = 0; i < stocks.Count; i++)
    {
        Console.WriteLine(stocks.Get(i));
    }

    Console.WriteLine("--- List iteration example end ---");
}
```

- `ArrayIterationExample()` creates a standard array and uses a `for` loop to iterate over each stock symbol
- `EnumeratorExample()` also creates a standard array but uses an `IEnumerator` from the `GetEnumerator()` function to iterate over each stock symbol
- `ForEachExample()` also creates a standard array but uses the `foreach` keyword to iterate over each stock symbol
- `ListIterationExample()` creates an instance of the `SuperCollection` class which inherits from `List<string>` and uses a `for` loop to iterate over each stock symbol

### [TreeExample](https://github.com/maceage/design-patterns/blob/master/IteratorPattern/TreeExamples.cs){#iterator-tree-example}

A slightly more complex example using a tree data structure, `CreateTreeWithValues()` instantiates a `Tree<int>` class and uses a `for` loop to create x number of values in a tree structure:

```csharp
private static Tree<int> CreateTreeWithValues(int numberOfValues)
{
    if (numberOfValues <= 0)
    {
        return null;
    }

    var tree = new Tree<int>(1);
    for (int i = 2; i <= numberOfValues; i++)
    {
        tree.Add(i);
    }

    return tree;
}
```

The `Tree<T>` class exposes four methods - `Add()`, `Depth()`, `Children()` and `ToList()`:

- `Add()` appends the given value to the tree, which itself is represented by an instance of `Tree<T>`. First, the value is added to the `LeftChild` if there is no value, otherwise it is added to `RightChild` if there is no value. Otherwise, the depth of the `LeftChild` tree is compared against the depth of the `RightChild` tree and if the `RightChild` tree has more items it is added to the `LeftChild` tree.
- `Depth()` simply looks to see if either the `LeftChild` or `RightChild` is null and returns 0 if so, otherwise it returns 1 plus the maximum depth of the `LeftChild` and `RightChild` trees.
- `Children()` returns a list of the `LeftChild` and `RightChild` trees.
- `ToList()` instantiates a `List<T>` and adds the `LeftChild` items and then the `RightChild` items before returning the list to the caller.

```csharp
[Serializable]
public class Tree<T> : IEnumerable<T>
{
    public Tree()
    {
    }
    
    public Tree(T value)
    {
        Value = value;
    }
    
    public T Value { get; set; }
    
    public Tree<T> LeftChild { get; set; }
    public Tree<T> RightChild { get; set; }
    
    public bool UseBreadthFirstEnumerator { get; set; }
    
    public void Add(T value)
    {
        if (LeftChild == null)
        {
            LeftChild = new Tree<T>(value);
            return;
        }
    
        if (RightChild == null)
        {
            RightChild = new Tree<T>(value);
            return;
        }
    
        if (LeftChild.Depth() <= RightChild.Depth())
        {
            LeftChild.Add(value);
            return;
        }
    
        RightChild.Add(value);
    }
    
    public int Depth()
    {
        if (LeftChild == null || RightChild == null)
        {
            return 0;
        }
    
        return 1 + Math.Max(LeftChild.Depth(), RightChild.Depth());
    }
    
    public IEnumerable<Tree<T>> Children()
    {
        if (LeftChild != null)
        {
            yield return LeftChild;
        }
    
        if (RightChild != null)
        {
            yield return RightChild;
        }
    }
    
    public List<T> ToList()
    {
        var myList = new List<T>();
        myList.Add(Value);
    
        if (LeftChild != null)
        {
            myList.AddRange(LeftChild.ToList());
        }
    
        if (RightChild != null)
        {
            myList.AddRange(RightChild.ToList());
        }
    
        return myList;
    }
    
    public IEnumerator<T> GetEnumerator()
    {
        if (UseBreadthFirstEnumerator)
        {
            return new TreeBreadthFirstEnumerator<T>(this);
        }
    
        return new TreeEnumerator<T>(this);
    }
    
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
```

`Tree<T>` also implements `IEnumerable<T>` to enable iteration and implements the `GetEnumerator` method using two classes - `TreeBreadthFirstEnumerator`, which implements the `IEnumerator<T>` interface and uses a `Queue<T>` to iterate through the tree in breadth-first order:

```csharp
public class TreeBreadthFirstEnumerator<T> : IEnumerator<T>
{
    private readonly Queue<IEnumerator<Tree<T>>> _enumerators = new Queue<IEnumerator<Tree<T>>>();
    private readonly Tree<T> _tree;
    
    private Tree<T> _current;
    
    public TreeBreadthFirstEnumerator(Tree<T> tree)
    {
        _tree = tree;
    }
    
    public T Current
    {
        get { return _current.Value; }
    }
    
    object IEnumerator.Current
    {
        get { return Current; }
    }
    
    public void Dispose()
    {
    }
    
    public bool MoveNext()
    {
        if (_current == null)
        {
            Reset();
            _current = _tree;
            _enumerators.Enqueue(_current.Children().GetEnumerator());
    
            return true;
        }
    
        while (_enumerators.Count > 0)
        {
            var enumerator = _enumerators.Peek();
            if (enumerator.MoveNext())
            {
                _current = enumerator.Current;
                _enumerators.Enqueue(_current.Children().GetEnumerator());
    
                return true;
            }
    
            _enumerators.Dequeue();
        }
    
        return false;
    }
    
    public void Reset()
    {
        _current = null;
        _enumerators.Clear();
    }
}
```

And `TreeEnumerator` which implements the `IEnumerator<T>` interface and uses a `Stack<T>` to iterate through the tree in depth-first order:

```csharp
public class TreeEnumerator<T> : IEnumerator<T>
{
    private readonly Stack<Tree<T>> _breadcrumb = new Stack<Tree<T>>();
    private readonly Tree<T> _tree;
    
    private Tree<T> _current;
    private Tree<T> _previous;
    
    public TreeEnumerator(Tree<T> tree)
    {
        _tree = tree;
    }
    
    public T Current
    {
        get { return _current.Value; }
    }
    
    object IEnumerator.Current
    {
        get { return Current; }
    }
    
    public void Dispose()
    {
    }
    
    public bool MoveNext()
    {
        if (_current == null)
        {
            Reset();
            _current = _tree;
            return true;
        }
    
        if (_current.LeftChild != null)
        {
            return TraverseLeft();
        }
    
        if (_current.RightChild != null)
        {
            return TraverseRight();
        }
    
        return TraverseUpAndRight();
    }
    
    private bool TraverseUpAndRight()
    {
        if (_breadcrumb.Count > 0)
        {
            _previous = _current;
    
            while (true)
            {
                _current = _breadcrumb.Pop();
                if (_previous != _current.RightChild)
                {
                    break;
                }
            }
    
            if (_current.RightChild != null)
            {
                _breadcrumb.Push(_current);
                _current = _current.RightChild;
                return true;
            }
        }
    
        return false;
    }
    
    private bool TraverseLeft()
    {
        _breadcrumb.Push(_current);
        _current = _current.LeftChild;
    
        return true;
    }
    
    private bool TraverseRight()
    {
        _breadcrumb.Push(_current);
        _current = _current.RightChild;
    
        return true;
    }
    
    public void Reset()
    {
        _current = null;
    }
}
```

In the example code, the `Tree<T>` class is used to create a binary tree structure and demonstrate the use of the `IEnumerable<T>` interface and the `GetEnumerator` method. The `TreeBreadthFirstEnumerator` and `TreeEnumerator` classes are used to iterate through the tree in breadth-first and depth-first order, respectively.

**Benefits of the Iterator pattern:**

- **Encapsulated traversal** – consumers never need to know whether they are walking an array, a list or a tree.
- **Multiple traversal strategies** – the same collection can offer depth-first, breadth-first or any other order side by side.
- **Simultaneous traversals** – because iteration state lives in the enumerator object rather than the collection, several iterations can run independently.
- **Clean consumer code** - the `foreach` construct hides all of the mechanics behind a single, familiar syntax.

In short, if you are building custom collections in .NET, implementing `IEnumerable<T>` with tailored enumerators is the idiomatic way to control how your data is walked.

## [Mediator pattern](https://github.com/maceage/design-patterns/tree/master/MediatorDesignPattern){#mediator-pattern}

The Mediator pattern centralises communication between a set of objects into a single mediator object. Instead of colleagues referring to each other directly - which quickly produces a tangle of bidirectional dependencies – they report to the mediator, which decides how the rest of the group should respond.

Using an abstract `Aircraft` class to represent different types of aircraft, the Mediator pattern is demonstrated by creating an `AirTrafficControl` class that acts as the mediator between the aircraft and the airport. The `AirTrafficControl` class maintains a list of aircraft and provides a `RegisterAircraftUnderGuidance()` method for adding instances of `Aircraft`:

```csharp
public class AirTrafficControl : IAirTrafficControl
{
    private const int MinimumIntrusionAltitude = 1000;
    
    private readonly IList<Aircraft> _aircraftUnderGuidance = new List<Aircraft>();
    
    public void ReceiveAircraftLocation(Aircraft reportingAircraft)
    {
        foreach (Aircraft currentAircraftUnderGuidance in _aircraftUnderGuidance.Where(x => !x.Equals(reportingAircraft)))
        {
            if (Math.Abs(currentAircraftUnderGuidance.Altitude - reportingAircraft.Altitude) < MinimumIntrusionAltitude)
            {
                currentAircraftUnderGuidance.WarnOfAirspaceIntrusionBy(reportingAircraft);
    
                reportingAircraft.Climb(MinimumIntrusionAltitude);
            }
        }
    }
    
    public void RegisterAircraftUnderGuidance(Aircraft aircraft)
    {
        if (!_aircraftUnderGuidance.Contains(aircraft))
        {
            _aircraftUnderGuidance.Add(aircraft);
        }
    }
}
```

The five implementations of the `Aircraft` class - `Junkers`, `Lancaster`, `Mustang`, `Spitfire` and `Stuka` - each override a `Ceiling` property that returns the maximum altitude the aircraft can fly:

```csharp
// Junkers
public class Junkers : Aircraft
{
    public Junkers(string callSign, IAirTrafficControl atc)
        : base(callSign, atc)
    {
    }

    public override int Ceiling
    {
        get
        {
            return 11150;
        }
    }
}

// Lancaster
public class Lancaster : Aircraft
{
    public Lancaster(string callSign, IAirTrafficControl atc)
        : base(callSign, atc)
    {
    }

    public override int Ceiling
    {
        get
        {
            return 21400;
        }
    }
}

// Mustang
public class Mustang : Aircraft
{
    public Mustang(string callSign, IAirTrafficControl atc)
        : base(callSign, atc)
    {
    }

    public override int Ceiling
    {
        get
        {
            return 41900;
        }
    }
}

// Spitfire
public class Spitfire : Aircraft
{
    public Spitfire(string callSign, IAirTrafficControl atc)
        : base(callSign, atc)
    {
    }

    public override int Ceiling
    {
        get
        {
            return 36500;
        }
    }
}

// Stuka
public class Stuka : Aircraft
{
    public Stuka(string callSign, IAirTrafficControl atc)
        : base(callSign, atc)
    {
    }

    public override int Ceiling
    {
        get
        {
            return 29603;
        }
    }
}
```

Within the base `Aircraft` class, an instance of the `IAirTrafficControl` interface is passed via the constructor. This allows the `AirTrafficControl` class to be notified when the `Altitude` property of an aircraft is set and take appropriate action, such as instructing the reporting aircraft to climb away from other traffic:

```csharp
public abstract class Aircraft
{
    private readonly IAirTrafficControl _atc;
    private int _currentAltitude;

    protected Aircraft(string callSign, IAirTrafficControl atc)
    {
        _atc = atc;
        CallSign = callSign;
        _atc.RegisterAircraftUnderGuidance(this);
    }

    public abstract int Ceiling { get; }

    public string CallSign { get; private set; }

    public int Altitude
    {
        get
        {
            return _currentAltitude;
        }

        set
        {
            _currentAltitude = value;
            _atc.ReceiveAircraftLocation(this);
        }
    }

    public void Climb(int heightToClimb)
    {
        Altitude += heightToClimb;

        Console.WriteLine("{0} climbing to {1}ft", CallSign, Altitude);
    }

    public override bool Equals(object obj)
    {
        if (obj.GetType() != GetType())
        {
            return false;
        }

        var incoming = (Aircraft)obj;
        return CallSign.Equals(incoming.CallSign);
    }

    public override int GetHashCode()
    {
        return CallSign.GetHashCode();
    }

    public void WarnOfAirspaceIntrusionBy(Aircraft reportingAircraft)
    {
        Console.WriteLine("Airspace intrusion for {0} by {1}", CallSign, reportingAircraft.CallSign);
    }
}
```

This is achieved in the `IAirTrafficControl.ReceiveAircraftLocation()` implementation by iterating through the list of aircraft and checking whether the absolute difference in altitude between the reporting aircraft and any other aircraft is less than the `MinimumIntrusionAltitude` of 1,000 feet:

```csharp
var airTrafficControl = new AirTrafficControl();

var fighter1 = new Junkers("JC123", airTrafficControl);
var fighter2 = new Lancaster("LA456", airTrafficControl);
var fighter3 = new Mustang("MS789", airTrafficControl);
var fighter4 = new Spitfire("SF3121", airTrafficControl);
var fighter5 = new Stuka("ST6059", airTrafficControl);

fighter1.Altitude += 25000;
fighter2.Altitude += 25000;
fighter3.Altitude += 25000;
fighter4.Altitude += 25000;
fighter5.Altitude += 25000;
```

If so, the `Aircraft.WarnOfAirspaceIntrusionBy()` method is called on the affected aircraft, and the reporting aircraft is told to climb by the `MinimumIntrusionAltitude` value via its `Climb()` method to prevent a collision.

**Benefits of the Mediator pattern:**

- **Reduced coupling** – colleagues know only the mediator, not each other, so aircraft can come and go freely.
- **Centralised coordination** - the collision-avoidance rules live in one place instead of being duplicated across every aircraft.
- **Easier maintenance** – changing how aircraft interact means editing the mediator alone.
- **Clearer domain modelling** – the real-world role of air traffic control maps naturally onto the code.

In short, whenever a group of objects must coordinate with one another and direct references would create a mesh of dependencies, a mediator is usually the cleaner answer.

## [Memento pattern](https://github.com/maceage/design-patterns/tree/master/MementoPattern){#memento-pattern}

The Memento pattern captures and externalises an object's internal state so that it can be restored later, without violating encapsulation. The originator snapshots its own state into a memento object, which a caretaker stores – and possibly stacks – without ever inspecting its contents. It is the classic backbone of undo functionality.

The best way to represent this pattern was to use a [WPF application](https://learn.microsoft.com/en-us/dotnet/desktop/wpf/overview/) whereby a version of the [`InkCanvas` class](https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.inkcanvas?view=windowsdesktop-10.0) extends the base functionality through the use of an `IMemento` interface with a simple `State` property to capture the `Stroke` instances created when interacting with the canvas:

```csharp
public interface IMemento
{
    object State { get; set; }
}
```

The `InkCanvasWithUndo` implementation exposes a `CreateMemento()` method that returns an `IMemento` instance containing the current state of the canvas, and a `SetMemento()` method that restores the canvas to a previous state by setting the `Stroke` instances to the value of the `State` property of the passed in `IMemento` instance:

```csharp
public class InkCanvasWithUndo : InkCanvas
{
    public IMemento CreateMemento()
    {
        Stroke[] copy = Strokes.ToArray();
        return new InkCanvasMemento { State = copy };
    }

    public void SetMemento(IMemento memento)
    {
        Strokes = new StrokeCollection((Stroke[])memento.State);
    }

    public class InkCanvasMemento : IMemento
    {
        public object State { get; set; }
    }
}
```

To support all this, the `MainWindow` class of the WPF application hooks into the `InkCanvasWithUndo_MouseUp` event to create a `Memento` instance when the user releases the mouse button, and adds it to a list of `Memento` instances representing previous states of the canvas. The `MainWindow` class also hooks into the `CommandBindings` collection to register a method to be executed when the user presses the undo combination, CTRL+Z:
```csharp
public partial class MainWindow
{
    private readonly Stack<IMemento> _states = new Stack<IMemento>();

    public MainWindow()
    {
        InitializeComponent();
        CommandBindings.Add(new CommandBinding(ApplicationCommands.Undo, OnExecutedCommands));
        InkCanvasWithUndo1.MouseUp += InkCanvasWithUndo_MouseUp;

        StoreState();
    }

    private static void OnExecutedCommands(object sender, ExecutedRoutedEventArgs e)
    {
        var myWindow = (MainWindow)sender;

        if (e.Command == ApplicationCommands.Undo)
        {
            myWindow.Undo();
        }
    }

    private void StoreState()
    {
        var memento = InkCanvasWithUndo1.CreateMemento();
        _states.Push(memento);

        StatesCountLabel.Content = _states.Count;
    }

    private void InkCanvasWithUndo_MouseUp(object sender, MouseButtonEventArgs e)
    {
        StoreState();
    }

    private void Undo()
    {
        if (_states.Count > 1)
        {
            _states.Pop();

            var lastState = _states.Peek();
            InkCanvasWithUndo1.SetMemento(lastState);
        }

        StatesCountLabel.Content = _states.Count;
    }
}
```

This restores the canvas to a previous state by calling the `Undo()` method which pops the last `IMemento` instance from the stack of `IMemento` instances and calls the `SetMemento()` method of the `InkCanvasWithUndo` instance with the popped `IMemento` instance, causing the last action to be reverted.

**Benefits of the Memento pattern:**

- **Undo/redo support** - snapshotting state makes it trivial to walk back through a history of changes.
- **Encapsulation preserved** - the caretaker (`MainWindow`) stores opaque mementos without needing to understand canvas internals.
- **Clean separation** - state capture logic stays with the originator rather than leaking into the UI code.
- **Simple history management** - a plain `Stack<T>` is all that is needed to track states.

In short, if your application needs reversible operations - editors, transactional workflows, game state – the Memento pattern gives you that with minimal coupling.

## [Null Object pattern](https://github.com/maceage/design-patterns/tree/master/NullObjectPattern){#null-object-pattern}

One of the more simple design patterns, the Null Object pattern provides a neutral, do-nothing implementation of an interface to stand in for the absence of a meaningful object. This lets callers avoid sprinkling null checks throughout their code, because a null object responds to every method with sensible, inert behaviour.

In the example project there is a `ComputerRepository` class that implements the Null Object pattern. The `ComputerRepository` class has a `Find()` method with a `computerName` parameter that returns a `Computer` object:

```csharp
public class ComputerRepository
{
    public ComputerBase Find(string computerName)
    {
        if (!string.IsNullOrWhiteSpace(computerName))
        {
            switch (computerName.ToLower())
            {
                case "apple":
                    return new AppleComputer();
                case "linux":
                    return new LinuxComputer();
                case "windows":
                    return new WindowsComputer();
            }
        }

        return ComputerBase.Null;
    }
}
```

Internally, the `Find()` method checks if the `computerName` parameter is not null and depending on the value, returns either `AppleComputer`, `LinuxComputer` or `WindowsComputer` - all of which inherit from the `ComputerBase` class:

```csharp
// AppleComputer
public class AppleComputer : ComputerBase
{
	public override Guid Id
	{
		get
		{
			return Guid.NewGuid();
		}
	}

	public override string Name
	{
		get
		{
			return "Apple computer";
		}
	}

	public override void Start()
	{
		Console.WriteLine("Apple computer started");
	}

	public override void Stop()
	{
		Console.WriteLine("Apple computer stopped");
	}
}

// LinuxComputer
public class LinuxComputer : ComputerBase
{
    public override Guid Id
    {
        get
        {
            return Guid.NewGuid();
        }
    }

    public override string Name
    {
        get
        {
            return "Linux computer";
        }
    }

    public override void Start()
    {
        Console.WriteLine("Linux computer started");
    }

    public override void Stop()
    {
        Console.WriteLine("Linux computer stopped");
    }
}

// WindowsComputer
public class WindowsComputer : ComputerBase
{
    public override Guid Id
    {
        get
        {
            return Guid.NewGuid();
        }
    }

    public override string Name
    {
        get
        {
            return "Windows computer";
        }
    }

    public override void Start()
    {
        Console.WriteLine("Windows computer started");
    }

    public override void Stop()
    {
        Console.WriteLine("Windows computer stopped");
    }
}
```

The `ComputerBase` class itself holds a public class definition called `NullComputer` which inherits from `ComputerBase` but has no method implementations and returns empty values for the exposed properties:

```csharp
public abstract class ComputerBase
{
    private static readonly NullComputer _nullComputer = new NullComputer();

    public static NullComputer Null
    {
        get
        {
            return _nullComputer;
        }
    }

    public abstract Guid Id { get; }
    public abstract string Name { get; }

    public abstract void Start();
    public abstract void Stop();

    public class NullComputer : ComputerBase
    {
        public override Guid Id
        {
            get
            {
                return Guid.Empty;
            }
        }

        public override string Name
        {
            get
            {
                return string.Empty;
            }
        }

        public override void Start()
        {
        }

        public override void Stop()
        {
        }
    }
}
```

If no match is found, then the `Find()` method returns a `NullComputer` object via the `ComputerBase.Null` property which itself holds a static instance of `NullComputer`.

**Benefits of the Null Object pattern:**

- **Fewer null checks** – callers never need to guard against null, simplifying every consuming method.
- **Default behaviour** - missing lookups degrade gracefully to no-ops rather than crashing.
- **Singleton efficiency** – one shared, stateless null instance serves all callers.
- **Polymorphic consistency** – code can operate uniformly over real and absent objects alike.

In short, wherever a "not found" result would otherwise ripple null checks through your call stack, a Null Object keeps the code clean and honest.

## [Observer pattern](https://github.com/maceage/design-patterns/tree/master/ObserverPattern){#observer-pattern}

The Observer pattern defines a one-to-many dependency between objects so that when one object (the subject) changes state, all of its dependents (the observers) are notified automatically. It is the foundation of event-driven programming, and this example demonstrates it three ways – a traditional abstract implementation, the .NET `IObserver<T>` pair, and C# events and delegates.

### [Traditional](https://github.com/maceage/design-patterns/tree/master/ObserverPattern/Traditional){#observer-traditional-pattern}

This example uses a `StockTicker` class to demonstrate the pattern which inherits from an `AbstractSubject` class:

```csharp
public class StockTicker : AbstractSubject
{
    private Stock _stock;

    public Stock Stock
    {
        get
        {
            return _stock;
        }

        set
        {
            _stock = value;
            Notify();
        }
    }
}
```

`AbstractSubject` is an abstract class that defines `Register()`, `Unregister()` and `Notify()` methods:

```csharp
public abstract class AbstractSubject
{
    private readonly List<AbstractObserver> _observers = new List<AbstractObserver>();

    public void Register(AbstractObserver observer)
    {
        _observers.Add(observer);
    }

    public void Unregister(AbstractObserver observer)
    {
        _observers.Remove(observer);
    }

    public void Notify()
    {
        foreach (var o in _observers)
        {
            o.Update();
        }
    }
}
```

The `Register()` method adds an `AbstractObserver` to the `_observers` list, the `Unregister()` method removes an `AbstractObserver` from the `_observers` list, and the `Notify()` method calls the `Update()` method on each `AbstractObserver` in the observers list.

The `AbstractObserver` abstract class has an abstract `Update()` method:

```csharp
public abstract class AbstractObserver
{
    public abstract void Update();
}
```

Which is itself implemented by two subclasses - `GoogleObserver` and `MicrosoftObserver`:

```csharp
// GoogleObserver
public class GoogleObserver : AbstractObserver
{
    public GoogleObserver(StockTicker subj)
    {
        DataSource = subj;
        subj.Register(this);
    }

    private StockTicker DataSource { get; }

    public override void Update()
    {
        decimal price = DataSource.Stock.Price;
        string symbol = DataSource.Stock.Symbol;

        if (symbol == "GOOG")
        {
            Console.WriteLine("Google's new price is: {0}", price);
        }
    }
}

// MicrosoftObserver
public class MicrosoftObserver : AbstractObserver
{
    public MicrosoftObserver(StockTicker subj)
    {
        DataSource = subj;
        subj.Register(this);
    }

    private StockTicker DataSource { get; }

    public override void Update()
    {
        decimal price = DataSource.Stock.Price;
        string symbol = DataSource.Stock.Symbol;

        if (symbol == "MSFT" && price > 10.00m)
        {
            Console.WriteLine("Microsoft has reached the target price: {0}", price);
        }
    }
}
```

When these classes are instantiated, they are passed a `StockTicker` object via the constructor which they use to register themselves via the `StockTicker.Register()` method:

```csharp
StockTicker stockTicker = new StockTicker();

GoogleObserver googleObserver = new GoogleObserver(stockTicker);
MicrosoftObserver microsoftObserver = new MicrosoftObserver(stockTicker);
```

When the corresponding `Stock` object instance is updated on the `StockTicker` object, the `Notify()` method is called, which in turn calls the `Update()` method on each `AbstractObserver` in the `_observers` list:

```csharp
foreach (var stock in SampleData.GetNext())
{
    stockTicker.Stock = stock;
}
```

### [IObserver](https://github.com/maceage/design-patterns/tree/master/ObserverPattern/IObserver){#observer-iobserver-pattern}

This version of the pattern effectively inverts the dependency between the `StockTicker` and `IObserver<T>`. In this case, the `StockTicker` class has a `Subscribe()` method that takes an instance of an `IObserver<T>` and registers it with the `StockTicker` object, returning an `Unsubscriber` instance that implements `IDisposable`. When the `Unsubscriber` instance is disposed, it removes the `IObserver<T>` from the internal `_observers` list:

```csharp
public class StockTicker : IObservable<Stock>
{
    private readonly List<IObserver<Stock>> _observers = new List<IObserver<Stock>>();
    
    private Stock _stock;
    
    public Stock Stock
    {
        get
        {
            return _stock;
        }
    
        set
        {
            _stock = value;
            Notify(_stock);
        }
    }
    
    private void Notify(Stock s)
    {
        foreach (var o in _observers)
        {
            if (s.Symbol == null || s.Price < 0)
            {
                o.OnError(new Exception("Bad Stock Data"));
            }
            else
            {
                o.OnNext(s);
            }
        }
    }
    
    public IDisposable Subscribe(IObserver<Stock> observer)
    {
        if (!_observers.Contains(observer))
        {
            _observers.Add(observer);
        }
    
        return new Unsubscriber(_observers, observer);
    }
    
    private class Unsubscriber : IDisposable
    {
        private readonly List<IObserver<Stock>> _observers;
        private readonly IObserver<Stock> _observer;
    
        public Unsubscriber(List<IObserver<Stock>> observers, IObserver<Stock> observer)
        {
            _observers = observers;
            _observer = observer;
        }
    
        public void Dispose()
        {
            if (_observer != null && _observers.Contains(_observer))
            {
                _observers.Remove(_observer);
            }
        }
    }
}
```

Internally to the `StockTicker` class, when the `Stock` property is set, the `Notify()` method is called which iterates over the `_observers` list and calls either the `OnNext()` method or the `OnError()` method if there is an issue with the stock price (null or less than 0) for each `IObserver<T>` instance.

Implementors of the `IObserver<T>` interface - `GoogleMonitor` and `MicrosoftMonitor` - then implement the `OnNext()` and `OnError()` methods and perform the appropriate actions:

```csharp
// GoogleMonitor
public class GoogleMonitor : IObserver<Stock>
{
    public void OnCompleted()
    {
        Console.WriteLine("End of trading day");
    }

    public void OnError(Exception error)
    {
        Console.WriteLine("Error occured in the stock ticker");
    }

    public void OnNext(Stock value)
    {
        if (value.Symbol == "GOOG")
        {
            Console.WriteLine("Google's new price is: {0}", value.Price);
        }
    }
}

// MicrosoftMonitor
public class MicrosoftMonitor : IObserver<Stock>
{
    public void OnCompleted()
    {
        Console.WriteLine("End of trading day");
    }

    public void OnError(Exception error)
    {
        Console.WriteLine("Error occured in the stock ticker");
    }

    public void OnNext(Stock value)
    {
        if (value.Symbol == "MSFT" && value.Price > 10.00m)
        {
            Console.WriteLine("Microsoft has reached the target price: {0}", value.Price);
        }
    }
}
```

When the `StockTicker` is instantiated, the respective monitor implementations are registered via the `Subscribe()` method:

```csharp
StockTicker stockTicker = new StockTicker();

GoogleMonitor googleMonitor = new GoogleMonitor();
MicrosoftMonitor microsoftMonitor = new MicrosoftMonitor();

using (stockTicker.Subscribe(googleMonitor))
{
    using (stockTicker.Subscribe(microsoftMonitor))
    {
        foreach (var stock in SampleData.GetNext())
        {
            stockTicker.Stock = stock;
        }
    }
}
```

### [EventDelegate](https://github.com/maceage/design-patterns/tree/master/ObserverPattern/EventDelegate){#observer-event-delegate}

This version of the pattern employs the event and delegate approach whereby the `StockTicker` class has a `StockChange` event that is raised when the `Stock` property is set:

```csharp
public class StockTicker
{
    private Stock _stock;
    
    public event EventHandler<StockChangeEventArgs> StockChange;
    
    public Stock Stock
    {
        get
        {
            return _stock;
        }
    
        set
        {
            _stock = value;
            OnStockChange(new StockChangeEventArgs(_stock));
        }
    }
    
    protected virtual void OnStockChange(StockChangeEventArgs e)
    {
        if (StockChange != null)
        {
            StockChange(this, e);
        }
    }
}
```

The `StockChange` event is of type `EventHandler<StockChangeEventArgs>` and the `StockChangeEventArgs` class contains the `Stock` property:

```csharp
public class StockChangeEventArgs : EventArgs
{
    public StockChangeEventArgs(Stock s)
    {
        Stock = s;
    }

    public Stock Stock { get; set; }
}
```

Any observers then register with the `StockTicker` class by subscribing to the `StockChange` event via the constructor. Internally, the logic checks against the `Stock` property to see whether the class - either `GoogleMonitor` or `MicrosoftMonitor` - should perform any actions off the back of the event being raised:

```csharp
// GoogleMonitor
public class GoogleMonitor
{
    public GoogleMonitor(StockTicker stockTicker)
    {
        stockTicker.StockChange += StockChangeHandler;
    }

    private static void StockChangeHandler(object sender, StockChangeEventArgs e)
    {
        CheckFilter(e.Stock);
    }

    private static void CheckFilter(Stock value)
    {
        if (value.Symbol == "GOOG")
        {
            Console.WriteLine("Google's new price is: {0}", value.Price);
        }
    }
}

// MicrosoftMonitor
public class MicrosoftMonitor
{
    public MicrosoftMonitor(StockTicker stockTicker)
    {
        stockTicker.StockChange += StockChangeHandler;
    }

    private static void StockChangeHandler(object sender, StockChangeEventArgs e)
    {
        CheckFilter(e.Stock);
    }

    private static void CheckFilter(Stock value)
    {
        if (value.Symbol == "MSFT" && value.Price > 10.00m)
        {
            Console.WriteLine("Microsoft has reached the target price: {0}", value.Price);
        }
    }
}
```

Registration of each monitor is similar to the traditional pattern in that the `StockTicker` instance is passed via the constructor:

```csharp
StockTicker stockTicker = new StockTicker();

GoogleMonitor googleMonitor = new GoogleMonitor(stockTicker);
MicrosoftMonitor microsoftMonitor = new MicrosoftMonitor(stockTicker);

foreach (var stock in SampleData.GetNext())
{
    stockTicker.Stock = stock;
}
```

**Benefits of the Observer pattern:**

- **Loose coupling** – the subject knows only that it has observers, never what they do with the notification.
- **Broadcast semantics** – any number of observers can react to the same state change simultaneously.
- **Runtime subscription** – observers can attach and detach at will, as the `Unsubscriber`/`using` example demonstrates.
- **Idiomatic C# options** - `IObserver<T>`, events and delegates each suit different granularity and error-handling needs.

In short, the Observer pattern underpins much of reactive programming and .NET events – mastering its variants means understanding how modern UIs and streaming systems stay in sync.

## [Rules pattern](https://github.com/maceage/design-patterns/tree/master/RulesPattern){#rules-pattern}

The Rules pattern encapsulates each piece of business logic in its own small class behind a common interface, then composes those rules together. Rather than one sprawling method of nested conditionals, each rule is independently testable and individually replaceable, and new rules slot in without touching the others.

In this example we have an `IDiscountRule` interface with a single method - `CalculateCustomerDiscount()` that returns a decimal value:

```csharp
public interface IDiscountRule
{
    decimal CalculateCustomerDiscount(Customer customer);
}
```

Multiple classes then implement this interface, including `BirthdayDiscountRule`, `FirstTimeCustomerRule`, `LoyalCustomerRule`, `SeniorRule` and `VeteranRule`, each with their own distinct ways of handling the `Customer` instance that is passed in:

```csharp
// BirthdayDiscountRule
public class BirthdayDiscountRule : IDiscountRule
{
    public decimal CalculateCustomerDiscount(Customer customer)
    {
        if (customer.DateOfBirth.Month == DateTime.Today.Month &&
            customer.DateOfBirth.Day == DateTime.Today.Day)
        {
            return 0.10m;
        }

        return 0;
    }
}

// FirstTimeCustomerRule
public class FirstTimeCustomerRule : IDiscountRule
{
    public decimal CalculateCustomerDiscount(Customer customer)
    {
        if (!customer.DateOfFirstPurchase.HasValue)
        {
            return 0.15m;
        }

        return 0;
    }
}

// LoyalCustomerRule
public class LoyalCustomerRule : IDiscountRule
{
    private readonly decimal _discount;
    private readonly int _yearsAsCustomer;

    public LoyalCustomerRule(int yearsAsCustomer, decimal discount)
    {
        _yearsAsCustomer = yearsAsCustomer;
        _discount = discount;
    }

    public decimal CalculateCustomerDiscount(Customer customer)
    {
        if (customer.DateOfFirstPurchase.HasValue)
        {
            if (customer.DateOfFirstPurchase.Value.AddYears(_yearsAsCustomer) <= DateTime.Today)
            {
                var birthdayRule = new BirthdayDiscountRule();

                return _discount + birthdayRule.CalculateCustomerDiscount(customer);
            }
        }

        return 0;
    }
}

// SeniorRule
public class SeniorRule : IDiscountRule
{
    public decimal CalculateCustomerDiscount(Customer customer)
    {
        if (customer.DateOfBirth < DateTime.Now.AddYears(-65))
        {
            return .05m;
        }

        return 0;
    }
}

// VeteranRule
public class VeteranRule : IDiscountRule
{
    public decimal CalculateCustomerDiscount(Customer customer)
    {
        if (customer.IsVeteran)
        {
            return 0.1m;
        }

        return 0;
    }
}
```

For example, `BirthdayDiscountRule` might check whether the customer's birthday is today and apply a discount, while `LoyalCustomerRule` might check the date of when the customer first made a purchase and calculate a similar discount based on the number of years since their first purchase.

The `DiscountCalculator` class then uses these rules to calculate the total discount for a given customer by adding them to a `List<IDiscountRule>` in the default constructor. The `CalculateDiscountPercentage()` method then iterates through this list and returns the maximum discount returned by any of the rules:

```csharp
public class DiscountCalculator
{
    private readonly List<IDiscountRule> _rules = new List<IDiscountRule>();

    public DiscountCalculator()
    {
        _rules.Add(new BirthdayDiscountRule());
        _rules.Add(new SeniorRule());
        _rules.Add(new VeteranRule());
        _rules.Add(new LoyalCustomerRule(1, 0.10m));
        _rules.Add(new LoyalCustomerRule(5, 0.12m));
        _rules.Add(new LoyalCustomerRule(10, 0.20m));
        _rules.Add(new FirstTimeCustomerRule());
    }

    public decimal CalculateDiscountPercentage(Customer customer)
    {
        decimal discount = 0;

        foreach (var rule in _rules)
        {
            discount = Math.Max(rule.CalculateCustomerDiscount(customer), discount);
        }

        return discount;
    }
}
```

**Benefits of the Rules pattern:**

- **Single responsibility per rule** – each business condition is isolated in a tiny, focused class.
- **Unit-testable logic** – every rule can be exercised with simple, deterministic tests.
- **Configurable composition** – the calculator decides which rules run, in what combinations, without modifying the rules themselves.
- **Easy to extend** – a new discount policy is a new class, not a surgical edit to a monolithic conditional.

In short, when your business logic starts sprouting deeply nested `if` statements, the Rules pattern offers a tidy, incremental escape route.

## [State pattern](https://github.com/maceage/design-patterns/tree/master/StatePattern){#state-pattern}

The State pattern allows an object to alter its behaviour when its internal state changes – the object appears to change its class at runtime. Rather than testing a `state` flag in every method, each state becomes a class that implements the shared interface, and transitions simply swap in a different state object.

An `ICommands` interface defines the common behaviour for all states, and concrete state classes implement this interface with their own behaviour:

```csharp
public interface ICommands
{
    bool Delete();
    void Edit(string title, string desc);
    void Print();
    void SetState(string state);
}
```

In the code example, four states are defined and implement the `ICommands` interface - `Active`, `Closed`, `Proposed` and `Resolved` - and each has its own implementation of `Delete()`, `Edit()`, `Print()` and `SetState()`:

```csharp
// Active
public class Active : BaseState, ICommands
{
    private readonly WorkItem _owner;

    public Active(WorkItem owner)
    {
        _owner = owner;
    }

    public bool Delete()
    {
        Console.WriteLine("Work Item is already active. Cannot Delete.");
        return false;
    }

    public void Edit(string title, string desc)
    {
        _owner.Title = title;
        _owner.Description = desc;
    }

    public void Print()
    {
        Print(_owner);
    }

    public void SetState(string state)
    {
        switch (state)
        {
            case "active":
                Console.WriteLine("Work Item is already active.");
                break;
            case "proposed":
            case "resolved":
                _owner.State = state;
                break;
            default:
                Console.WriteLine("Work Item is in an active state and cannot be set to {0}.", state);
                break;
        }
    }
}

// Closed
public class Closed : BaseState, ICommands
{
    private readonly WorkItem _owner;

    public Closed(WorkItem owner)
    {
        _owner = owner;
    }

    public bool Delete()
    {
        return true;
    }

    public void Edit(string title, string desc)
    {
        _owner.Title = title;
        _owner.Description = desc;
    }

    public void Print()
    {
        Print(_owner);
    }

    public void SetState(string state)
    {
        switch (state)
        {
            case "closed":
                Console.WriteLine("Work Item is already closed.");
                break;
            case "resolved":
                _owner.State = state;
                break;
            default:
                Console.WriteLine("Work Item is in a closed state and cannot be set to {0}.", state);
                break;
        }
    }
}

// Proposed
public class Proposed : BaseState, ICommands
{
    private readonly WorkItem _owner;

    public Proposed(WorkItem owner)
    {
        _owner = owner;
    }

    public bool Delete()
    {
        return true;
    }

    public void Edit(string title, string desc)
    {
        _owner.Title = title;
        _owner.Description = desc;
    }

    public void Print()
    {
        Print(_owner);
    }

    public void SetState(string state)
    {
        switch (state)
        {
            case "proposed":
                Console.WriteLine("Work Item is already proposed.");
                break;
            case "active":
                _owner.State = state;
                break;
            default:
                Console.WriteLine("Work Item is in a proposed state and cannot be set to {0}.", state);
                break;
        }
    }
}

// Resolved
public class Resolved : BaseState, ICommands
{
    private readonly WorkItem _owner;

    public Resolved(WorkItem owner)
    {
        _owner = owner;
    }

    public bool Delete()
    {
        Console.WriteLine("Work Item is already resolved. Cannot Delete.");
        return false;
    }

    public void Edit(string title, string desc)
    {
        _owner.Title = title;
        _owner.Description = desc;
    }

    public void Print()
    {
        Print(_owner);
    }

    public void SetState(string state)
    {
        switch (state)
        {
            case "resolved":
                Console.WriteLine("Work Item is already resolved.");
                break;
            case "active":
            case "closed":
                _owner.State = state;
                break;
            default:
                Console.WriteLine("Work Item is in an resolved state and cannot be set to {0}.", state);
                break;
        }
    }
}
```

- In the **Active state**, the item cannot be deleted but can be edited and printed.
- In the **Closed state**, the item can be deleted, edited and printed (amended: the original text stated the item cannot be deleted, but `Closed.Delete()` returns `true`).
- In the **Proposed state**, the item can be edited, deleted and printed.
- In the **Resolved state**, the item cannot be deleted but can be edited and printed.

The `WorkItem` class has a `State` property that, when set, creates a new instance of the specified state and assigns it to the internal `_stateCommand` variable:

```csharp
public class WorkItem : ICommands
{
    private ICommands _stateCommands;
    private string _state;

    public int Id { get; set; }
    public string Title { get; set; }
```csharp
    public string Description { get; set; }

    public string State
    {
        get
        {
            return _state;
        }

        set
        {
            _state = value.ToLower();

            if (_state == "proposed")
            {
                _stateCommands = new States.Proposed(this);
            }

            if (_state == "active")
            {
                _stateCommands = new States.Active(this);
            }

            if (_state == "resolved")
            {
                _stateCommands = new States.Resolved(this);
            }

            if (_state == "closed")
            {
                _stateCommands = new States.Closed(this);
            }
        }
    }

    internal static WorkItem Create()
    {
        var wi = new WorkItem();
        wi.Id = -1;
        wi.State = "Proposed";
        return wi;
    }

    public bool Delete()
    {
        bool canDelete = _stateCommands.Delete();

        if (canDelete)
        {
            Console.WriteLine("Work item deleted!");
        }

        return canDelete;
    }

    public void Edit(string title, string desc)
    {
        _stateCommands.Edit(title, desc);
    }

    public void Print()
    {
        _stateCommands.Print();
    }

    public void SetState(string newstate)
    {
        _stateCommands.SetState(newstate.ToLower());
    }
}
```

The `WorkItem` class delegates all of the `ICommands` behaviour to the current state object, so when the `State` property is set, the work item's behaviour changes accordingly – a delete attempt in the Proposed state succeeds, while the same call in the Active state is refused with a message.

**Benefits of the State pattern:**

- **Contextual behaviour** – each state's rules live in one place rather than being smeared across every method in `switch` statements.
- **Open/closed compliance** – adding a new state means adding a new class, not editing every existing method.
- **Explicit transitions** - permitted state changes are declared alongside the state that owns them, making the workflow self-documenting.
- **Localised state-specific logic** - bugs around what is or is not allowed in a given state become easy to locate and fix.

In short, any time you find yourself guarding methods with `if (state == ...)` checks, the State pattern will usually clean the situation up considerably.

## [Strategy pattern](https://github.com/maceage/design-patterns/tree/master/StrategyPattern){#strategy-pattern}

The Strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. The object using a strategy holds a reference to an abstraction and delegates the work to it, meaning the algorithm can be selected – or swapped – at runtime without the consuming code changing at all.

In this example the `ICalculateOperation` interface defines the common behaviour for all strategies, and concrete strategy classes implement this interface with their own behaviour. A single `Calculate()` method takes two parameters and returns a result:

```csharp
public interface ICalculateOperation
{
    int Calculate(int value1, int value2);
}
```

Implementations of this interface include `AddOperation`, `DivideOperation`, `MinusOperation`, and `MultiplyOperation`, which perform addition, subtraction, multiplication, and division, respectively:

```csharp
// AddOperation
public class AddOperation : ICalculateOperation
{
    public int Calculate(int value1, int value2)
    {
        return value1 + value2;
    }
}

// DivideOperation
public class DivideOperation : ICalculateOperation
{
    public int Calculate(int value1, int value2)
    {
        return value1 / value2;
    }
}

// MinusOperation
public class MinusOperation : ICalculateOperation
{
    public int Calculate(int value1, int value2)
    {
        return value1 - value2;
    }
}

// MultiplyOperation
public class MultiplyOperation : ICalculateOperation
{
    public int Calculate(int value1, int value2)
    {
        return value1 * value2;
    }
}
```

When the `Calculator` class is instantiated, it takes an `ICalculateOperation` object as a parameter, which determines the behaviour of the `Calculate()` method:

```csharp
public class Calculator
{
    private readonly ICalculateOperation _calculateOperation;

    public Calculator(ICalculateOperation calculateOperation)
    {
        _calculateOperation = calculateOperation;
    }

    public int Calculate(int value1, int value2)
    {
        return _calculateOperation.Calculate(value1, value2);
    }
}
```

This allows the `Calculator` object to change its behaviour based on the strategy that is passed to it:

```csharp
private static void AddOperation()
{
    Calculator calculator = new Calculator(new AddOperation());
    int result = calculator.Calculate(NumberOne, NumberTwo);

    Console.WriteLine("Add operation result: {0}", result);
}

private static void DivideOperation()
{
    Calculator calculator = new Calculator(new DivideOperation());
    int result = calculator.Calculate(NumberOne, NumberTwo);

    Console.WriteLine("Divide operation result: {0}", result);
}

private static void MinusOperation()
{
    Calculator calculator = new Calculator(new MinusOperation());
    int result = calculator.Calculate(NumberOne, NumberTwo);

    Console.WriteLine("Minus operation result: {0}", result);
}

private static void MultiplyOperation()
{
    Calculator calculator = new Calculator(new MultiplyOperation());
    int result = calculator.Calculate(NumberOne, NumberTwo);

    Console.WriteLine("Multiply operation result: {0}", result);
}

public class DivideOperation : ICalculateOperation
{
    public int Calculate(int value1, int value2)
    {
        if (value2 == 0)
        {
            throw new ArgumentOutOfRangeException(nameof(value2), "Cannot divide by zero.");
        }

        return value1 / value2;
    }
}
```

**Benefits of the Strategy pattern:**

- **Runtime algorithm selection** – the behaviour of an object can be chosen per use rather than baked in at compile time.
- **Eliminated conditionals** – one algorithm per class replaces sprawling branches on an operation type.
- **Independent testing** – every strategy can be unit tested in isolation.
- **Trivial extensibility** - new algorithms join the family without touching the `Calculator` or any existing strategy.

In short, the Strategy pattern is one of the most frequently applicable patterns in day-to-day development - anywhere you might reach for a `switch` on a behaviour type is a candidate.

## [Template Method pattern](https://github.com/maceage/design-patterns/tree/master/TemplateMethodPattern){#template-method-pattern}

The Template Method pattern defines the skeleton of an algorithm in a base class, deferring some steps to subclasses. The base class fixes the order of operations – the template method – while abstract or virtual hooks let derived classes supply or refine individual steps without altering the overall flow.

Using an `OrderShipment` base class, the implementation of the Template Method pattern has three methods - an abstract `GetShippingLabelFromCarrier()` method and virtual `VerifyShippingData()` and `PrintLabel()` methods:

```csharp
public abstract class OrderShipment
{
    public string ShippingAddress { get; set; }
    public string Label { get; set; }

    public void Ship(StringBuilder stringBuilder)
    {
        VerifyShippingData();
        GetShippingLabelFromCarrier();
        PrintLabel(stringBuilder);
    }

    public virtual void VerifyShippingData()
    {
        if (string.IsNullOrWhiteSpace(ShippingAddress))
        {
            throw new ApplicationException("Invalid address");
        }
    }

    public abstract void GetShippingLabelFromCarrier();

    public virtual void PrintLabel(StringBuilder stringBuilder)
    {
        string label = string.Format("Label: {0}", Label);
        stringBuilder.AppendLine(label);
    }
}
```

Four implementations of the `OrderShipment` class are provided, each with a different shipping carrier. The `GetShippingLabelFromCarrier()` method is abstract and must be implemented by each subclass, while the `VerifyShippingData()` and `PrintLabel()` methods are virtual and can be overridden by subclasses:

```csharp
// AusPostShipment
public class AusPostShipment : OrderShipment
{
    public override void VerifyShippingData()
    {
        if (string.IsNullOrWhiteSpace(ShippingAddress) || !ShippingAddress.ToLower().Contains("australia"))
        {
            throw new ApplicationException("Invalid address");
        }
    }

    public override void GetShippingLabelFromCarrier()
    {
        Label = string.Format("AusPost: [{0}]", ShippingAddress);
    }

    public override void PrintLabel(StringBuilder stringBuilder)
    {
        string label = string.Format("Label: {0} (Australia)", Label);
        stringBuilder.AppendLine(label);
    }
}

// DhlShipment
public class DhlShipment : OrderShipment
{
    public override void GetShippingLabelFromCarrier()
    {
        Label = string.Format("DHL: [{0}]", ShippingAddress);
    }
}

// PostOfficeShipment
public class PostOfficeShipment : OrderShipment
{
    public override void GetShippingLabelFromCarrier()
    {
        Label = string.Format("Post Office: [{0}]", ShippingAddress);
    }
}

// TntShipment
public class TntShipment : OrderShipment
{
    public override void GetShippingLabelFromCarrier()
    {
        Label = string.Format("TNT: [{0}]", ShippingAddress);
    }
}
```

The `Ship()` method is the template method itself: it always verifies the shipping data, obtains the label from the carrier and prints it in that order, regardless of which subclass is doing the shipping. In this example, the `AusPostShipment` class overrides the `VerifyShippingData()` method to perform additional validation specific to its shipping carrier and the `PrintLabel()` method to return a slightly different value, whereas the other implementations merely provide an implementation for the `GetShippingLabelFromCarrier()` method.

**Benefits of the Template Method pattern:**

- **Fixed algorithm shape** – the invariant sequence of steps is defined once in the base class and cannot be accidentally reordered by subclasses.
- **Hooked variation points** - subclasses customise precisely the steps that differ and inherit the rest.
- **Reuse without duplication** – the shared verification and printing logic lives in one place.
- **Progressive refinement** – carriers can start with the default behaviour and override selectively, as `AusPostShipment` does.

In short, the Template Method pattern is ideal when several classes follow the same overall procedure but vary in a few of the details.

## [Visitor pattern](https://github.com/maceage/design-patterns/tree/master/VisitorPattern){#visitor-pattern}

The Visitor pattern allows you to add new operations to a class hierarchy without modifying the existing classes. It separates an algorithm from the objects on which it operates – a visitor object walks the structure and, through double dispatch, each element calls back the appropriate overloaded `Visit()` method on the visitor, making it easier to extend and maintain the code.

The `ICarElement` interface defines a single method `Accept()` that takes a `ICarElementVisitor` object as a parameter:

```csharp
// ICarElement
public interface ICarElement
{
    void Accept(ICarElementVisitor visitor);
}
```

This method is implemented by all concrete classes in the hierarchy, allowing them to accept a visitor object and perform operations on them:

```csharp
// Body
public class Body : ICarElement
{
    public void Accept(ICarElementVisitor visitor)
    {
        visitor.Visit(this);
    }
}

// Engine
public class Engine : ICarElement
{
    public void Accept(ICarElementVisitor visitor)
    {
        visitor.Visit(this);
    }
}

// Wheel
// Amended: removed a stray opening brace that preceded the class definition in the original
public class Wheel : ICarElement
{
    public Wheel(string name)
    {
        Name = name;
    }

    public string Name { get; private set; }

    public void Accept(ICarElementVisitor visitor)
    {
        visitor.Visit(this);
    }
}
```

This is demonstrated through the use of a concrete `Car` class that has an internal `IList<CarElement>` collection of `ICarElement` objects:

```csharp
public class Car : ICarElement
{
    private readonly IList<ICarElement> _elements;

    public Car()
    {
        _elements = new List<ICarElement>();
        _elements.Add(new Wheel("Front left"));
        _elements.Add(new Wheel("Front right"));
        _elements.Add(new Wheel("Back left"));
        _elements.Add(new Wheel("Back right"));
        _elements.Add(new Body());
        _elements.Add(new Engine());
    }

    public void Accept(ICarElementVisitor visitor)
    {
        foreach (ICarElement carElement in _elements)
        {
            carElement.Accept(visitor);
        }

        visitor.Visit(this);
    }
}
```

When the `Car.Accept()` method is called, the corresponding `Accept()` method is called on each element in the collection, allowing the visitor to perform operations on each element. The `ICarElementVisitor` interface defines multiple `Visit()` methods, one for each concrete class in the hierarchy. Each `Visit()` method then performs a specific operation on the corresponding concrete class:

```csharp
// ICarElementVisitor
public interface ICarElementVisitor
{
    void Visit(Engine engine);

    void Visit(Wheel wheel);

    void Visit(Body body);

    void Visit(Car car);
}
```

In this example there are two concrete implementations of the `ICarElementVisitor` interface - `CarElementDoVisitor` and `CarElementPrintVisitor`:

```csharp
// CarElementDoVisitor
public class CarElementDoVisitor : ICarElementVisitor
{
    public void Visit(Engine engine)
    {
        Console.WriteLine("Starting my engine");
    }

    public void Visit(Wheel wheel)
    {
        Console.WriteLine("Visiting my {0} wheel", wheel.Name);
    }

    public void Visit(Body body)
    {
        Console.WriteLine("Moving my body");
    }

    public void Visit(Car car)
    {
        Console.WriteLine("Starting my car");
    }
}

// CarElementPrintVisitor
public class CarElementPrintVisitor : ICarElementVisitor
{
    public void Visit(Engine engine)
    {
        Console.WriteLine("Visiting engine");
    }

    public void Visit(Wheel wheel)
    {
        Console.WriteLine("Visiting {0} wheel", wheel.Name);
    }

    public void Visit(Body body)
    {
        Console.WriteLine("Visiting body");
    }

    public void Visit(Car car)
    {
        Console.WriteLine("Visiting car");
    }
}
```

Because both visitors satisfy the same interface, an entire new operation can be performed over the car's structure without changing any of the `ICarElement` classes - that is the essence of the pattern.

**Benefits of the Visitor pattern:**

- **New operations without recompilation of the hierarchy** - behaviours are added by writing a new visitor, not by editing every element class.
- **Related logic co-located** - all of one operation (say, "print everything") sits in a single class rather than being scattered across the hierarchy.
- **Type-safe dispatch** - overloaded `Visit()` methods give compile-time checking that every element type is handled.
- **Natural fit for composite structures** - combined with a composite like `Car`, traversals and operations remain cleanly separated.

In short, when you have a stable class hierarchy but frequently evolving operations performed upon it, the Visitor pattern lets you grow the operations side indefinitely.

## Wrapping up

Behavioural patterns are all about communication – who talks to whom, who owns which responsibility, and how behaviour can change over time. Whereas creational patterns address how objects come into being and structural patterns address how they compose, behavioural patterns shape the conversations between them.

As a rough guide:

- Need to decouple senders from receivers? Look at **Chain of Responsibility**, **Command**, **Mediator** and **Observer**.
- Changing behaviour over time? **State**, **Strategy** and **Template Method** are the usual suspects.
- Working with collections and structures? **Iterator** and **Visitor** shine here.
- Cleaning up defensive code? **Null Object** and **Rules** will take you a long way.

The full source code for every example in this post is available in [my design patterns repository on GitHub](https://github.com/maceage/design-patterns) – each pattern is a standalone console application you can clone and debug to watch the flow for yourself.
