Decorator pattern

Decorator

Decorator design pattern allows to attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

Decorator
Decorator

Client

[TestMethod]
public void DecoratorTest()
{
    IComponent concreteComponent = new ConcreteComponent1();
    IComponent concreteDecorator1 = new ComponentDecorator1(concreteComponent);
    IComponent concreteDecorator2 = new ComponentDecorator2(concreteDecorator1);

    Assert.AreEqual(concreteDecorator1.Operation(), "ComponentDecorator1 + " + concreteComponent.Operation());
    Assert.AreEqual(concreteDecorator2.Operation(), "ComponentDecorator2 + " + ((ComponentDecorator2)concreteDecorator2).ExtendedOperation() + " + ComponentDecorator1 + " + concreteComponent.Operation());
}

The Component defines the interface for components that can have dynamically attached responsibilities.

/// <summary>
/// Declares the interface for components that can have dynamically attached responsibilities. 
/// </summary>
public interface IComponent
{
    string Operation();
}

The ConcreteComponent implements the Component’s interface to which responsibilities can be attached dynamically.

/// <summary>
/// Implements the Component's interface to which responsibilities can be attached dynamically.
/// </summary>
public class ConcreteComponent1 : IComponent
{

    public string Operation()
    {
        return "ConcreteComponent1";
    }
}

The Decorator maintains a reference to the Component’s object and defines the interface that conforms the Component’s interface

/// <summary>
/// Maintance a reference to the Component's object and define an interface that conforms the component's interface 
/// </summary>
public abstract class AbstractComponentDecorator : IComponent
{

    private IComponent _refToConcreteComponent;

	protected AbstractComponentDecorator(IComponent concreteComponent)
    {
        _refToConcreteComponent = concreteComponent;
    }


    public virtual string Operation()
    {
        return _refToConcreteComponent.Operation();
    }
}

The ComponentDecorator adds responsibilities to an attached component.

/// <summary>
/// Adds responsibilites to a component 
/// </summary>
public class ComponentDecorator1 : AbstractComponentDecorator
{
    public ComponentDecorator1(IComponent concreteComponent) : base(concreteComponent) { }

    public override string Operation()
    {
        return "ComponentDecorator1 + " + base.Operation();
    }
}

Command design pattern

Command design pattern

Command design pattern
Command design pattern

Command design pattern encapsulates request as an object thereby allowing parameterize other objects with different request, log and queue requests, and support undoable operations.

Command Real World Example
Command Real World Example

Test client:

[TestFixture]
public class CommandPatternTest
{
    private Calculator _calculator;
    private Invoker<int> _invoker;

    [SetUp]
    public void SetUp()
    {
        //Arrange
        _calculator = new Calculator();
        _invoker = new Invoker<int>();
    }

    [TestCase(1, 2, 3)]
    public void InvokedAddCommand_OnValidParams_ReturnsExpectedResult(int a, int b, int expectedResult)
    {
        //Arrange
        var addCommand = new AddCommand<int>(_calculator, a, b);
        //Act
        var actualResult = _invoker.SetAndExecuteCommand(addCommand);
        //Assert
        Assert.AreEqual(expectedResult, actualResult);
    }

    [TestCase(3, 2, 1)]
    public void InvokedSubtractCommand_OnValidParams_ReturnsExpectedResult(int a, int b, int expectedResult)
    {
        //Arrange
        var subtractCommand = new SubtractCommand<int>(_calculator, a, b);
        //Act
        var actualResult = _invoker.SetAndExecuteCommand(subtractCommand);
        Assert.AreEqual(expectedResult, actualResult);
    }

    [TestCase(1, 2, 3)]
    public void InvokedUndo_ReturnsExpectedResult(int a, int b, int expectedResult)
    {
        //Arrange
        var addCommand = new AddCommand<int>(_calculator, 1, 2);
        _invoker.SetAndExecuteCommand(addCommand);
        _invoker.SetAndExecuteCommand(addCommand);
        //Act
        var actualResult = _invoker.Undo();
        //Assert
        Assert.AreEqual(expectedResult, actualResult);
    }
}

