Saturday, January 13, 2018

Design Pattern : Prototype

The prototype design pattern is a design pattern that is used to instantiate a class by copying, or cloning, the properties of an existing object. The new object is an exact copy of the prototype but permits modification without altering the original.
This is another Gang of Four creational pattern. As programmer I’m absolutely sure that you found yourself create objects using new keyword many times and in some cases, when objects has a lot of properties which must be filled it was so boring and quantity of time you spent on this single task was enormous. I thing you agree when I say that today’s programming is all about the costs and saving of resources (especially time) is a big issue. Sometimes you can find another way how to instantiate a new object using existing objects. This type of object creation is called cloning. This practise is very useful when the construction of a new object using new keyword is inefficient.
When original object is cloned, the new object is a shallow (or sometimes called deep) copy, This copy duplicates all of the properties and fields of original object. If a property is reference type, the reference is copied too.

Structural code example

 
The UML diagram below describes an implementation of the prototype design pattern. This diagram consits of two type of classes:
  • Prototype: represents an abstract base class from the objects that can be cloned. This class contains single virtual method Clone() that returns prototype object. .NET framework includes interface named ICloneable which creates a new instance of a class with the same value as an existing instance.
  • ConcretePrototype: this class inherits from Prototype base class and includes additional functionality. In this class is also overriden Clone() method.
static class Program
{
    static void Main()
    {
        ConcretePrototype prototype = new ConcretePrototype("1");
        ConcretePrototype clone = (ConcretePrototype)prototype.Clone();
        Console.WriteLine("Cloned: {0}", clone.Id);
    }
}

abstract class Prototype
{
    private readonly string _id;

    protected Prototype(string id)
    {
        _id = id;
    }

    public string Id
    {
        get { return _id; }
    }

    public abstract Prototype Clone();
}

class ConcretePrototype : Prototype
{
    public ConcretePrototype(string id)
        : base(id)
    {
    }
    public override Prototype Clone()
    {
        return (Prototype)MemberwiseClone();
    }
}

Real world example

In this example I have created two concrete prototype classes: Commander and Infantry. Both of this classes inherites from StormTrooper class. StormTrooper class has two public methods: FirePower and Armor and one public method Clone which returns a shallow copy of object.
class Program
{
    static void Main()
    {
        var stormCommander = new Commander();
        var infantry = new Infantry();


        var stormCommander2 = stormCommander.Clone() as Commander;
        var infantry2 = infantry.Clone() as Infantry;


        if (stormCommander2 != null)
            Console.WriteLine("Firepower: {0}, Armor: {1}",stormCommander2.FirePower,stormCommander2.Armor);

        if (infantry2 != null)
            Console.WriteLine("Firepower: {0}, Armor: {1}", infantry2.FirePower, infantry2.Armor);
    }
}

public abstract class StormTrooper:ICloneable
{
    public int FirePower { get; set; }
    public int Armor { get; set; }

    public object Clone()
    {
        return MemberwiseClone();
    }
}

public class Commander:StormTrooper
{
    public Commander()
    {
        Armor = 15;
        FirePower = 20;
    }
}

public class Infantry : StormTrooper
{
    public Infantry()
    {
        FirePower = 10;
        Armor = 9;
    }
}

No comments:

Post a Comment