Wednesday, February 15, 2012

Design Patterns : Prototype pattern Implementation

Prototype pattern falls in the section of creational pattern. It gives us a way to create new objects from the existing instance of the object. In one sentence we clone the existing object with its data. By cloning any changes to the cloned object does not affect the original object value. If you are thinking by just setting objects we can get a clone then you have mistaken it. By setting one object to other object we set the reference of object BYREF. So changing the new object also changed the original object. To understand the BYREF fundamental more clearly consider the figure ‘BYREF’ below. Following is the sequence of the below code:
  • In the first step we have created the first object i.e. obj1 from class1.
  • In the second step we have created the second object i.e. obj2 from class1.
  • In the third step we set the values of the old object i.e. obj1 to ‘old value’.
  • In the fourth step we set the obj1 to obj2.
  • In the fifth step we change the obj2 value.
  • Now we display both the values and we have found that both the objects have the new value.

Figure :- BYREf
The conclusion of the above example is that objects when set to other objects are set BYREF. So changing new object values also changes the old object value.

There are many instances when we want the new copy object changes should not affect the old object. The answer to this is prototype patterns.

Lets look how we can achieve the same using C#. In the below figure ‘Prototype in action’ we have the customer class ‘ClsCustomer’ which needs to be cloned. This can be achieved in C# my using the ‘MemberWiseClone’ method. In JAVA we have the ‘Clone’ method to achieve the same. In the same code we have also shown the client code. We have created two objects of the customer class ‘obj1’ and ‘obj2’. Any changes to ‘obj2’ will not affect ‘obj1’ as it’s a complete cloned copy.


Figure: - Prototype in action 

Another example:
The prototype pattern provides an alternative to instantiating new objects by copying the prototype of an existing one.

Challenge

You are working on an application having stored settings in the Settings class. The properties of the class are assigned inside the constructor. It involves calling the configuration file, security database, user profile database etc.

You need to pass the above instance to a component inside a library. The component could play around with the properties so we need to send only another instance of Settings. As the instance creation is expensive we need to create a copy of the above instance.

What would be the best approach?

Definition

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

Solution

We can use the Prototype pattern to address this scenario. This pattern allows us to create a new instance by prototyping an existing instance with required properties.
PrtTyPtrn1.jpg

The System.object class includes a new method named MemberwiseClone() which provides a shallow copy of the current object. Shallow copy involves copying only the value types. Coupled with ICloneable interface we can provide a Clone() method that invokes MemberwiseClone() for the Settings class.

    public class Settings : ICloneable
    {
        public Settings()
        {
            // Load ApplicationSettings from Configuration
            // Load ThemeSettings from Database
            // Load UserSettings from Database
            Thread.Sleep(3000);
// Simulate a delay for the above operations
            ApplicationSettings = "ApplicationSettings1";
            ThemeSettings = "ThemeSettings1";
            UserSettings = "UserSettings1";
        }
        public string ApplicationSettings
        {
            get;
            set;
        }
        public string ThemeSettings
        {
            get;
            set;
        }
        public string UserSettings
        {
            get;
            set;
        }
        public object Clone()
        {
            return this.MemberwiseClone();
        }
        public override string ToString()
        {
            return this.ApplicationSettings + " " +
              this.ThemeSettings + " " +
              this.UserSettings;
        }
    }


Executing the Application

Now we can try playing with the class instances. First we create an instance of Settings (which is a 3 second delay process). Later we take a clone of the Settings instance and modify the properties. We can see that the new instance was created using the Clone() method.

static void Main(string[] args)
{
    Settings settings = new Settings();
    Settings settingsClone = (Settings)settings.Clone();
    settingsClone.ApplicationSettings = "NewSettings"; // Change property
    Console.WriteLine("INSTANCE 1: " + settings.ToString());
    Console.WriteLine("INSTANCE 2: " + settingsClone.ToString());
    Console.ReadKey(false);
}

On executing the application we can see the following results.
PrtTyPtrn2.jpg

We can see from the above code that:
  1. Instance 1 was created using new keyword
  2. Instance 2 was created using Clone() method
  3. Changing of Instance 2 does not affect Instance 1
So this concludes our experiment with the Prototype pattern.

References: 
  

No comments:

Post a Comment