Click here to Skip to main content
15,896,606 members
Articles / Programming Languages / C#

Design Patterns 3 of 3 - Behavioral Design Patterns

Rate me:
Please Sign up or sign in to vote.
4.91/5 (198 votes)
7 Sep 2012CPOL22 min read 372.2K   6.4K   454  
In this last article about design patterns I will discuss about behavioral design patterns and I will show on real examples how to implement them.
This is an old version of the currently published article.

Introduction

This is the third (and the last) article about design patterns. In the first article of this series I have discussed about creational design patters. The second article was about structural design patterns and now I will describe another set of patterns called Behavioral design patterns.

A behavioral pattern explains how objects interact. It describes how different objects and classes send messages to each other to make things happen and how the steps of a task are divided among different objects. Where creational patterns mostly describe a moment of time (the instant of creation), and structural patterns describe a more or less static structure, behavioral patterns describe a process or a flow

Chain of responsibility pattern

The chain of responsibility pattern is a design pattern that defines a linked list of handlers, each of which is able to process requests. When a request is submitted to the chain, it is passed to the first handler in the list that is able to process it.

As a programmer I’m sure, that you found a problem when event generated by one object needed to be handled by another object. Chain of responsibility pattern can solve this problem. In this pattern we have a source of command objects and a series of processing objects. The command is passed to the first processing object which can handle this command or send it to it’s successor. This continues until the command is processed or the end of the chain is reached. In this pattern object which send a command doesn’t know which object will process the command.

Structural code example

Image 1

The UML diagram below describes an implementation of the chain of responsibility design pattern.

This diagram consists of three parts:

  • Client: this class passes commands (or requests) to the first object of the chain of processing objects.
  • HandlerBase: represents interface or base class for all concrete handlers. It contains a member variable which points to the next processing object.
  • ConcreteHandlers: this is a concrete implementation of HandlerBase class.
C#
static class Program
{
    static void Main()
    {
        HandlerBase handlerA = new ConcreteHandlerA();
        HandlerBase handlerB = new ConcreteHandlerB();
        handlerA.SetSuccessor(handlerB);
        handlerA.HandleRequest(1);
        handlerB.HandleRequest(11);
    }
}

public abstract class HandlerBase
{
    protected HandlerBase _successor;

    public abstract void HandleRequest(int request);

    public void SetSuccessor(HandlerBase successor)
    {
        _successor = successor;
    }
}

public class ConcreteHandlerA : HandlerBase
{
    public override void HandleRequest(int request)
    {
        if (request == 1)
            Console.WriteLine("Handled by ConcreteHandlerA");
        else if (_successor != null)
            _successor.HandleRequest(request);
    }
}


public class ConcreteHandlerB : HandlerBase
{
    public override void HandleRequest(int request)
    {
        if (request > 10)
            Console.WriteLine("Handled by ConcreteHandlerB");
        else if (_successor != null)
            _successor.HandleRequest(request);
    }
}

Real world example

Let’s take a loot at real world example. Imagine you have a wending machine which accepts coins. Rather than having a slot for each type of coin, the machine has only one for all of them. The inserted coin is sent to appropriate storage place that is determined by receiver of the command. In this example we have a Coin class with two properties: Diameter and Weight. This Coin class is in this example a request (or a command). Next we have abstract CoinHandlerBase class with method SetSuccessor() which sets next processing object and abstract method EvaluateCoin which will be overriden be concrete handlers. In this example we will handle only 50 pecne, 5 pence, 1 pound, 10 pence and 20 pence coins. For each type of coins we must implement handler. So now we have five handlers. Each of handler will work with diamenter and weight of coin respecting slightly differences between fixed values defined by handler and properties of coins. This help us to fix the problem when a coin has a little bigger/smaller diameter or when coins is a little heavier or lighter.

C#
class FiftyPenceHandler : CoinHandlerBase
{
    public override CoinEvaluationResult EvaluateCoin(Coin coin)
    {
        if (Math.Abs(coin.Weight - 8) < 0.02 && Math.Abs(coin.Diameter - 27.3) < 0.15)
        {
            Console.WriteLine("Captured 50p");
            return CoinEvaluationResult.Accepted;
        }
        if (_successor != null)
        {
            return _successor.EvaluateCoin(coin);
        }
        return CoinEvaluationResult.Rejected;
    }
}

public class FivePenceHandler : CoinHandlerBase
{

    public override CoinEvaluationResult EvaluateCoin(Coin coin)
    {
        if (Math.Abs(coin.Weight - 3.25) < 0.02 && Math.Abs(coin.Diameter - 18) < 0.1)
        {
            Console.WriteLine("Captured 5p");
            return CoinEvaluationResult.Accepted;
        }
        if (_successor != null)
        {
            return _successor.EvaluateCoin(coin);
        }
        return CoinEvaluationResult.Rejected;
    }
}

class OnePoundHandler : CoinHandlerBase
{
    public override CoinEvaluationResult EvaluateCoin(Coin coin)
    {
        if (Math.Abs(coin.Weight - 9.5) < 0.02 && Math.Abs(coin.Diameter - 22.5) < 0.13)
        {
            Console.WriteLine("Captured £1");
            return CoinEvaluationResult.Accepted;
        }
        if (_successor != null)
        {
            return _successor.EvaluateCoin(coin);
        }
        return CoinEvaluationResult.Rejected;
    }
}

public class TenPenceHandler : CoinHandlerBase
{
    public override CoinEvaluationResult EvaluateCoin(Coin coin)
    {
        if (Math.Abs(coin.Weight - 6.5) < 0.03 && Math.Abs(coin.Diameter - 24.5) < 0.15)
        {
            Console.WriteLine("Captured 10p");
            return CoinEvaluationResult.Accepted;
        }
        if (_successor != null)
        {
            return _successor.EvaluateCoin(coin);
        }
        return CoinEvaluationResult.Rejected;
    }
}

class TwentyPenceHandler : CoinHandlerBase
{
    public override CoinEvaluationResult EvaluateCoin(Coin coin)
    {
        if (Math.Abs(coin.Weight - 5) < 0.01 && Math.Abs(coin.Diameter - 21.4) < 0.1)
        {
            Console.WriteLine("Captured 20p");
            return CoinEvaluationResult.Accepted;
        }
        if (_successor != null)
        {
            return _successor.EvaluateCoin(coin);
        }
        return CoinEvaluationResult.Rejected;
    }
}

public abstract class CoinHandlerBase
{
    protected CoinHandlerBase _successor;

    public void SetSuccessor(CoinHandlerBase successor)
    {
        _successor = successor;
    }

    public abstract CoinEvaluationResult EvaluateCoin(Coin coin);
}

public class Coin
{
    public float Weight { get; set; }
    public float Diameter { get; set; }
}

class Program
{
    static void Main()
    {
        var h5 = new FivePenceHandler();
        var h10 = new TenPenceHandler();
        var h20 = new TwentyPenceHandler();
        var h50 = new FiftyPenceHandler();
        var h100 = new OnePoundHandler();
        h5.SetSuccessor(h10);
        h10.SetSuccessor(h20);
        h20.SetSuccessor(h50);
        h50.SetSuccessor(h100);

        var tenPence = new Coin { Diameter = 24.49F, Weight = 6.5F };
        var fiftyPence = new Coin { Diameter = 27.31F, Weight = 8.01F };
        var counterfeitPound = new Coin { Diameter = 22.5F, Weight = 9F };

        Console.WriteLine(h5.EvaluateCoin(tenPence));
        Console.WriteLine(h5.EvaluateCoin(fiftyPence));
        Console.WriteLine(h5.EvaluateCoin(counterfeitPound));
    }
}

public enum CoinEvaluationResult
{
    Accepted,
    Rejected
}

Command pattern

The command pattern is a design pattern that enables all of the information for a request to be contained within a single object. The command can then be invoked as required, often as part of a batch of queued commands with rollback capabilities.

