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
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
We can see from the above code that:
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.
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.
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";
}
ThemeSettings = "ThemeSettings1";
UserSettings = "UserSettings1";
}
public string
ApplicationSettings
{
get;
set;
}
{
get;
set;
}
public string
ThemeSettings
{
get;
set;
}
{
get;
set;
}
public string
UserSettings
{
get;
set;
}
{
get;
set;
}
public object
Clone()
{
return this.MemberwiseClone();
}
{
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();
{
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.WriteLine("INSTANCE 2: " + settingsClone.ToString());
Console.ReadKey(false);
}
On executing the application we can see the following results.
}
On executing the application we can see the following results.
We can see from the above code that:
-
Instance 1 was created using new keyword
-
Instance 2 was created using Clone() method
-
Changing of Instance 2 does not affect Instance 1
So this concludes our experiment with the
Prototype pattern.
References:
No comments:
Post a Comment