Invoker:

/// 
/// The Invoker holds a command and calls command's execute method
/// 
/// 
public class Invoker where  T : struct, IConvertible, IComparable
{
    private Stack<ICalculatorCommand> _commands = new Stack<ICalculatorCommand>();        

    public void SetCommand(ICalculatorCommand command)
    {
        _commands.Push(command);            
    }

    public T SetAndExecuteCommand(ICalculatorCommand command)
    {
        _commands.Push(command);
        return command.Calculate();
    }        

    public T Execute()
    {
        return _commands.Peek().Calculate();
    }

    public T Undo()
    {
        if (!_commands.Any())
            throw new InvalidOperationException();
            
        _commands.Pop();
        return _commands.Peek().Calculate();           
    }
}

Receiver:

public enum Operand
{
    Add = '+',
    Subtract = '-'
}

/// 
/// A commands receiver, performs real actions 
/// 
public class Calculator
{
    public dynamic PerformCalculation(Operand operand, dynamic arg1, dynamic arg2)
    {
        switch (operand)
        {
            case Operand.Add:                    
                return arg1 + arg2;
            case Operand.Subtract:
                return arg1 - arg2;
        }
        return null;
    }
}

Abstract command:

public interface ICalculatorCommand where T : struct, IConvertible, IComparable
{
    T Calculate();
}

Concrete commands

public class AddCommand : ICalculatorCommand where T : struct, IConvertible, IComparable
{
    private Calculator _calculator;
    private T _arg1, _arg2;

    public AddCommand(Calculator calculator, T arg1, T arg2)
    {
        _calculator = calculator;
        _arg1 = arg1;
        _arg2 = arg2;
    }

    public T Calculate()
    {
        return (T)_calculator.PerformCalculation(Operand.Add, _arg1, _arg2);
    }
}

public class SubtractCommand : ICalculatorCommand where T : struct, IConvertible, IComparable
{
    private Calculator _calculator;
    private T _arg1, _arg2;

    public SubtractCommand(Calculator calculator, T arg1, T arg2)
    {
        _calculator = calculator;
        _arg1 = arg1;
        _arg2 = arg2;
    }

    public T Calculate()
    {
        return (T)_calculator.PerformCalculation(Operand.Subtract, _arg1, _arg2);
    }
}

Strategy design pattern

Strategy

Strategy pattern defines a family of algorithms, encapsulates each one, make them interchangeable. Strategy lets algorithms vary independently from clients that use it.

Strategy

Context is configured with strategy object. Maintains a reference to a strategy object. May defined an interface to access to strategy data.

public class Context<T>
{
	private IAbstractStrategy<T> _strategy;

	private Context(){}

	/// <summary>
	/// A context constructor which takes a concrete class 
	/// which implements algorithms
	/// </summary>
	/// <param name="strategy">A concrete class which implements algorithms to call</param>
	public Context(IAbstractStrategy<T> strategy)
	{
		_strategy = strategy;           
	}

	/// <summary>
	/// A member of the context class which is capable to use members of the concrete strategy class
	/// </summary>
	public T PerformAlgorithm(T param)
	{
		return _strategy.PerformAlgorithm(param);
	}
}

Strategy defines an interface common for all supported algorithms

/// <summary>
/// Defines an interface which have common methods to call by its context class
/// </summary>   
public interface IAbstractStrategy<T>
{
	T PerformAlgorithm(T param);
}

ConcreteStrategy implements the Strategy interface

/// <summary>
/// Concrete class which implements an interface defined by its contract
/// </summary>
public class ConcreteStrategy1<T> : IAbstractStrategy<T>
{
	public T PerformAlgorithm(T param)
	{
		return param;
	}
}