Command pattern is behavioral design pattern in which all information needed to execute a method are encapsulated within an object which could be used immediately or held for later use. This object doesn’t execute anything, it only includes information.

There are three key terms which need to be explained: client, invoker and receiver. Client creates the command object. The invoker decides when the method which needs information encapsulated within command object should be called. Receiver is an instance of the class which contains the method’s code.

Structural code example

Image 2

The UML diagram below describes an implementation of the command design pattern. This diagram consists of five parts:

  • Client: The class is a consumer of the classes of the command design pattern. It creates the command objects and links them to receivers.
  • Receiver: this is the class which knows how to perform the operations associated with carrying out the request.
  • CommandBase: this is the abstract class (or interface) for all command objects. It holds information about receiver which is responsible for executing operation using information encapsulated within command object.
  • ConcreteCommand: concrete implementation of CommandBase abstract class or interface.
  • Invoker: is the object which decides when to execute the command.
C#
class Program
{
    static void Main()
    {
        Client client = new Client();
        client.RunCommand();
    }
}

public class Client
{
    public void RunCommand()
    {
        var invoker = new Invoker();
        var receiver = new Receiver();
        var command = new ConcreteCommand(receiver);
        command.Parameter = "Hello, world!";
        invoker.Command = command;
        invoker.ExecuteCommand();
    }
}

public class Receiver
{
    public void Action(string message)
    {
        Console.WriteLine("Action called with message, '{0}'.", message);
    }
}


public class Invoker
{
    public CommandBase Command { get; set; }

    public void ExecuteCommand()
    {
        Command.Execute();
    }
}

public abstract class CommandBase
{
    protected readonly Receiver _receiver;

    public CommandBase(Receiver receiver)
    {
        _receiver = receiver;
    }

    public abstract void Execute();
}

public class ConcreteCommand : CommandBase
{
    public string Parameter { get; set; }

    public ConcreteCommand(Receiver receiver) : base(receiver) { }

    public override void Execute()
    {
        _receiver.Action(Parameter);
    }
}

Real world example

I have prepared a simple example that demonstrates using of command pattern. In this example command pattern is used to control the robot movement. In this example the client is an application. The receiver of the commands is the robot itself. The Robot class has 4 methods which for controlling the movement: Move, RotateLeft, RotateRight, TakeSample. The RobotCommandBase is the abstract base class for all concrete command classes. It has one protected Robot field which points to the Robot object and abstract method Move and Undo which must be overriden be concrete command. The class RobotController is in this example invoker. It contains two methods: ExecuteCommands and UndoCommands. The first method will execute all commands in a queue and method UndoCommands is undo functionality to reverse a number commands as required.

C#
public abstract class RobotCommandBase
{
    protected Robot _robot;

    public RobotCommandBase(Robot robot)
    {
        _robot = robot;
    }

    public abstract void Execute();

    public abstract void Undo();
}

public class MoveCommand:RobotCommandBase
{
    public int ForwardDistance { get; set; }

    public MoveCommand(Robot robot) : base(robot) { }

    public override void Execute()
    {
        _robot.Move(ForwardDistance);
    }

    public override void Undo()
    {
        _robot.Move(-ForwardDistance);
    }
}

public class RotateLeftCommand : RobotCommandBase
{
    public double LeftRotationAngle { get; set; }

    public RotateLeftCommand(Robot robot) : base(robot) { }

    public override void Execute()
    {
        _robot.RotateLeft(LeftRotationAngle);
    }

    public override void Undo()
    {
        _robot.RotateRight(LeftRotationAngle);
    }
}

public class RotateRightCommand : RobotCommandBase
{
    public double RightRotationAngle { get; set; }

    public RotateRightCommand(Robot robot) : base(robot) { }

    public override void Execute()
    {
        _robot.RotateRight(RightRotationAngle);
    }

    public override void Undo()
    {
        _robot.RotateLeft(RightRotationAngle);
    }
}

public class TakeSampleCommand : RobotCommandBase
{
    public bool TakeSample { get; set; }

    public TakeSampleCommand(Robot robot) : base(robot) { }

    public override void Execute()
    {
        _robot.TakeSample(true);
    }

    public override void Undo()
    {
        _robot.TakeSample(false);
    }
}

public class RobotController
{
    public Queue<RobotCommandBase> Commands;
    private Stack<RobotCommandBase> _undoStack;

    public RobotController()
    {
        Commands = new Queue<RobotCommandBase>();
        _undoStack = new Stack<RobotCommandBase>();
    }

    public void ExecuteCommands()
    {
        Console.WriteLine("EXECUTING COMMANDS.");

        while (Commands.Count > 0)
        {
            RobotCommandBase command = Commands.Dequeue();
            command.Execute();
            _undoStack.Push(command);
        }
    }

    public void UndoCommands(int numUndos)
    {
        Console.WriteLine("REVERSING {0} COMMAND(S).", numUndos);

        while (numUndos > 0 && _undoStack.Count > 0)
        {
            RobotCommandBase command = _undoStack.Pop();
            command.Undo();
            numUndos--;
        }
    }
}

public class Robot
{
    public void Move(int distance)
    {
        if (distance > 0)
            Console.WriteLine("Robot moved forwards {0}mm.", distance);
        else
            Console.WriteLine("Robot moved backwards {0}mm.", -distance);
    }

    public void RotateLeft(double angle)
    {
        if (angle > 0)
            Console.WriteLine("Robot rotated left {0} degrees.", angle);
        else
            Console.WriteLine("Robot rotated right {0} degrees.", -angle);
    }

    public void RotateRight(double angle)
    {
        if (angle > 0)
            Console.WriteLine("Robot rotated right {0} degrees.", angle);
        else
            Console.WriteLine("Robot rotated left {0} degrees.", -angle);
    }

    public void TakeSample(bool take)
    {
        if(take)
            Console.WriteLine("Robot took sample");
        else
            Console.WriteLine("Robot released sample");
    }
}

class Program
{
    static void Main()
    {
        var robot = new Robot();
        var controller = new RobotController();

        var move = new MoveCommand(robot);
        move.ForwardDistance = 1000;
        controller.Commands.Enqueue(move);

        var rotate = new RotateLeftCommand(robot);
        rotate.LeftRotationAngle = 45;
        controller.Commands.Enqueue(rotate);

        var scoop = new TakeSampleCommand(robot);
        scoop.TakeSample = true;
        controller.Commands.Enqueue(scoop);

        controller.ExecuteCommands();
        controller.UndoCommands(3);
    }
}

Interpreter pattern

The interpreter pattern is a design pattern that is useful when developing domain-specific languages or notations. The pattern allows the grammar for such a notation to be represented in an object-oriented fashion that can easily be extended.

The Interpreter pattern is another behavioral design pattern that specifies how to evaluate the sentences in a language. This pattern is described in terms of formal grammars. It performs some activities based upon a set of expressions. We have two types of expressions: terminal and non-terminal. Difference between this types is very simple. While terminal expressions represents a structures which can be immediately evaluated, the non-terminal expressions are composed of one or more expressions which could be terminal or non-terminal. Interpreter pattern is very similar to Composite pattern. The terminal expressions represents the leafs of this tree structure and non-terminal represents composites. The Interpreter defines the behavior while the composite defines only the structure.

Structural code example

Image 3

The UML diagram below describes an implementation of the interpreter design pattern. This diagram consists of five parts:

  • Client: builds (or is given) an abstract syntax tree representing a particular sentence in the language that the grammar defines. The abstract syntax tree is assembled from instances of the NonterminalExpression and TerminalExpression classes invoke the Interpret operation.
  • Context: contains information that is global to the interpreter.
  • ExpressionBase: declares an interface or abstract class for all expressions.
  • TerminalExpresion: implements an Interpret operation associated with terminal symbols in the grammar. An instance is required for every terminal symbol in the sentence.
  • NonterminalExpression: Non-terminal expressions are represented using a concrete subclass of ExpressionBase. These expressions are aggregates containing one or more further expressions, each of which may be terminal or non-terminal. When a non-terminal expression class's Interpret method is called, the process of interpretation includes calls to the Interpret method of the expressions it holds.
