# Software Design Patterns: Miscellaneous

*2024-02-15*

> Miscellaneous design patterns


*As ever, the source code for these patterns is available in the accompanying design-patterns GitHub repository:*

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

These are patterns I've discovered throughout my career that are not officially in the [Gang of Four design patterns]({{< relref"software-design-patterns" >}}) but I thought they deserved a mention anyway.

### [Model-View-Presenter pattern](https://github.com/maceage/design-patterns/tree/master/ModelViewPresenterPattern){#model-view-presenter-pattern}

The Model-View-Presenter (MVP) pattern is a UI design pattern that separates the presentation logic from the business logic, making it easier to test and maintain. It divides an application into three parts: the **Model**, which holds the domain data; the **View**, which is responsible solely for rendering and capturing user input; and the **Presenter**, which acts as the intermediary between the two – retrieving data, applying presentation logic, and telling the View what to display.

In this example, the `FoodPresenter` acts as an intermediary between the `IFoodView` and the `FoodListViewModel`, handling user input and updating the view accordingly:

```csharp
public interface IFoodView
{
    void Show(FoodListViewModel viewModel);
}
```

For this project, a `FoodListViewModelMapper` is used to map the `FoodListViewModel` from the `Food` data. This mapper is responsible for creating the initial state of the `FoodListViewModel` and mapping the `Food` data to `FoodViewModel` objects:

```csharp
public static class FoodListViewModelMapper
{
    public static FoodListViewModel MapFoodListViewModel()
    {
        return new FoodListViewModel
        {
            IsSorted = false,
            Food = MapFoodList()
        };
    }

    private static IList<FoodViewModel> MapFoodList()
    {
        var foodList = GetFood();

        return foodList.Select(MapFood).ToList();
    }

    private static FoodViewModel MapFood(Food food)
    {
        return new FoodViewModel { Id = food.Id, Name = food.Name };
    }

    private static IList<Food> GetFood()
    {
        return new List<Food>
        {
            new Food { Name = "Sushi" },
            new Food { Name = "Cake" },
            new Food { Name = "Sandwich" },
            new Food { Name = "Cookie" },
            new Food { Name = "Banana" }
        };
    }
}
```

The `FoodListViewModel` simply contains a list of `FoodViewModel` instances and a boolean that indicates whether the list is sorted:

```csharp
public class FoodListViewModel
{
    public IEnumerable<FoodViewModel> Food { get; set; }

    public bool IsSorted { get; set; }
}
```

The `FoodPresenter` is then responsible for initialising the view with the initial state of the `FoodListViewModel`. It does this by calling the `GetViewModel` method to retrieve the view model and then passing it to the `Show` method of the `IFoodView` interface:

```csharp
public class FoodPresenter
{
    private readonly IFoodView _view;

    public FoodPresenter(IFoodView view)
    {
        _view = view;
    }

    public void Init()
    {
        var foodListViewModel = GetViewModel();

        _view.Show(foodListViewModel);
    }

    public void Sort(bool isSorted)
    {
        var vm = GetViewModel();

        if (!isSorted)
        {
            vm.Food = vm.Food.OrderBy(f => f.Name);
        }

        vm.IsSorted = !isSorted;

        _view.Show(vm);
    }

    private static FoodListViewModel GetViewModel()
    {
        return FoodListViewModelMapper.MapFoodListViewModel();
    }
}
```

