Where I Share What I Learn. Basically my Notebook :)

Prototype Pattern using C#

Introduction

According to Wikipedia:

The prototype pattern is a creational design pattern in software development. It is used when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects.

According to Gang Of Four:

Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.

UML:

When to use it?

To avoid the inherent cost of creating a new object in the standard way (e.g., using the ‘new’ keyword) when it is prohibitively expensive for a given application.

So whats happening here?

Firstly we are using two ways to clone the object

Shallow Clone: In .Net we have a method called MemberwiseClone, its a method that is available on all objects. It copies the values of all fields and any references, and returns a reference to this copy. However, it does not copy what the references in the object point to.Many objects are simple, without references to other objects, and therefore shallow copies are adequate.To preserve the complete value of the object, including all its subobjects use a deep copy.

Deep Clone: An alternative is a deep copy, meaning that fields are dereferenced: rather than references to objects being copied, new copy objects are created for any referenced objects, and references to these placed in B. The result is different from the result a shallow copy gives in that the objects referenced by the copy B are distinct from those referenced by A, and independent. Deep copies are more expensive, due to needing to create additional objects, and can be substantially more complicated, due to references possibly forming a complicated graph. In the .NET Framework they are encapsulated in a process called serialization, which can be defined by using attribute [Serializable] on the class to be serialized. Objects are copied to a given destination and can be brought back again at will. The options for serialization destinations are several, including disks and the Internet, but the easiest one for serializing smallish objects is memory itself. Thus a deep copy consists of serializing and deserializing in one method.

Then we are also using a PrototypeManager, which I mentioned earlier that its used to maintains a list of clone types and their keys so that we can retrieve an already cloned object quickly.

The main program consists of a series of experiments demonstrating the effects of cloning and deep copying.

In the first group, Australia is shallow copied. After changing of Australia’s clone, the capital is Canberra in the prototype and Sydney in the clone. The statement responsible is c2.Capital = “Sydney”;

however, changing the language to Chinese ( c2.Language.Data = “Chinese”;) also changes the prototype’s language to Chinese. That is not what we wanted. We got the error because we did a shallow copy and the language in the prototype and in the clone reference the same DeeperData object.

In the next experiment, we clone Germany using a deep copy ( c3 = manager.prototypes[“Germany”].DeepClone();).

Now changing the capital ( c3.Capital = “Munich”;) does not affect the prototype but the deep clone is affected. Similarily altering the deep state-its language to Turkish ( c3.Language.Data = “Turkish”;), shows the prototype after the changes; it is unaffected.