C#
static class Program
{
    static void Main()
    {
        Client.BuildAndInterpretCommands();
    }
}

public static class Client
{
    public static void BuildAndInterpretCommands()
    {
        var context = new Context("hello world!!!");
        var root = new NonterminalExpression
                       {
                           Expression1 = new TerminalExpression(),
                           Expression2 = new TerminalExpression()
                       };
        root.Interpret(context);
    }
}

public class Context
{
    public string Name { get; set; }

    public Context(string name)
    {
        Name = name;
    }
}

public abstract class ExpressionBase
{
    public abstract void Interpret(Context context);
}


public class TerminalExpression : ExpressionBase
{
    public override void Interpret(Context context)
    {
        Console.WriteLine("Terminal for {0}.", context.Name);
    }
}


public class NonterminalExpression : ExpressionBase
{
    public ExpressionBase Expression1 { get; set; }

    public ExpressionBase Expression2 { get; set; }

    public override void Interpret(Context context)
    {
        Console.WriteLine("Nonterminal for {0}.", context.Name);
        Expression1.Interpret(context);
        Expression2.Interpret(context);
    }
}

Real world example

As an example I decided to implement simplified Polish notation evaluator. This evaluator allows you to add or subtract simple integer values. The grammar for Polish notation is very simple. While integer values represent terminals, subtraction and addition operators represent non-terminals. In this example is not necessary to create a custom context class, because the context is represented by string that contains numbers and + and - symbols. In this example we have one IExpressionBase interface that includes signature for method Evaluate which evaluates the expression and returns result of evaluation. Next we have three concrete expression classes which implements IExpressionBase interface. IntegerExpression class which represents basic integers. AdditionExpression and SubtractionExpression classes are non-terminal expression classes. Both of this classes have constructor with two IExpressionBase parametes. Both of this parameters must be evaluate and result of the evaluation is returned by AdditionExpression and SubtractionExpressionClasses.

C#
public interface IExpressionBase
{
    int Evaluate();
}

public class AdditionExpression : ExpressionBase.IExpressionBase
{
    ExpressionBase.IExpressionBase _expr1;
    ExpressionBase.IExpressionBase _expr2;

    public AdditionExpression(ExpressionBase.IExpressionBase expr1, ExpressionBase.IExpressionBase expr2)
    {
        _expr1 = expr1;
        _expr2 = expr2;
    }

    public int Evaluate()
    {
        int value1 = _expr1.Evaluate();
        int value2 = _expr2.Evaluate();
        return value1 + value2;
    }

    public override string ToString()
    {
        return string.Format("({0} + {1})", _expr1, _expr2);
    }
}

public class SubtractionExpression : ExpressionBase.IExpressionBase
{
    ExpressionBase.IExpressionBase _expr1;
    ExpressionBase.IExpressionBase _expr2;

    public SubtractionExpression(ExpressionBase.IExpressionBase expr1, ExpressionBase.IExpressionBase expr2)
    {
        _expr1 = expr1;
        _expr2 = expr2;
    }

    public int Evaluate()
    {
        int value1 = _expr1.Evaluate();
        int value2 = _expr2.Evaluate();
        return value1 - value2;
    }

    public override string ToString()
    {
        return string.Format("({0} + {1})", _expr1, _expr2);
    }
}

public class IntegerExpression:ExpressionBase.IExpressionBase
{
    int _value;

    public IntegerExpression(int value)
    {
        _value = value;
    }

    public int Evaluate()
    {
        return _value;
    }

    public override string ToString()
    {
        return _value.ToString();
    }
}

    static void Main(string[] args)
    {
        var parser = new Parser();

        var commands = new string[]
                                {
                                    "+ 5 6",
                                    "- 6 5",
                                    "+ - 4 5 6",
                                    "+ 4 - 5 6",
                                    "+ - + - - 2 3 4 + - -5 6 + -7 8 9 10"
                                };

        foreach (var command in commands)
        {
            ExpressionBase.IExpressionBase expression = parser.Parse(command);
            Console.WriteLine("{0} = {1}", expression, expression.Evaluate());
        }
    }
}

public class Parser
{
    public ExpressionBase.IExpressionBase Parse(string polish)
    {
        var symbols = new List<string>(polish.Split(' '));
        return ParseNextExpression(symbols);
    }

    public ExpressionBase.IExpressionBase ParseNextExpression(List<string> symbols)
    {
        int value;
        if (int.TryParse(symbols[0], out value))
        {
            symbols.RemoveAt(0);
            return new IntegerExpression(value);
        }
        return ParseNonTerminalExpression(symbols);
    }

    private ExpressionBase.IExpressionBase ParseNonTerminalExpression(List<string> symbols)
    {
        var symbol = symbols[0];
        symbols.RemoveAt(0);

        var expr1 = ParseNextExpression(symbols);
        var expr2 = ParseNextExpression(symbols);

        switch (symbol)
        {
            case "+":
                return new AdditionExpression(expr1, expr2);
            case "-":
                return new SubtractionExpression(expr1, expr2);
            default:
                string message = string.Format("Invalid Symbol ({0})", symbol);
                throw new InvalidOperationException(message);
        }
    }
}

This example was taken from www.blackwasp.co.uk/Interpreter.aspx.

Iterator pattern

The iterator pattern is a design pattern that provides a means for the elements of an aggregate object to be accessed sequentially without knowledge of its structure. This allows traversing of lists, trees and other structures in a standard manner.

One of the most common data structures in software development is a structure which is generic called a collection. The collection is a set of objects. These object can have the same type or they can by all casted to the base type. Collection can by an array, list and so on. One of the most important think of collection is ability to access the elements without exposing the internal structure of collection. The main intent of iterator pattern is to provide a simple interface for traversing a collection of items. The iterator take responsibility of accessing and passing trough the objects of the collection and put it in the iterator object. The iterator object will maintain the state of the iteration, keeping track of the current item and having a way of identifying what elements are next to be iterated.

Structural code example

Image 4

The UML diagram below describes an implementation of the interpreter design pattern. This diagram consists of five parts:

  • Client: this object requests and consumes the iterator from aggregate object when it want to loop thought items.
  • AggregateBase: this is abstract base class (or interface) for all concrete aggregates. This class contains method which returns iterator.
  • ConcreteAggregate: represents the concrete implementation of AggregateBase. It holds items which can be traverser using iterator.
  • IteratorBase: this is the abstract class (or interface) for all concrete iterators. It include methods (in case of interface signature of methods) which allows you to traverse through items.
  • ConcreteIterator: this is the concrete implementation of IteratorBase.
C#
static class Program
{
    static void Main()
    {
        var aggregate = new ConcreteAggregate();
        aggregate[0] = "Item 1";
        aggregate[1] = "Item 2";
        aggregate[2] = "Item 3";
        aggregate[3] = "Item 4";


        var itorator = new ConcreteIterator(aggregate);


        object item = itorator.First();
        while (item != null)
        {
            Console.WriteLine(item);
            item = itorator.Next();
        }
    }
}
abstract class Iterator
{
    public abstract object First();
    public abstract object Next();
    public abstract bool IsDone();
    public abstract object CurrentItem();
}

abstract class Aggregate
{
    public abstract Iterator CreateIterator();
}

class ConcreteIterator : Iterator
{
    private readonly ConcreteAggregate _aggregate;
    private int _current;

    public ConcreteIterator(ConcreteAggregate aggregate)
    {
        _aggregate = aggregate;
    }

    public override object First()
    {
        return _aggregate[0];
    }

    public override object Next()
    {
        object ret = null;
        if (_current < _aggregate.Count - 1)
        {
            ret = _aggregate[++_current];
        }

        return ret;
    }

    public override object CurrentItem()
    {
        return _aggregate[_current];
    }

    public override bool IsDone()
    {
        return _current >= _aggregate.Count;
    }
}