Using a standard [WinForms](https://learn.microsoft.com/en-us/dotnet/desktop/winforms/overview/) app to demonstrate the Model-View-Presenter pattern, `MainForm` implements the `IFoodView` interface and the corresponding `Show()` method. When the `SortButton` is clicked, the `SortButton_Click()` handler is invoked which calls the `FoodPresenter.Sort()` method to process the command:

```csharp
public partial class MainForm : Form, IFoodView
{
    private readonly FoodPresenter _presenter;

    public MainForm()
    {
        InitializeComponent();

        _presenter = new FoodPresenter(this);
        _presenter.Init();
    }

    public void Show(FoodListViewModel viewModel)
    {
        SortButton.Tag = viewModel.IsSorted;

        FoodListBox.DataSource = new List<FoodViewModel>(viewModel.Food);
        FoodListBox.DisplayMember = "Name";
        FoodListBox.ValueMember = "Id";
    }

    private void SortButton_Click(object sender, System.EventArgs e)
    {
        _presenter.Sort((bool)SortButton.Tag);
    }
}
```
The Model-View-Presenter pattern offers several benefits:

- **Separation of concerns** – Presentation logic lives in the presenter, keeping the view dumb and the business logic in the model, which makes each part easier to reason about.
- **Improved testability** – Because the presenter only depends on an interface for the view, presentation logic can be unit tested without instantiating any UI controls.
- **View interchangeability** – Since the view is defined purely by an interface, the same presenter can drive a WinForms view, a web view, or a mock implementation.
- **Reduced duplication** – Common presentation logic such as sorting or filtering can be centralised in one presenter rather than scattered across event handlers.

By moving all decision-making out of the view and into a presenter that talks to an abstraction, MVP keeps UI code tidy, testable, and reusable across front ends.

### [Model-View-ViewModel pattern](https://github.com/maceage/design-patterns/tree/master/ModelViewViewModelPattern){#model-view-viewmodel-pattern}

The Model-View-ViewModel (MVVM) pattern is slightly different to the Model-View-Presenter pattern in that the ViewModel holds the model that's being displayed and processes commands that are invoked on the model. Rather than the presenter explicitly pushing state at the view, the ViewModel publishes changes to its own properties, and the view keeps itself up to date through data binding. This makes MVVM the pattern of choice for binding-driven frameworks such as WPF.

In this example, a `Car` class implements the `INotifyPropertyChanged` interface so that interested parties - in this case the data bindings on the form - are notified whenever a property changes:

```csharp
public class Car : INotifyPropertyChanged
{
    private string _make;
    private string _model;
    private DateTime _lastUpdated;

    public event PropertyChangedEventHandler PropertyChanged;

    public string Make
    {
        get
        {
            return _make;
        }

        set
        {
            _make = value;
            OnPropertyChanged("Make");
        }
    }

    public string Model
    {
        get
        {
            return _model;
        }

        set
        {
            _model = value;
            OnPropertyChanged("Model");
        }
    }

    public DateTime LastUpdated
    {
        get
        {
            return _lastUpdated;
        }

        set
        {
            _lastUpdated = value;
            OnPropertyChanged("LastUpdated");
        }
    }

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
```

A `SaveCarCommand` implements the `ICommand` interface from the [`System.Windows.Input`](https://learn.microsoft.com/en-us/dotnet/api/system.windows.input.icommand?view=net-10.0) namespace by providing functionality for the `CanExecute()` and `Execute()` methods:

```csharp
public class SaveCarCommand : ICommand
{
    private readonly Action _executeMethod;

    public SaveCarCommand(Action executeAction)
    {
        _executeMethod = executeAction;
    }

    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        _executeMethod.Invoke();
    }
}
```

This is then all wired together in the `MainFormViewModel` by implementing the `INotifyPropertyChanged` interface as well as holding an instance of the `Car` class:

```csharp
public class MainFormViewModel : INotifyPropertyChanged
{
    private Car _modelCar;
    private SaveCarCommand _saveCarCommand;

    public MainFormViewModel()
    {
        InitializeCommands();
        LoadCar();
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public Car ModelCar
    {
        get
        {
            return _modelCar;
        }

        set
        {
            _modelCar = value;
            OnPropertyChanged("ModelCar");
        }
    }

    public SaveCarCommand SaveCarCommand
    {
        get
        {
            return _saveCarCommand;
        }

        set
        {
            _saveCarCommand = value;
            OnPropertyChanged("SaveCarCommand");
        }
    }

    private void LoadCar()
    {
        ModelCar = new Car { Make = "BMW", Model = "M2", };
    }

    private void InitializeCommands()
    {
        SaveCarCommand = new SaveCarCommand(UpdateCar);
    }

    private void UpdateCar()
    {
        ModelCar.LastUpdated = DateTime.Now;
    }

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
```

Finally, this is all demonstrated in another WinForms app by adding to the `DataBindings` property by creating a `Binding` for each property to change on the `Control` based on the property that's changed in the `Car` model. When the `SaveButton` is clicked, the `SaveButton_Click` method is invoked which calls the respective `SaveCarCommand` on the `MainFormViewModel` instance, as set up on the `SaveButton.Tag` property when the form is loaded:

```csharp
public partial class MainForm : Form
{
    private MainFormViewModel _mainFormViewModel;
    
    public MainForm()
    {
        InitializeComponent();
    }
    
    private void MainForm_Load(object sender, EventArgs e)
    {
        _mainFormViewModel = new MainFormViewModel();
    
        BindingSource bindingSource = new BindingSource(_mainFormViewModel, null);
    
        MakeTextBox.DataBindings.Add("Text", bindingSource, "ModelCar.Make");
        ModelTextBox.DataBindings.Add("Text", bindingSource, "ModelCar.Model");
        LastUpdatedLabel.DataBindings.Add("Text", bindingSource, "ModelCar.LastUpdated");
    
        SaveButton.Tag = _mainFormViewModel.SaveCarCommand;
    }
    
    private void SaveButton_Click(object sender, EventArgs e)
    {
        ICommand command = ((Control)sender).Tag as ICommand;
    
        if (command != null)
        {
            command.Execute(null);
        }
    }
}
```

The Model-View-ViewModel pattern offers several benefits:

- **Loose coupling between view and logic** – The view knows only about bindable properties and commands, never about the mechanics behind them, so both halves can evolve independently.
- **Improved testability** – Commands and property-change behaviour live in plain classes that can be exercised by unit tests without any UI harness.
- **Less plumbing code in the view** – Data binding eliminates the manual "read the control, validate, push to the model" wiring that event-handler-heavy approaches require.
- **Composable commands** – Encapsulating actions as `ICommand` implementations makes them reusable across multiple views and easy to enable or disable via `CanExecute()`.

By letting the view observe the ViewModel rather than be driven by it, MVVM turns UI state into data that can be bound, tested, and reused with minimal ceremony.

### [Service Locator pattern](https://github.com/maceage/design-patterns/tree/master/ServiceLocatorPattern){#service-locator-pattern}

The Service Locator pattern is a design pattern that provides a centralised location for getting services or dependencies in an application. It acts as a registry or lookup table that allows components to locate and retrieve services without having to know the specific implementation details of those services.

While probably considered an antipattern which has been superseded by the [Dependency Injection](https://www.geeksforgeeks.org/system-design/dependency-injectiondi-design-pattern/) pattern, Service Locator is still worth a mention as it is very similar:

In this example an `ILogger` interface defines a single `LogMessage` method with a `string` parameter:

```csharp
public interface ILogger
{
    void LogMessage(string message);
}
```

This is then implemented by a `Logger` class:

```csharp
public class Logger : ILogger
{
    public void LogMessage(string message)
    {
        Console.WriteLine(message);
    }
}
```

A `ServiceLocator` class is then used to register and retrieve services based on the interface and the corresponding implementation:

```csharp
public class ServiceLocator
{
    private static readonly Hashtable _services = new Hashtable();

    public static void AddService<T>(T service)
    {
        _services.Add(typeof(T).Name, service);
    }

    public static void AddService<T>(string name, T service)
    {
        _services.Add(name, service);
    }

    public static T GetService<T>()
    {
        return (T)GetService<T>(typeof(T).Name);
    }

    public static object GetService<T>(string serviceName)
    {
        return (T)_services[serviceName];
    }
}
```

A `Consumer` class then has a parameterless constructor with a reference to the `ServiceLocator` class for retrieving the `ILogger` concrete implementation:

```csharp
public class Consumer
{
    private readonly ILogger _logger;

    public Consumer()
    {
        _logger = ServiceLocator.GetService<ILogger>();
    }

    public void DoSomething(int numberOfTimes)
    {
        for (int i = 0; i < numberOfTimes; i++)
        {
            _logger.LogMessage("Doing something!");
        }
    } 
}
```

To demonstrate this pattern at runtime using a console application, a `RegisterServices` method is used to register the `ILogger` concrete implementation with the `ServiceLocator` class:

```csharp
public class Program
{
    public static void Main(string[] args)
    {
        RegisterServices();

        Consumer consumer = new Consumer();
        consumer.DoSomething(5);

        Console.ReadLine();
    }

    private static void RegisterServices()
    {
        ILogger logger = new Logger();
        ServiceLocator.AddService(logger);
    }
}
```

When the `Consumer` class is created, the `ServiceLocator` is invoked via the constructor and the respective concrete implementation is retrieved.

The reason why Service Locator is considered an antipattern is due to the reliance on the `ServiceLocator` class in the constructor - whereas the Dependency Injection pattern works by injecting the dependencies into the class through its constructor or properties, making them visible in the class signature rather than hidden inside its body.

The Service Locator pattern does nonetheless offer some benefits, particularly in constrained scenarios:

- **Centralised dependency resolution** – Every service is registered and retrieved from one well-known place, so there is a single composition point for the whole application.
- **Decoupling from concrete types** – Consumers depend only on interfaces and remain ignorant of which implementation sits behind them.
- **Low ceremony** – For small applications or legacy codebases, a locator avoids the upfront cost of introducing a full DI container or reworking constructors.
- **Deferred resolution** – Dependencies can be looked up lazily at the point of use rather than resolved eagerly at construction time.

Although Service Locator trades a little transparency for convenience - which is precisely why dependency injection is now preferred - it remains a useful pattern to recognise, both in older codebases and in the parts of modern frameworks where a locator still lurks behind the scenes.

### [Unit of Work pattern](https://github.com/maceage/design-patterns/tree/master/UnitOfWorkPattern){#unit-of-work-pattern}

The Unit of Work pattern is a design pattern that provides a way to manage a collection of objects that have been modified and need to be persisted to a database. It is often used in object-relational mapping (ORM) frameworks to manage the state of objects and ensure that changes are persisted to the database in a consistent and efficient manner.

To demonstrate this we have a `Database` class that has two methods - `Insert()` and `Update()` - which both take an `IEntity` as a parameter:

```csharp
public static class Database
{
    public static void Insert(IEntity entity)
    {
        Console.WriteLine("Inserting entity {0} into database...", entity);
    }

    public static void Update(IEntity entity)
    {
        Console.WriteLine("Updating entity {0} in database...", entity);
    }
}
```

The `IEntity` interface itself is defined as follows:

```csharp
public interface IEntity
{
    Guid Id { get; set; }

    void Insert();
    void Update();
    IList<IEntity> Load();
}
```

Implementing this interface is a `Customer` class that provides concrete implementations for these interface methods:

```csharp
public class Customer : IEntity
{
    public Customer()
    {
        Id = Guid.NewGuid();
    }

    public Guid Id { get; set; }

    public string FirstName { get; set; }
    public string LastName { get; set; }

    public void Insert()
    {
        Database.Insert(this);
    }

    public void Update()
    {
        Database.Update(this);
    }

    public IList<IEntity> Load()
    {
        return new List<IEntity>
        {
            new Customer { FirstName = "Bill", LastName = "Gates" },
            new Customer { FirstName = "Steve", LastName = "Jobs" },
            new Customer { FirstName = "Elon", LastName = "Musk" }
        };
    }

    public override string ToString()
    {
        return string.Format("{0} {1}", FirstName, LastName);
    }
}
```

Finally, the `UnitOfWork` class exposes `Add()`, `Load()`, `Commit()`, `ListAdded()` and `ListChanged()` methods. Note that the `Commit()` method uses a [`TransactionScope` instance](https://learn.microsoft.com/en-us/dotnet/api/system.transactions.transactionscope?view=net-10.0) to ensure the code is run transactionally. In other words, work inside the block is committed only if no exception happens, otherwise it is rolled back:

```csharp
public class UnitOfWork
{
    private readonly IList<IEntity> _added = new List<IEntity>();
    private IList<IEntity> _changed = new List<IEntity>();

    public void Add(IEntity entity)
    {
        _added.Add(entity);
    }

    public void Load(IEntity entity)
    {
        _changed = entity.Load() as List<IEntity>;
    }

    public void Commit()
    {
        using (TransactionScope transactionScope = new TransactionScope())
        {
            foreach (IEntity entity in _changed)
            {
                entity.Update();
            }

            foreach (IEntity entity in _added)
            {
                entity.Insert();
            }

            transactionScope.Complete();
        }
    }

    public void ListAdded()
    {
        foreach (IEntity entity in _added)
        {
            Console.WriteLine("Entity '{0}' added", entity);
        }
    }

    public void ListChanged()
    {
        foreach (IEntity entity in _changed)
        {
            Console.WriteLine("Entity '{0}' changed", entity);
        }
    }
}
```

A console application demonstrates this by instantiating a `UnitOfWork` instance and performing the operations on it:

```csharp
public static void Main(string[] args)
{
    UnitOfWork unitOfWork = new UnitOfWork();

    Customer customer = new Customer();
    unitOfWork.Load(customer);

    Customer firstCustomer = new Customer { FirstName = "Steve", LastName = "Ballmer" };
    Customer secondCustomer = new Customer { FirstName = "Steve", LastName = "Wozniak" };

    unitOfWork.Add(firstCustomer);
    unitOfWork.Add(secondCustomer);

    Console.WriteLine("Changed entities...");
    unitOfWork.ListChanged();

    Console.WriteLine("Added entities...");
    unitOfWork.ListAdded();

    Console.WriteLine("Committing changes...");
    unitOfWork.Commit();

    Console.ReadLine();
}
```

The Unit of Work pattern offers several benefits:

- **Transactional consistency** – Changes are accumulated and committed as one atomic unit, so either everything persists or nothing does.
- **Efficient batched persistence** – Multiple inserts and updates are flushed together in a single round of operations rather than one database trip per change.
- **Change tracking in one place** – The unit of work maintains the state of added and changed entities centrally, keeping persistence bookkeeping out of the domain objects themselves.
- **Clear commit boundary** – The explicit `Commit()` call makes the moment of persistence visible and controllable in application code.

By deferring persistence until an explicit commit, the Unit of Work pattern keeps database interactions consistent, efficient, and easy to reason about – which is exactly why ORM frameworks like Entity Framework build it into their `DbContext`.

## Wrapping Up

That concludes this look at four more patterns that sit outside the official Gang of Four catalogue. Although they emerged from different corners of software - UI architecture in the case of MVP and MVVM, dependency management for Service Locator, and data persistence for Unit of Work – they all serve the same underlying goal: separating what an application does from the mechanics of how it does it.

Recognising them (alongside when they fall short, as with Service Locator) makes it easier to read unfamiliar codebases and to reach for the right abstraction when architecting your own.
