原型模式
2010-08-26 22:18 Clingingboy 阅读(342) 评论(0) 编辑 收藏 举报分浅拷贝和深拷贝,值得注意的地方是浅拷贝无法复制引用类型
实现方法
浅拷贝:通过调用MemberwiseClone方法
深拷贝:通过序列化来实现
来看下面接口
[Serializable()] public abstract class IPrototype <T> { public T Clone() { return (T) this.MemberwiseClone(); // Shallow copy } public T DeepCopy() { // Deep Copy MemoryStream stream = new MemoryStream(); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(stream, this); stream.Seek(0, SeekOrigin.Begin); T copy = (T) formatter.Deserialize(stream); stream.Close(); return copy; } }
为了区分浅拷贝和深拷贝的区别,在对象中再定义一个引用类型,为了实现深拷贝,都需要加上Serializable元数据
[Serializable()] // Helper class used to create a second level data structure class DeeperData { public string Data {get; set;} public DeeperData(string s) { Data = s; } public override string ToString () { return Data; } } [Serializable()] class Prototype : IPrototype <Prototype> { // Content members public string Country {get; set;} public string Capital {get; set;} public DeeperData Language {get; set;} public Prototype (string country, string capital, string language) { Country = country; Capital = capital; Language = new DeeperData(language); } public override string ToString() { return Country+"\t\t"+Capital+"\t\t->"+Language; } }
客户端测试调用
class PrototypeClient : IPrototype <Prototype> { static void Report (string s, Prototype a, Prototype b) { Console.WriteLine("\n"+s); Console.WriteLine("Prototype "+a+"\nClone "+b); } static void Main () { PrototypeManager manager = new PrototypeManager(); Prototype c2, c3; // Make a copy of Australia's data c2 = manager.prototypes["Australia"].Clone(); Report("Shallow cloning Australia\n===============", manager.prototypes["Australia"], c2); // Change the capital of Australia to Sydney c2.Capital = "Sydney"; Report("Altered Clone's shallow state, prototype unaffected", manager.prototypes["Australia"], c2); // Change the language of Australia (deep data) c2.Language.Data = "Chinese"; Report("Altering Clone deep state: prototype affected *****", manager.prototypes["Australia"], c2); // Make a copy of Germany's data c3 = manager.prototypes["Germany"].DeepCopy(); Report("Deep cloning Germany\n============", manager.prototypes["Germany"], c3); // Change the capital of Germany c3.Capital = "Munich"; Report("Altering Clone shallow state, prototype unaffected", manager.prototypes["Germany"], c3); // Change the language of Germany (deep data) c3.Language.Data = "Turkish"; Report("Altering Clone deep state, prototype unaffected", manager.prototypes["Germany"], c3); Console.ReadKey(); } }
测试结果
/* Output
Shallow cloning Australia
===============
Prototype Australia Canberra ->English
Clone Australia Canberra ->English
Altered Clone's shallow state, prototype unaffected
Prototype Australia Canberra ->English
Clone Australia Sydney ->English
Altering Clone deep state: prototype affected *****浅拷贝结果
Prototype Australia Canberra ->Chinese
Clone Australia Sydney ->Chinese
Deep cloning Germany
============
Prototype Germany Berlin ->German
Clone Germany Berlin ->German
Altering Clone shallow state, prototype unaffected
Prototype Germany Berlin ->German
Clone Germany Munich ->German
Altering Clone deep state, prototype unaffected深拷贝结果
Prototype Germany Berlin ->German
Clone Germany Munich ->Turkish
*/
该模式在维护对象状态的时候,或者重复使用该对象的时候特别有用.