class ConcreteAggregate : Aggregate
{
    private readonly ArrayList _items = new ArrayList();

    public override Iterator CreateIterator()
    {
        return new ConcreteIterator(this);
    }

    public int Count
    {
        get { return _items.Count; }
    }

    public object this[int index]
    {
        get { return _items[index]; }
        set { _items.Insert(index, value); }
    }
}

Real world example

In this example I decided to create a custom collection (PersonAggregate) of Person objects. This custom collection is an aggregate which implements IPersonEnumerable aggregate base interface. This interface contains signature of method GetIterator() which returns iterator for this collection. Next I have created PersonEnumerator class which is the concreate implementation of IPersonIterator interface. This class has one constructor which accepts IPersonEnumerable object. PersonEnumerator class has three methods that allows you to traverse though list of persons. Method MoveFirst sets cursor at the first element of the list. Method MoveNext sets the cursor at the next element of the list and returns true if another element exists in collection after the current item. Last method Reset sets the cursor before the first element of the list.

C#
public interface IPersonEnumerable
{
    IPersonIterator GetIterator();
}

public class PersonAggregate : IPersonEnumerable
{
    private List<Person> _persons = new List<Person>();

    public Person this[int index]
    {
        get { return _persons[index]; }
    }

    public IPersonIterator GetIterator()
    {
        return new PersonEnumerator(this);
    }

    public int Count
    {
        get { return _persons.Count; }
    }

    public void Add(Person person)
    {
        _persons.Add(person);
    }
}

public class PersonEnumerator:IPersonIterator
{
    private PersonAggregate _aggregate;
    int _position;

    public PersonEnumerator(PersonAggregate aggregate)
    {
        _aggregate = aggregate;
    }

    public void MoveFirst()
    {
        if(_aggregate.Count==0)
        {
            throw new InvalidOperationException();
        }
        _position = 0;
    }

    public void Reset()
    {
        _position = -1;
    }

    public bool MoveNext()
    {
        _position++;
        return _position < _aggregate.Count;
    }

    public Person Current
    {
        get
        {
            if (_position < _aggregate.Count)
                return _aggregate[_position];
            throw new InvalidOperationException();
        }
    }
}

public interface IPersonIterator
{
    void MoveFirst();

    void Reset();

    bool MoveNext();

    Person Current { get; }
}

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public double Height { get; set; }
}

    static void Main(string[] args)
    {
        PersonAggregate aggregate = new PersonAggregate();
        aggregate.Add(new Person(){FirstName = "Robert", Height = 168,LastName = "Kanasz"});
        aggregate.Add(new Person(){FirstName = "John", Height = 181, LastName = "Doe" });
        aggregate.Add(new Person() { FirstName = "Jane", Height = 158, LastName = "Doe" });

        IPersonIterator iterator = aggregate.GetIterator();

        iterator.Reset();

        while (iterator.MoveNext())
        {
            Console.WriteLine(iterator.Current.FirstName + " " + iterator.Current.LastName);
        }

    }

Mediator pattern

The mediator pattern is a design pattern that promotes loose coupling of objects by removing the need for classes to communicate with each other directly. Instead, mediator objects are used to encapsulate and centralise the interactions between classes.

Mediator pattern is another behavioral design pattern. In some situations the program is made up of a large classes. This is not unusual but problem arises when this classes need to communicate with each other. Using traditional approach when classes communicate directly this classes require to know their internal implementation. This could leads to a very big mess because when program is becoming more and more complex it is harder to read and understand. This classes are tightly coupled which is not good from design point of view and in a future it could cause problems.

Mediator design pattern solves this problem. In this pattern the communication between objects is encapsulated with mediator object. Instead of classes communicating directly, classes send messages to the mediator and mediator sends this messages to another classes.

Structural code example

Image 5

The UML diagram below describes an implementation of the mediator design pattern. This diagram consists of four parts:

  • ColleagueBase: this is the abstract class (or interface) for all concrete colleagues. It has protected field that holds reference to mediator object.
  • ConcreteColleague: this is the implementation of ColleagueBase class. Concrete colleagues are classes which communicate with each other.
  • MediatorBase: this is the abstract class for mediator object. This class contains methods that can be consumed by colleagues.
  • ConcreateMediator: this class implements communication methods of MediatorBase class. this class holds reference to all colleagues which need to communicate.
C#
static class Program
{
    static void Main()
    {
        var m = new ConcreteMediator();

        var c1 = new ConcreteColleague1(m);
        var c2 = new ConcreteColleague2(m);

        m.Colleague1 = c1;
        m.Colleague2 = c2;

        c1.Send("How are you?");
        c2.Send("Fine, thanks");
    }
}
public abstract class ColleagueBase
{
    protected MediatorBase _mediator;

    public ColleagueBase(MediatorBase mediator)
    {
        _mediator = mediator;
    }
}

public abstract class MediatorBase
{
    public abstract void SendMessage(ColleagueBase caller, string message);
}

class ConcreteMediator : MediatorBase
{
    private ConcreteColleague1 _colleague1;
    private ConcreteColleague2 _colleague2;

    public ConcreteColleague1 Colleague1
    {
        set { _colleague1 = value; }
    }

    public ConcreteColleague2 Colleague2
    {
        set { _colleague2 = value; }
    }


    public override void SendMessage(ColleagueBase caller, string message)
    {
        if (caller == _colleague1)
        {
            _colleague2.Notify(message);
        }
        else
        {
            _colleague1.Notify(message);
        }
    }
}

class ConcreteColleague1 : ColleagueBase
{
    public ConcreteColleague1(MediatorBase mediator)
        : base(mediator)
    {
    }

    public void Send(string message)
    {
        _mediator.SendMessage(this,message);
    }

    public void Notify(string message)
    {
        Console.WriteLine("Colleague1 gets message: " + message);
    }
}

class ConcreteColleague2 : ColleagueBase
{
    public ConcreteColleague2(MediatorBase mediator)
        : base(mediator)
    {
    }

    public void Send(string message)
    {
        _mediator.SendMessage(this, message);
    }

    public void Notify(string message)
    {
        Console.WriteLine("Colleague2 gets message: "+ message);
    }
}

Real world example

Implement this example in real world is a really simple. Let’s imagine you need to create an application which needs to control several aircrafts. Rather than having aircraft to aircraft communication is better to implement centralized mechanism which receives messages from all aircrafts, process them and sends to the other aircrafts.

In this example there are several aircrafs represented by classes: Airbus380, Boeing747 and LearJet45. This classes inherit the Aircraft abstract base class and acts as colleagues. RegionalAirTrafficControll class is the concrete implementatino of mediator class and implements IAirTrafficControl interface (MediatorBase). RegionalAirTraffic control object holds the reference to all aircrafts that need to communicate with each other.

Everytime the aircraft changes its flight altitude, it sends message to mediator (RegionalAirTraffincControl). Mediator finds whether any of the aircrafts is in the same flight corridor of the message sender and if yes, it sends to the aircraft notification message and sender is ordered to increase its altitude.

C#
public abstract class Aircraft
{
    private readonly IAirTrafficControl _atc;
    private int _altitude;

    public string RegistrationNumber { get; set; }

    public int Altitude
    {
        get { return _altitude; }
        set
        {
            _altitude = value;
            _atc.SendWarningMessage(this);
        }
    }

    public Aircraft(string registrationNumber, IAirTrafficControl atc)
    {

        RegistrationNumber = registrationNumber;
        _atc = atc;
        _atc.RegistrerAircraft(this);
    }

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

    public void ReceiveWarning(Aircraft reportingAircraft)
    {
        Console.WriteLine("ATC: ({0}) - {1} is at your flight altitude!!!",this.RegistrationNumber,reportingAircraft.RegistrationNumber);
    }
}

public class Airbus380:Aircraft
{
    public Airbus380(string registrationNumber, IAirTrafficControl atc) : base(registrationNumber, atc)
    {
    }
}

