原型模式是一種對象建立型模式,它將一個原型對象傳遞給一個要發起建立的對象,該對象經過請求原型對象複製本身來實現建立過程。編程
因爲軟件系統中常常會出現須要建立多個相同或類似的對象,所以原型模式在開發中具備較高的使用頻率。經過原型模式克隆出來的對象屬於全新的對象,它們在內存中擁有本身的內存地址,對克隆對象的修改不會影響原型對象,而且每個克隆對象都是相互獨立的。網絡
在淺克隆中,若是原型對象的成員變量是值類型,將會複製一份給克隆對象;若是成員變量是引用類型,則將引用類型的地址複製一份給克隆對象,也就是說克隆對象與原型對象的成員變量指向相同的內存地址。即淺克隆的時候,只複製原型對象自己和它的值類型成員,而引用類型的成員並無複製。ide
深克隆的時候,原型對象中的值類型成員和引用類型成員都將複製給克隆對象,即深克隆除了複製對象自己之外,對象所包含的全部成員也將被複制。this
abstract class ProtoType { public abstract ProtoType Clone(); } class ProtoTypeA : ProtoType { private string m_Attr; public string Attr { get { return this.m_Attr; } set { this.m_Attr = value; } } public override ProtoType Clone() { var o = new ProtoTypeA(); o.Attr = this.m_Attr; return o; } } static void Main() { //使用 var prototypeA = new ProtoTypeA(); var copy = prototypeA.Clone(); }
在C#語言中,提供了MemberwiseClone方法用於實現淺克隆,修改代碼以下:spa
class ProtoTypeA : ProtoType { private string m_Attr; public string Attr { get { return this.m_Attr; } set { this.m_Attr = value; } } private Member m_Member; public Member Member { get { return this.m_Member; } set { this.m_Member = value; } } public override ProtoType Clone() { return (ProtoTypeA)this.MemberwiseClone(); } }
static void Main() { var prototypeA = new ProtoTypeA(); var copy = (ProtoTypeA)prototypeA.Clone(); Console.WriteLine(prototypeA == copy); //false Console.WriteLine(prototypeA.Attr == copy.Attr); //true Console.WriteLine(prototypeA.Member == copy.Member); //true,證實爲淺克隆 Console.ReadKey(); }
public override ProtoType Clone() { var copy = (ProtoTypeA)this.MemberwiseClone(); copy.Member = new Member(); return copy; } static void Main() { var prototypeA = new ProtoTypeA(); var copy = (ProtoTypeA)prototypeA.Clone(); Console.WriteLine(prototypeA == copy); //false Console.WriteLine(prototypeA.Attr == copy.Attr); //true Console.WriteLine(prototypeA.Member == copy.Member); //false,證實爲深克隆 Console.ReadKey(); }
[Serializable] abstract class ProtoType { public abstract ProtoType Clone(); } [Serializable] class Member { } [Serializable] class ProtoTypeA : ProtoType { ... }
public override ProtoType Clone() { ProtoTypeA copy = null; using (var fs = new FileStream("Temp.txt", FileMode.Create)) { try { new BinaryFormatter().Serialize(fs, this); } catch (SerializationException e) { throw e; } } using (var fs = new FileStream("Temp.txt", FileMode.Open)) { try { copy = (ProtoTypeA)new BinaryFormatter().Deserialize(fs); } catch (SerializationException e) { throw e; } }; return copy; } static void Main() { var prototypeA = new ProtoTypeA(); prototypeA.Member = new Member(); var copy = (ProtoTypeA)prototypeA.Clone(); Console.WriteLine(prototypeA == copy); //false Console.WriteLine(prototypeA.Attr == copy.Attr); //true Console.WriteLine(prototypeA.Member == copy.Member); //false,證實爲深克隆 Console.ReadKey(); }