This pattern allows you to create an object by copying a prototype instead of "newing" it up. Why would you want to do that? Well, let's say you had an object and the creation of this object was computationally expensive. If you created this object by "newing" it every time, you'd suffer the same creation cost every time. However, if you create it (or a prototype of it) only once and then clone it the second and subsequent times you need it, then you save yourself a lot of computational expense.

The UML model for this pattern looks something like this

Here's an example implementation in C#

using System;
using System.Collections.Generic;
using System.Text;

namespace garyshort.org.patterns.prototype
{
    class Program
    {
        /// <summary>
        /// GS - Define a class to be a prototype 
        /// for our "expensive to create" object
        /// </summary>
        public class MortgagePrototype
        {
            private int _Atribute1;

            public int Attribute1
            {
                get { return _Atribute1; }
                set { _Atribute1 = value; }
            }

            //GS - Lots more attributes making 
            //this object expensive to create

            private int _AttributeN;

            public int AttributeN
            {
                get { return _AttributeN; }
                set { _AttributeN = value; }
            }

            public MortgagePrototype Clone()
            {
                return this.MemberwiseClone() as 
                    MortgagePrototype;
            }
	    }

        /// <summary>
        /// GS - Now add in the extra attributes 
        /// that make a commercial mortgage
        /// </summary>
        public class CommercialMortgagePrototype : 
            MortgagePrototype
        {
            private int _CMAttribute1;

            public int CMAttribute1
            {
                get { return _CMAttribute1; }
                set { _CMAttribute1 = value; }
            }

            //GS - Lots more attributes making this 
            //object expensive to create

            private int _CMAttributeN;

            public int CMAttributeN
            {
                get { return _CMAttributeN; }
                set { _CMAttributeN = value; }
            }

            public override string ToString()
            {
                return "I am a commercial mortgage";
            }
	    }

        public class ResidentialMortgagePrototype : 
            MortgagePrototype
        {
            private int _RMAttribute1;

            public int RMAttribute1
            {
                get { return _RMAttribute1; }
                set { _RMAttribute1 = value; }
            }

            //GS - Lots more attributes making this 
            //object expensive to create

            private int _RMAttributeN;

            public int RMAttributeN
            {
                get { return _RMAttributeN; }
                set { _RMAttributeN = value; }
            }

            public override string ToString()
            {
                return "I am a residential mortgage";
            }
        }
        
        static void Main(string[] args)
        {
            //GS - Let's test the pattern

            //GS - These objects are expensive to create 
            //so create them once here, early on in the 
            //application

            CommercialMortgagePrototype cmp = 
                new CommercialMortgagePrototype();
            ResidentialMortgagePrototype rmp = 
                new ResidentialMortgagePrototype();
            
            //Okay let's create a new commercial mortgage
            CommercialMortgagePrototype cm1 = cmp.Clone() as 
                CommercialMortgagePrototype;

            //GS - And a residental mortgage too
            ResidentialMortgagePrototype rm1 = rmp.Clone() as 
                ResidentialMortgagePrototype;

            //GS - Do work here...

            //GS - Create more expensive objects here...

            //GS - etc...

            //GS - Let's make sure they work
            Console.WriteLine(cm1.ToString());
            Console.WriteLine(rm1.ToString());

        }
    }
}

The output from this implimentation looks like this

Technorati tags: ,