public class Boeing747: Aircraft
{
    public Boeing747(string registrationNumber, IAirTrafficControl atc) : base(registrationNumber, atc)
    {
    }
}

public class LearJet45:Aircraft
{
    public LearJet45(string registrationNumber, IAirTrafficControl atc) : base(registrationNumber, atc)
    {
    }
}

public interface IAirTrafficControl
{
    void RegistrerAircraft(Aircraft aircraft);

    void SendWarningMessage(Aircraft aircraft);
}

public class RegionalAirTrafficControl : IAirTrafficControl
{
    readonly List<Aircraft> _registeredAircrafts = new List<Aircraft>();

    public void RegistrerAircraft(Aircraft aircraft)
    {
        if (!_registeredAircrafts.Contains(aircraft))
        {
            _registeredAircrafts.Add(aircraft);
        }
    }

    public void SendWarningMessage(Aircraft aircraft)
    {
        var list = from a in _registeredAircrafts
                   where a != aircraft &&
                         Math.Abs(a.Altitude - aircraft.Altitude) < 1000
                   select a;
        foreach (var a in list)
        {
            a.ReceiveWarning(aircraft);
            aircraft.Climb(1000);
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        var regionalATC = new RegionalAirTrafficControl();
        var aircraft1 = new Airbus380("AI568", regionalATC);
        var aircraft2 = new Boeing747("BA157", regionalATC);
        var aircraft3 = new Airbus380("LW111", regionalATC);

        aircraft1.Altitude += 100;

        aircraft3.Altitude = 1100;
    }
}

Memento pattern

The memento pattern is a design pattern that permits the current state of an object to be stored without breaking the rules of encapsulation. The originating object can be modified as required but can be restored to the saved state at any time.

It is sometimes necessary to capture internal state of object at some point in time and have the ability to restore to that state later at run time. This is the right place where you can use the memento pattern. This pattern is used to provide an application the undo functionality. Sometimes it is called undo with rollback.

Structural code example

Image 6

The UML diagram below describes an implementation of the memento design pattern. This diagram consists of three parts:

  • Originator: Creates a memento object capturing the originators internal state. Originator uses the memento object to restore its previous state.
  • Memento: Stores internal state of the Originator object. The state can include any number of state variables. The Memento must have two interfaces, an interface to the caretaker. This interface must not allow any operations or any access to internal state stored by the memento and thus honors encapsulation. The other interface is to the originator and allows the originator to access any state variables necessary to for the originator to restore previous state.
  • Caretaker: Is responsible for keeping the memento. The memento is opaque to the caretaker, and the caretaker must not operate on it.
C#
static class Program
{
    static void Main()
    {
        var originator = new Originator {State = "State A"};
        Console.WriteLine(originator.State);
        var caretaker = new Caretaker {Memento = originator.CreateMemento()};
        originator.State = "State B";
        Console.WriteLine(originator.State);
        originator.SetMemento(caretaker.Memento);
        Console.WriteLine(originator.State);
    }
}

class Originator
{
    private string _state;

    public string State
    {
        get { return _state; }
        set
        {
            _state = value;
        }
    }

    public Memento CreateMemento()
    {
        return (new Memento(_state));
    }

    public void SetMemento(Memento memento)
    {
        State = memento.GetState();
    }
}

class Memento
{
    private readonly string _state;

    public Memento(string state)
    {
        _state = state;
    }

    public string GetState()
    {
        return _state;

    }
}

class Caretaker
{
    private Memento _memento;

    public Memento Memento
    {
        set { _memento = value; }
        get { return _memento; }
    }
}

Real world example

In this example we want to tract state at point in time of Person class. The state at point in time is stored in memento class PersonMemento which has the same properties (or state variables) as Person class, but here is one little difference. All of the state variables of memento class are set via constructor and once they are filled we can’t change them. When memento is created it is stored using Add method in caretaker object’s internal stack. Caretaker has another method call GetMemento which removes and returns the object at the top of the internal stack.

C#
public class PersonCaretaker
{
    readonly Stack<PersonMemento> _mementos = new Stack<PersonMemento>();

    public PersonMemento GetMemento()
    {
        return _mementos.Pop();
    }

    public void Add(PersonMemento memento)
    {
        _mementos.Push(memento);
    }
}

public class PersonMemento
{
    public string FirstName { get; private set; }
    public string LastName { get; private set; }
    public string CellPhone { get; private set; }
    public string Address { get; private set; }

    public PersonMemento(string fName, string lName, string cell, string address)
    {
        FirstName = fName;
        LastName = lName;
        CellPhone = cell;
        Address = address;
    }
}

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string CellPhone { get; set; }
    public string Address { get; set; }

    public PersonMemento CreateUnDo()
    {
        return new PersonMemento(FirstName,LastName,CellPhone,Address);
    }

    public  void UnDo(PersonMemento memento)
    {
        FirstName = memento.FirstName;
        LastName = memento.LastName;
        CellPhone = memento.CellPhone;
        Address = memento.Address;
    }

    public void ShowInfo()
    {
        Console.WriteLine("FIRST NAME: {0}",FirstName);
        Console.WriteLine("LAST NAME: {0}", LastName);
        Console.WriteLine("ADDRESS: {0}", Address);
        Console.WriteLine("CELLPHONE: {0}", CellPhone);
    }
}

class Program
{
    static void Main()
    {
        var person = new Person
                         {
                                Address = "Under the Bridge 171",
                                CellPhone = "122011233185",
                                FirstName = "John",
                                LastName = "Doe"
                            };

        var caretaker = new PersonCaretaker();
        caretaker.Add(person.CreateUnDo());

        person.ShowInfo();
        Console.WriteLine();

        person.Address = "Under the Tree 119";
        caretaker.Add(person.CreateUnDo());

        person.ShowInfo();
        Console.WriteLine();

        person.CellPhone = "987654321";
        person.ShowInfo();
        Console.WriteLine();

        person.UnDo(caretaker.GetMemento());
        person.ShowInfo();
        Console.WriteLine();

        person.UnDo(caretaker.GetMemento());
        person.ShowInfo();
        Console.WriteLine();
    }
}

Observer pattern

The observer pattern is a design pattern that defines a link between objects so that when one object's state changes, all dependent objects are updated automatically. This pattern allows communication between objects in a loosely coupled manner.

Using this design pattern allows you to monitor and publish changes of a single object called subject. When change occurs other objects called observers can be automatically notified by calling one of their methods. This pattern gives you a loosely coupling between subjects and observers. The subjects hold references to all of the observers which must be notified when changes occur.

Structural code example

Image 7

The UML diagram below describes an implementation of the observer design pattern. This diagram consists of four parts:

  • SubjectBase: this is the base class for all subjects. It contains one protected list of observers that are subscribed to the subject and methods allow to add or remove observers. It also contains method Notify which loops through the list of observers and call their Notify method.
  • ConcreteSubject: this is the concrete implementation of SubjectBase class. It maintains it’s own state and when change occur it calls Notify method which loops through all of the observers and calls their Notify method.
  • ObserverBase: this is the abstract class for all observers. It contains the method which is called when subject’s state changes.
  • ConcreteObserver: this is the concrete implementation of ObserverBase.
C#
static class Program
{
    static void Main()
    {
        var subject = new ConcreteSubject();
        subject.Attach(new ConcreteObserver(subject,"Observer 1"));
        subject.Attach(new ConcreteObserver(subject,"Observer 2"));
        subject.Attach(new ConcreteObserver(subject,"Observer 3"));
        subject.SetState("STATE");
    }
}

public abstract class SubjectBase
{
    private ArrayList _observers = new ArrayList();

    public void Attach(ObserverBase o)
    {
        _observers.Add(o);
    }

    public void Detach(ObserverBase o)
    {
        _observers.Remove(o);
    }

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


public class ConcreteSubject : SubjectBase
{
    private string _state;

    public string GetState()
    {
        return _state;
    }

