In this article I would like to explain the Prototype Pattern and C# support for
it. 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.
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.
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
http://sourcemaking.com/design_patterns/prototype
Summary
In this article we have explored the Prototype pattern. The usage of Prototype
pattern can be summarized as:
-
Faster instance creation with required
properties
-
The new keyword can be avoided in instance
creation
-
Provides an alternative to Abstract Factory
pattern
-
Runtime specification of instance properties
-
Reference of concrete class can be avoided
The associated source code contains the example we
discussed.