Printed from www.rmfusion.com A Developer website designed for Developers

Prototype Pattern Code Review

Code Download

Define the Prototype Interface and Handler Objects

Define the IPrototype abstract to be used as the base class for the main Prototype classes.

[Serializable()] public abstract class IPrototype { public ProtoType Clone() { return ((ProtoType)this.MemberwiseClone()); }
public ProtoType DeepCopy() { MemoryStream stream = new MemoryStream(); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(stream, this); stream.Seek(0, SeekOrigin.Begin); ProtoType copy = (ProtoType)formatter.Deserialize(stream); stream.Close(); return (copy); } }

The class defines the Clone() method (which does a shallow copy of the original object) and the DeepCopy() method.

A shallow copy creates a new instance of the same type as the original object, and then copies the nonstatic fields of the original object. If the field is a value type, a bit-by-bit copy of the field is performed. If the field is a reference type, the reference is copied but the referred object is not; therefore, the reference in the original object and the reference in the clone point to the same object.

In contrast, a deep copy of an object duplicates everything directly or indirectly referenced by the fields in the object.

The ProtoType class (object) represents the original prototype class, from which other classes will be cloned.

[Serializable()] public class ProtoType : IPrototype { public String Country { get; set; } public String Capital { get; set; } public DeeperData Language { get; set; }
public ProtoType(String country, String capital, String language) { this.Country = country; this.Capital = capital; this.Language = new DeeperData(language); }
public override string ToString() { return(String.Format("{0}\t\t{1}\t\t->{2}", this.Country, this.Capital, this.Language)); } }

The DeeperData class (object) is an extension to the Prototype class (object) and represents a referred object in the Prototype class (object).

[Serializable()] public class DeeperData { public String Data { get; set; }
public DeeperData(String s) { this.Data = s; }
public override string ToString() { return (Data); } }

Define the PrototypeManager Object

The PrototypeManager class (object) creates a collection of Prototype objects.

class PrototypeManager : IPrototype { public Dictionary<String, ProtoType> prototypes = new Dictionary<String, ProtoType> { {"Germany", new ProtoType("Germany", "Berlin", "German")}, {"Italy", new ProtoType("Italy", "Rome", "Italian")}, {"Australia", new ProtoType("Australia", "Canberra", "English")} }; }

Use the Prototype Pattern

The Program class creates an instance of the PrototypeManager class, which creates different prototype instances. These prototypes are then cloned using shallow copy and deep copy methods. The outputs from the difference methods are displayed for comparision.

class Program { static void Report(String s, ProtoType a, ProtoType b) { Console.WriteLine(String.Format("\n{0}", s)); Console.WriteLine(String.Format("Prototype\t{0}\nClone\t\t{1}", a, b)); }
static void Main(string[] args) { PrototypeManager manager = new PrototypeManager(); ProtoType c2; ProtoType c3;
c2 = manager.prototypes["Australia"].Clone(); Report("Shallow cloning Australia\n===============", manager.prototypes["Australia"], c2);
c2.Capital = "Sydney"; Report("Altered Clone's shallow state, prototype unaffected", manager.prototypes["Australia"], c2);
c2.Language.Data = "Chinese"; Report("Altering Clone deep state: prototype affected *****", manager.prototypes["Australia"], c2);
c3 = manager.prototypes["Germany"].DeepCopy( ); Report("Deep cloning Germany\n============", manager.prototypes["Germany"], c3);
c3.Capital = "Munich"; Report("Altering Clone shallow state, prototype unaffected", manager.prototypes["Germany"], c3);
c3.Language.Data = "Turkish"; Report("Altering Clone deep state, prototype unaffected", manager.prototypes["Germany"], c3);
Console.Read(); } }