    public void SetState(string newState)
    {
        _state = newState;
        Notify();
    }
}


public abstract class ObserverBase
{
    public abstract void Update();
}


public class ConcreteObserver : ObserverBase
{
    private ConcreteSubject _subject;
    private string _name;

    public ConcreteObserver(ConcreteSubject subject, string name)
    {
        _subject = subject;
        _name = name;
    }

    public override void Update()
    {
        string subjectState = _subject.GetState();
        Console.WriteLine(_name + ": " +subjectState);
    }
}

Real world example

Let's assume we have a stock system which provides data from several companies. In this example we have a two observers: AllStockObserver and IBMStockObserver. AllStockObserver responds to every change of ConcreteStockTicker class. IBMStockTicker class responds only when stocks of IBM company comes out from ConcreteStockTicker.

C#
public class AllStockObserver : IStockObserverBase
{
    public AllStockObserver(string name)
    {
        Name = name;
    }

    public string Name { get; set; }

    public void Notify(Stock stock)
    {
        Console.WriteLine("Notified {0} of {1}'s " +
                          "change to {2:C}", Name, stock.Code, stock.Price);
    }
}

public class IBMStockObserver:IStockObserverBase
{
    public IBMStockObserver(string name)
    {
        Name = name;
    }

    public string Name { get; set; }

    public void Notify(Stock stock)
    {
        if(stock.Code=="IBM")
            Console.WriteLine("Notified {0} of {1}'s " +
                          "change to {2:C}", Name, stock.Code, stock.Price);
    }
}

public class ConcreteStockTicker:StockTickerBase
{
    private Stock stock;
    public Stock Stock
    {
        get { return stock; }
        set {
            stock = value;
            Notify();
        }
    }

    public override void Notify()
    {
        foreach (var observer in _observers)
        {
            observer.Notify(stock);
        }
    }
}

public class Stock
{
    public decimal Price { get; set; }
    public string Code { get; set; }
}

public interface IStockObserverBase
{
    void Notify(Stock stock);
}

public abstract class StockTickerBase
{
    readonly protected List<IStockObserverBase> _observers = new List<IStockObserverBase>();

    public void Register(IStockObserverBase observer)
    {
        if(!_observers.Contains(observer))
        {
            _observers.Add(observer);
        }
    }

    public void Unregister(IStockObserverBase observer)
    {
        if (_observers.Contains(observer))
        {
            _observers.Remove(observer);
        }
    }

    public abstract void Notify();
}

class Program
{
    static void Main(string[] args)
    {
        var stockTicker = new ConcreteStockTicker();
        var ibmObserver = new IBMStockObserver("ROBER KANASZ");
        var allObserver = new AllStockObserver("IVOR LOTOCASH");

        stockTicker.Register(ibmObserver);
        stockTicker.Register(allObserver);

        foreach (var s in StockData.getNext())
            stockTicker.Stock = s;
    }
}

public static class StockData
{
    private static decimal[] samplePrices = new decimal[] { 10.00m, 10.25m, 555.55m, 9.50m, 9.03m, 500.00m, 499.99m, 10.10m, 10.01m };
    private static string[] sampleStocks = new string[] { "MSFT", "MSFT", "GOOG", "MSFT", "MSFT", "GOOG", "GOOG", "MSFT", "IBM" };
    public static IEnumerable<Stock> getNext()
    {
        for (int i = 0; i < samplePrices.Length; i++)
        {
            Stock s = new Stock();
            s.Code = sampleStocks[i];
            s.Price = samplePrices[i];
            yield return s;
        }
    }
}

State pattern

The state pattern is a design pattern that allows an object to completely change its behaviour depending upon its current internal state. By substituting classes within a defined context, the state object appears to change its type at run-time.

This design pattern allows you to alter behaviour of an object as response to changes of it’s internal state.It allows to change behavior of at run-time without changing the interface used to access the object. This change is hidden in context of this object. This pattern is very useful when creating software state machines, where the functionality of an object changes fundamentally according to its state.

Structural code example

Image 8

The UML diagram below describes an implementation of the state design pattern. This diagram consists of three parts:

  • Context: this class holds the concrete state object that provides behaviour according it’s current state.
  • StateBase: this is the abstract class for all concrete state classes. It defines the interface which is consumed by context class.
  • ConcreteState: this is the concrete implementation of StateBase class. it provides a real functionality consumed by context class.
C#
static class Program
{
    static void Main()
    {
        var context = new Context(new ConcreteStateA());
        context.Request();
        context.Request();
        context.Request();
        context.Request();
    }
}

public class Context
{
    private StateBase _state;

    public Context(StateBase state)
    {
        _state = state;
        State = _state;
    }

    public void Request()
    {
        _state.Handle(this);
    }

    public StateBase State
    {
        set
        {
            _state = value;
            Console.WriteLine("Current state: {0}",_state.GetType());
        }
    }
}

public abstract class StateBase
{
    public abstract void Handle(Context context);
}

class ConcreteStateA : StateBase
{
    public override void Handle(Context context)
    {
        context.State = new ConcreteStateB();
    }
}

class ConcreteStateB : StateBase
{
    public override void Handle(Context context)
    {
        context.State = new ConcreteStateA();
    }
}

Real world example

The DVD player was chosen as a real world example on which I want to demonstrate the State design pattern. Let’s assume that DVD player has two buttons: play and menu. DVD player will behave differently when you push this button according to it’s selected state. The following table describes behavior of DVD player according to it’s state:


StatePlay buttonMenu button
MoviePlayingStateStop playing. State switched to MoviePausedState.State switched to MenuState.
MoviePausedStateStart playing. State switched to MoviePlayingState.State switched to MenuState MenuState.
StandByStateStart playing. State switched to MoviePlayingState.State switched to MenuState MenuState.
MenuStateNo state change.State switched to MenuState StandByState.
C#
public class MenuState:DVDPlayerState
{
    public MenuState()
    {
        Console.WriteLine("MENU");
    }

    public override void PlayButtonPressed(DVDPlayer player)
    {
        Console.WriteLine("  Next Menu Item Selected");
    }

    public override void MenuButtonPressed(DVDPlayer player)
    {
        player.State = new StandbyState();
    }
}

public class MoviePausedState:DVDPlayerState
{
    public MoviePausedState()
    {
        Console.WriteLine("MOVIE PAUSED");
    }

    public override void PlayButtonPressed(DVDPlayer player)
    {
        player.State = new MoviePlayingState();
    }

    public override void MenuButtonPressed(DVDPlayer player)
    {
        player.State = new MenuState();
    }
}

public class MoviePlayingState:DVDPlayerState
{
    public MoviePlayingState()
    {
        Console.WriteLine("MOVIE PLAYING");
    }

    public override void PlayButtonPressed(DVDPlayer player)
    {
        player.State = new MoviePausedState();
    }

    public override void MenuButtonPressed(DVDPlayer player)
    {
        player.State = new MenuState();
    }
}

public class StandbyState:DVDPlayerState
{
    public StandbyState()
    {
        Console.WriteLine("STANDBY");
    }

    public override void PlayButtonPressed(DVDPlayer player)
    {
        player.State = new MoviePlayingState();
    }

    public override void MenuButtonPressed(DVDPlayer player)
    {
        player.State = new MenuState();
    }
}

public class DVDPlayer
{
    private DVDPlayerState _state;

    public DVDPlayer()
    {
        _state = new StandbyState();
    }

    public DVDPlayer(DVDPlayerState state)
    {
        _state = state;
    }

    public void PressPlayButton()
    {
        _state.PlayButtonPressed(this);
    }

    public void PressMenuButton()
    {
        _state.MenuButtonPressed(this);
    }

    public DVDPlayerState State
    {
        get { return _state; }
        set { _state = value; }
    }
}

public abstract class DVDPlayerState
{
    public abstract void PlayButtonPressed(DVDPlayer player);

    public abstract void MenuButtonPressed(DVDPlayer player);
}

