Views: 13.8K
Replies: 3
Archived
|
Prototype Pattern to copy/clone objectsI would like to know why following the DOF Prototype pattern is better suited than creating a simple and plain way of copying/cloning an object. Given the following base class and creational factory method class PersonBirthFactory: public class Person { public Object Firstname{ get; set; } public Object Lastname{ get; set; } } public class PersonBirthFactory { public static CreatePerson() { Person p = new Person(); p.FirstName = firstName; p.LastName = firstName; return p; } } public object DeepCopy() { MemoryStream stream = new MemoryStream(); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(stream, this); stream.Seek(0, SeekOrigin.Begin); object copy = formatter.Deserialize(stream); stream.Close(); return copy; }
public object DeepCopy() { Person p = new Person(); p.FirstName = this.FirstName; p.LastName = this.FirstName; return p; } I can implement this pattern w/o doing research and wondering the benefits here, is it just a performance increase for using this? In my current scenario the copy might happen at most 4 times in an hour, but when it happens they happen in quick sucession. I am mainly doing this to remove the logic when creating a collection and need to fill in the missing items(cloned from other items) from the factory. The offending code is complex if/then/else/loops/etc... Best suited outside the factory in another object where I may need to use in other parts of the application down the road. Looking for alternatives and would like to open a discussion on the best alternative. TIA, S Net Wreck, Sep 20, 2010
|
|
Reply 1Thanks a lot I did exactly as you said and it worked just amazing, see my output Thanks,
==================={STEP 1}== Doe, John (Mother: Doe, Jane)) Doe, John (Mother: Doe, Jane)) Doe, John (Mother: Doe, Jane)) ==================={STEP 2}== Doe, John (Mother: Doe, Jen)) Doe, John (Mother: Doe, Jen)) Doe, John (Mother: Doe, Jane))
Krutisha Chovatiya, Mar 10, 2015
|
|
Reply 2Thanks for this. Just replicated it and got:
==================={STEP 1}== Doe, John (Mother: Doe, Jane)) Doe, John (Mother: Doe, Jane)) Doe, John (Mother: Doe, Jane)) ==================={STEP 2}== Doe, John (Mother: Doe, Jen)) Doe, John (Mother: Doe, Jen)) Doe, John (Mother: Doe, Jane)) Thanks, Richard Wilcox Matthew Carey, Oct 01, 2014
|
|
Reply 3Hi,
I can think of two issues with your approach of copying the object. 1. You will need to modify your copy method each time a property changes in the Person class. 2. You copy the reference, not the object. This means that when the primary object has a member of a reference type and it changes, your copy will change too. (will provide example shortly). Hope that helps. UPDATE: Added Code example First, the Person class: [Serializable] public class Person { public Object FirstName { get; set; } public Object LastName { get; set; } public Person Mother { get; set; } public static Person CreatePerson(string firstName, string lastName) { var p = new Person { FirstName = firstName, LastName = lastName }; return p; } public override string ToString() { if( Mother != null) { return string.Format("{0}, {1} (Mother: {2})", LastName, FirstName, Mother); } else { return string.Format("{0}, {1})", LastName, FirstName); } } } Helper methods for copying: public static class PersonBirthFactory { public static Person DeepCopy(this Person person) { var stream = new MemoryStream(); var formatter = new BinaryFormatter(); formatter.Serialize(stream, person); stream.Seek(0, SeekOrigin.Begin); object copy = formatter.Deserialize(stream); stream.Close(); return copy as Person; } public static Person SimpleCopy(this Person person) { var p = new Person {FirstName = person.FirstName, LastName = person.LastName, Mother = person.Mother}; return p; } } internal class Program { private static void Main(string[] args) { var john = Person.CreatePerson("John", "Doe"); john.Mother = Person.CreatePerson("Jane", "Doe"); //var jane = Person.CreatePerson("Jane", "Doe"); var johnSimpleCopy = john.SimpleCopy(); var johnDeepCopy = john.DeepCopy(); System.Console.WriteLine("============{STEP 1}=="); System.Console.WriteLine(john); System.Console.WriteLine(johnSimpleCopy); System.Console.WriteLine(johnDeepCopy); john.Mother.FirstName = "Jen"; System.Console.WriteLine("============{STEP 2}=="); System.Console.WriteLine(john); System.Console.WriteLine(johnSimpleCopy); System.Console.WriteLine(johnDeepCopy); } } The output: ==================={STEP 1}== Doe, John (Mother: Doe, Jane)) Doe, John (Mother: Doe, Jane)) Doe, John (Mother: Doe, Jane)) ==================={STEP 2}== Doe, John (Mother: Doe, Jen)) Doe, John (Mother: Doe, Jen)) Doe, John (Mother: Doe, Jane)) As you can see from above, when chaning the Mother in object "john" "johnsimplecopy" is also changed. This means that your version of the copying only copies the reference not the object itself. Robert Blixt, Sep 21, 2010
|