Design patterns Composite pattern Composite logger


Example

The Composite pattern is a design pattern that allows to treat a group of objects as a single instance of an object. It is one of the Gang of Four's structural design patterns.

Example below demonstrate how Composite can be used to log to multiple places using single Log invocation. This approach adheres to SOLID principles because it allows you to add new logging mechanism without violating Single responsibility principle (each logger has only one responsibility) or Open/closed principle (You can add new logger that will log to new place by adding new implementation and not by modifying existing ones).

public interface ILogger
{
    void Log(string message);
}

public class CompositeLogger : ILogger
{
    private readonly ILogger[] _loggers;

    public CompositeLogger(params ILogger[] loggers)
    {
        _loggers = loggers;
    }

    public void Log(string message)
    {
        foreach (var logger in _loggers)
        {
            logger.Log(message);
        }
    }
}

public class ConsoleLogger : ILogger
{
    public void Log(string message)
    {
        //log to console
    }
}

public class FileLogger : ILogger
{
    public void Log(string message)
    {
        //log to file
    }
}

var compositeLogger = new CompositeLogger(new ConsoleLogger(), new FileLogger());
compositeLogger.Log("some message"); //this will be invoked both on ConsoleLogger and FileLogger

It is worth mentioning that composite loggers can be nested (one of the parameters to composite loggers constructor can be another composite logger) creating tree-like structure.