    static void Main()
    {
        var player = new DVDPlayer();

        player.PressPlayButton();
        player.PressMenuButton();
        player.PressPlayButton();
        player.PressPlayButton();
        player.PressMenuButton();
        player.PressPlayButton();
        player.PressPlayButton();
    }

Strategy pattern

The strategy pattern is a design pattern that allows a set of similar algorithms to be defined and encapsulated in their own classes. The algorithm to be used for a particular purpose may then be selected at run-time according to your requirements.

This design pattern can be used in common situations where classes differs only in behaviour. In this case it is a good idea to separate this behaviour algorithms in separate classes which can be selected at run-time. This pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. This separation allows may vary independently that clients that use it. It also increases the flexibility of application allowing to add new algorithms in a future.

Structural code example

Image 9

The UML diagram below describes an implementation of the strategy design pattern. This diagram consists of three parts:

  • Client: this class uses interchangeable algorithms. It maintains a reference to StrategyBase object. Sometimes it defines an interface that lets StrategyBase access its data.
  • StrategyBase: declares an interface common to all supported algorithms. Client uses this interface to call the algorithm defined by a ConcreteStrategy.
  • ConcreteStrategy: this is the concrete strategy class inherits from the StrategyBase class. Each instance provides a different algorithm that may be used by the client.
C#
static class Program
{
    static void Main()
    {
        var client = new Client {Strategy = new ConcreteStrategyA()};
        client.CallAlgorithm();
        client.Strategy = new ConcreteStrategyB();
        client.CallAlgorithm();
    }
}

public class Client
{
    public StrategyBase Strategy { private get; set; }

    public void CallAlgorithm()
    {
        Strategy.Algorithm();
    }
}

public abstract class StrategyBase
{
    public abstract void Algorithm();
}

public class ConcreteStrategyA : StrategyBase
{
    public override void Algorithm()
    {
        Console.WriteLine("Concrete Strategy A");
    }
}

public class ConcreteStrategyB : StrategyBase
{
    public override void Algorithm()
    {
        Console.WriteLine("Concrete Strategy B");
    }
}

Real world example

In following example I will show you, how to use Strategy design pattern. This example application will simulate a different robot behaviour. In this example I have created a several Robot class instances with different behaviour. I have created four instances of Robot class. To each of the instances is passed behaviour algorithm using constructor. We have four kinds of behaviour algorithm classes which implement IRobotBehaviour interface.

C#
public class AggresiveBehaviour:IRobotBehaviour
{
    public void Move()
    {
        Console.WriteLine("\tAggresive Behaviour: if find another robot, attack it");
    }
}

public class BorgBehaviour:IRobotBehaviour
{
    public void Move()
    {
        Console.WriteLine("\tBorg Behaviour: if find another robot, assimilate it");
    }
}

public class DefensiveBehaviour:IRobotBehaviour
{
    public void Move()
    {
        Console.WriteLine("\tDefensive Behaviour: if find another robot, run from it");
    }
}

public class NormalBehaviour:IRobotBehaviour
{
    public void Move()
    {
        Console.WriteLine("\tNormal Behaviour: if find another robot, ignore it");
    }
}

public interface IRobotBehaviour
{
    void Move();
}

public class Robot
{
    private readonly IRobotBehaviour _behaviour;
    private readonly string _name;
    public Robot(string name, IRobotBehaviour behaviour)
    {
        _behaviour = behaviour;
        _name = name;
    }

    public void Move()
    {
        Console.WriteLine(_name);
        _behaviour.Move();
    }
}

class Program
{
    static void Main()
    {
        var robot1 = new Robot("4of11", new BorgBehaviour());
        var robor2 = new Robot("Military Robot", new AggresiveBehaviour());
        var robot3 = new Robot("rotoROBOt", new NormalBehaviour());

        robot1.Move();
        robor2.Move();
        robot3.Move();
    }
}

Template method pattern

The template method pattern is a design pattern that allows a group of interchangeable, similarly structured, multi-step algorithms to be defined. Each algorithm follows the same series of actions but provides a different implementation of the steps.

This design pattern allows you to change behaviour of class at run-time. It is almost the same pattern like Strategy design pattern but with one significant difference. While Strategy design pattern overrides entire algorithm, Template method allows you to change only some parts of behaviour algorithm using abstract operations (entire algorithm is separated into several operations).

Structural code example

Image 10

The UML diagram below describes an implementation of the template method design pattern. This diagram consists of two parts:

  • AlgorithmBase: defines abstract primitive operations that concrete subclasses define to implement steps of an algorithm. Implements a template method which defines the skeleton of an algorithm. The template method calls primitive operations as well as operations defined in AbstractClass or those of other objects.
  • ConcreteAlgorithm: implements the primitive operations to carry out subclass-specific steps of the algorithm. When a concrete class is called the template method code will be executed from the base class while for each method used inside the template method will be called the implementation from the derived class.
C#
static class Program
{
    static void Main()
    {

        AlgorithmBase algorithmBase1 = new ConcreteAlgorithmA();
        algorithmBase1.TemplateMethod();

        AlgorithmBase algorithmBase2 = new ConcreteAlgorithmB();
        algorithmBase2.TemplateMethod();
    }
}

public abstract class AlgorithmBase
{
    public void TemplateMethod()
    {
        Step1();
        Step2();
        Step3();
    }

    protected abstract void Step1();

    protected abstract void Step2();

    protected abstract void Step3();
}

public class ConcreteAlgorithmA : AlgorithmBase
{
    protected override void Step1()
    {
        Console.WriteLine("ConcreteAlgorithmA.Step1()");
    }

    protected override void Step2()
    {
        Console.WriteLine("ConcreteAlgorithmA.Step2()");
    }

    protected override void Step3()
    {
        Console.WriteLine("ConcreteAlgorithmA.Step3()");
    }
}


public class ConcreteAlgorithmB : AlgorithmBase
{
    protected override void Step1()
    {
        Console.WriteLine("ConcreteAlgorithmB.Step1()");
    }

    protected override void Step2()
    {
        Console.WriteLine("ConcreteAlgorithmB.Step2()");
    }

    protected override void Step3()
    {
        Console.WriteLine("ConcreteAlgorithmB.Step3()");
    }
}

Real world example

This example is a little notification application that uses different kinds of notification senders. The consumer of the sender is Message class. Each of the senders inherits from NotificationSenderBase class which has abstract method called Notify().

C#
public abstract class NotificationSenderBase
{
    protected SystemOperator _operator;

    public NotificationSenderBase(SystemOperator systemOperator)
    {
        _operator = systemOperator;
    }

    protected abstract string GetNotificationMessageText();


    public abstract void Notify();

}

public class MailNotificationSender : NotificationSenderBase
{
    public MailNotificationSender(SystemOperator systemOperator) : base(systemOperator)
    {
    }

    protected override string GetNotificationMessageText()
    {
        return "[UNSPECIFIED ERROR OCCURED]";
    }

    public override void Notify()
    {
        Console.WriteLine("EMAIL MESSAGE:{0} WAS SET TO: {1}", GetNotificationMessageText(), _operator.Email);
    }
}

public class Message
{
    public NotificationSenderBase Sender { get; set; }

    public void Send()
    {
        Sender.Notify();
    }
}

public class SmsNotificationSender: NotificationSenderBase
{
    public SmsNotificationSender(SystemOperator systemOperator) : base(systemOperator)
    {
    }

    protected override string GetNotificationMessageText()
    {
        return "UNSPECIFIED ERROR OCCURED";
    }

    public override void Notify()
    {
        Console.WriteLine("SMS MESSAGE:{0} WAS SET TO: {1}",GetNotificationMessageText(),_operator.CellPhone);
    }
}

public class SystemOperator
{
    public string Name { get; set; }
    public string Pager { get; set; }
    public string CellPhone { get; set; }
    public string Email { get; set; }
}

class Program
{
    static void Main()
    {

        var systemOperator = new SystemOperator
                                            {
                                                CellPhone = "145616456",
                                                Email = "system@operator.com",
                                                Name = "Super Operator",
                                                Pager = "465565456"
                                            };
        var message = new Message();

        message.Sender = new SmsNotificationSender(systemOperator);
        message.Send();

        message.Sender = new MailNotificationSender(systemOperator);
        message.Send();
    }
}

Visitor pattern

The visitor pattern is a design pattern that separates a set of structured data from the functionality that may be performed upon it. This promotes loose coupling and enables additional operations to be added without modifying the data classes.

Visitor pattern allow you to separate an algorithm from relatively complex object structure on which it operates. The result of this separation is data model with limited functionality and set of visitor that perform operations upon the data. Another benefit is the ability to add a new visitor without the modifying the existing structure. The classes of data structure are created with the members that can be consumed by visitor object. Usually this data object is passed to visitor as parameter of it’s method (the convention is to call this method Visit()).

Structural code example

Image 11

The UML diagram below describes an implementation of the visitor design pattern. This diagram consists of sixparts:

  • Client: this class is a consumer of Visitor pattern. It manages object structure and instructs the objects within structure when to accept visitor.
  • ObjectStructure: this is a class containing all the objects that can be visited. It offers a mechanism to iterate through all the elements. Thi s structure is not necessarily a collection. In can be a complex structure, such as a composite object.
  • ElementBase: is an abstraction which declares the accept operation. This is the entry point which enables an object to be "visited" by the visitor object. Each object from a collection should implement this abstraction in order to be able to be visited.
  • ConcreteElement: Those classes inherits from the base abstract class ElementBase or implements interface and defines the accept operation. The visitor object is passed to this object using the accept operation.
  • VisitorBase: declares a Visit operation for each class of ConcreteElement in the object structure. The operation's name and signature identifies the class that sends the Visit request to the visitor. That lets the visitor determine the concrete class of the element being visited. Then the visitor can access the elements directly through its particular interface.
  • ConcreteVisitor: implements each operation declared by Visitor. Each operation implements a fragment of the algorithm defined for the corresponding class or object in the structure. ConcreteVisitor provides the context for the algorithm and stores its local state. This state often accumulates results during the traversal of the structure.
C#
static class Program
{
    static void Main()
    {
        var objectStructure = new ObjectStructure();
        objectStructure.Attach(new ConcreteElementA());
        objectStructure.Attach(new ConcreteElementB());
        objectStructure.Accept(new ConcreteVisitorA());
        objectStructure.Accept(new ConcreteVisitorB());
    }
}

public abstract class ElementBase
{
    public abstract void Accept(VisitorBase visitor);
}

public abstract class VisitorBase
{
    public abstract void Visit(ConcreteElementA element);

    public abstract void Visit(ConcreteElementB element);
}

public class ObjectStructure
{
    private List<ElementBase> _elements;

    public ObjectStructure()
    {
        _elements = new List<ElementBase>();
    }

    public void Accept(VisitorBase visitor)
    {
        foreach (ElementBase element in _elements)
        {
            element.Accept(visitor);
        }
    }

    public void Attach(ElementBase element)
    {
        _elements.Add(element);
    }

    public void Detach(ElementBase element)
    {
        _elements.Remove(element);
    }
}

public class ConcreteElementA : ElementBase
{
    public override void Accept(VisitorBase visitor)
    {
        visitor.Visit(this);
    }

    public string Name { get; set; }
}


public class ConcreteElementB : ElementBase
{
    public override void Accept(VisitorBase visitor)
    {
        visitor.Visit(this);
    }

    public string Title { get; private set; }
}

public class ConcreteVisitorA : VisitorBase
{
    public override void Visit(ConcreteElementA element)
    {
        Console.WriteLine("VisitorA visited ElementA : {0}", element.Name);
    }

    public override void Visit(ConcreteElementB element)
    {
        Console.WriteLine("VisitorA visited ElementB : {0}", element.Title);
    }
}


public class ConcreteVisitorB : VisitorBase
{
    public override void Visit(ConcreteElementA element)
    {
        Console.WriteLine("VisitorB visited ElementA : {0}", element.Name);
    }

    public override void Visit(ConcreteElementB element)
    {
        Console.WriteLine("VisitorB visited ElementB : {0}", element.Title);
    }
}

Real world example

In this example we have Car class which represents object structure. This class contains one generic list of IElementBase objects which represent car parts. To support visitor design pattern, every of concrete implementation of IElementBase object contains method called Accept that attaches car part to concrete visitor. We have one concrete visitor which displays information about car parts. Every visitor in this case must implements IVisitorBase interface. This interface contains signature for four Visit methods. Each of this methods consume a different kind of car part.

C#
public class Body : IElementBase
{

    public Body(string  name)
    {
        Name = name;
    }

    public string Name { get; set; }

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

public class Engine : IElementBase
{

    public Engine(string name)
    {
        Name = name;
    }

    public string Name { get; set; }

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

public class Transmission : IElementBase
{
    public Transmission(string name)
    {
        Name = name;
    }

    public string Name { get; set; }

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

public class Wheel : IElementBase
{

    public Wheel(string  name)
    {
        Name = name;
    }

    public string Tire { get; set; }

    public string Name { get; set; }

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

    void IElementBase.Accept(IVisitorBase visitor)
    {
        throw new System.NotImplementedException();
    }
}

public class CarElementPrintVisitor:IVisitorBase
{
    public void Visit(Wheel wheel)
    {
        Console.WriteLine("Wheel ({0}): {1}",wheel.Name,wheel.Tire);
    }

    public void Visit(Body body)
    {
        Console.WriteLine("Body: {0}",body.Name);
    }

    public void Visit(Engine engine)
    {
        Console.WriteLine("Engine: {0}",engine.Name);
    }

    public void Visit(Transmission transmission)
    {
        Console.WriteLine("Transmission: {0}",transmission.Name);
    }
}

public interface IElementBase
{
    void Accept(IVisitorBase visitor);
}

public class Car : IElementBase
{
    private readonly List<IElementBase> _parts;

    public Car()
    {
        _parts=new List<IElementBase>
                   {
                       new Wheel("Front Left"){Tire = "Michelin Pilot Super Sport"},
                       new Wheel("Front Right"){Tire = "Michelin Pilot Super Sport"},
                       new Wheel("Back Left"){Tire = "Michelin Pilot Super Sport"},
                       new Wheel("Back Right"){Tire = "Michelin Pilot Super Sport"},
                       new Engine("3.3 TDI 225"),
                       new Body("4-door sedan"),
                       new Transmission("5-speed manual")
                   };
    }

    public void Accept(IVisitorBase visitor)
    {
        foreach (var part in _parts)
        {
            part.Accept(visitor);
        }
    }
}

public interface IVisitorBase
{
    void Visit(Wheel wheel);
    void Visit(Body wheel);
    void Visit(Engine wheel);
    void Visit(Transmission wheel);
}

class Program
{
    static void Main()
    {

        var visitor = new CarElementPrintVisitor();

        var car = new Car();
        car.Accept(visitor);
    }
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect Marwin Cassovia Soft
Slovakia Slovakia
My name is Robert Kanasz and I have been working with ASP.NET, WinForms and C# for several years.
MCSD - Web Applications
MCSE - Data Platform
MCPD - ASP.NET Developer 3.5
- Web Developer 4
MCITP - Database Administrator 2008
- Database Developer 2008
MCSA - SQL Server 2012
MCTS - .NET Framework 3.5, ASP.NET Applications
- SQL Server 2008, Database Development
- SQL Server 2008, Implementation and Maintenance
- .NET Framework 4, Data Access
- .NET Framework 4, Service Communication Applications
- .NET Framework 4, Web Applications
MS - Programming in HTML5 with JavaScript and CSS3 Specialist

Open source projects: DBScripter - Library for scripting SQL Server database objects


Please, do not forget vote

Comments and Discussions

Discussions on this specific version of this article. Add your comments on how to improve this article here. These comments will not be visible on the final published version of this article.