Prototype Pattern的四個要素:
- 模式名稱:
Prototype Pattern(原型模式)
- 問題:
當需要建立多個具有相同或類似屬性的物件時,使用傳統的建立方式可能會導致程式碼重複和效率低下。
- 解決方案:
Prototype Pattern透過使用已有的物件來複製建立新物件,從而避免了程式碼重複和效率低下的問題。
- 結果:
使用Prototype Pattern可以更加靈活地建立和管理物件,並且可以提高程式碼的重用性和可維護性。
實作
在C#中實現原型模式,我們可以使用兩種不同的複製方式:淺層複製和深層複製。
淺層複製
淺層複製(Shallow Cpoy)是指複製物件時,只複製物件本身及其所有值類型的成員變數,而不複製物件的參考類型成員變數。這意味著複製後的物件和原始物件仍然共享參考類型成員變數,因此對複製物件或原始物件的參考類型成員變數進行修改,將會影響到另一個物件,可以透過實現ICloneable介面來實現。
public class MyClass : ICloneable
{
public int Value;
public List<int> List;
public object Clone()
{
return MemberwiseClone();
}
}
public class Program
{
static void Main(string[] args)
{
MyClass original = new MyClass();
original.Value = 1;
original.List = new List<int>() { 1, 2, 3 };
MyClass clone = (MyClass)original.Clone();
clone.Value = 2;
clone.List[0] = 4;
Console.WriteLine(original.Value); // Output: 1
Console.WriteLine(clone.Value); // Output: 2
Console.WriteLine(original.List[0]); // Output: 4
Console.WriteLine(clone.List[0]); // Output: 4
}
}
在這個範例程式碼中,我們定義了一個MyClass類別,它實現了ICloneable介面並定義了Value和List成員變數。
在Main方法中,我們建立了一個original物件並設定其Value和List成員變數。然後我們透過調用Clone方法來複製這個物件並設定複製物件的Value和List成員變數。
最後,我們輸出了original和clone物件的Value和List成員變數,結果顯示出對clone物件的List成員變數進行修改同時也修改了original物件的List成員變數, 這是因為兩個物件仍然共享同一個List物件的參考。
深層複製
如果希望深層複製(Deep Copy)物件,從而完全分離原始物件和複製物件。這種方式需要實現自己的Clone方法,而不是使用ICloneable介面(視情況可以使用遞迴的方式複製樹狀結構等情境)。
以下是深複製的範例程式碼:
public class MyClass
{
public int Value;
public List<int> List;
public MyClass Clone()
{
MyClass clone = new MyClass();
clone.Value = Value;
clone.List = new List<int>(List);
return clone;
}
}
public class Program
{
static void Main(string[] args)
{
MyClass original = new MyClass();
original.Value = 1;
original.List = new List<int>() { 1, 2, 3 };
MyClass clone = original.Clone();
clone.Value = 2;
clone.List[0] = 4;
Console.WriteLine(original.Value); // Output: 1
Console.WriteLine(clone.Value); // Output: 2
Console.WriteLine(original.List[0]); // Output: 1
Console.WriteLine(clone.List[0]); // Output: 4
}
}
在這個示例程式碼中,我們定義了一個MyClass類別,它定義了Value和List成員變數,並定義了自己的Clone方法。
在Main方法中,我們建立了一個original物件並設定其Value和List成員變數。然後我們透過調用Clone方法來複製這個物件並設定複製物件的Value和List成員變數。在複製List成員變數時,我們使用了List的複製建構子(Copy Constructor)來複製List物件本身。
最後,我們輸出了original和clone物件的Value和List成員變數,結果顯示出對clone物件的List成員變數進行修改並不會影響original物件的List成員變數,這是因為兩個物件已經完全分離。
總之,Prototype模式是一種創建型設計模式,它可以通過複製現有物件來創建新物件,從而避免直接創建物件所帶來的開銷和複雜性。要實現Prototype模式,可以使用ICloneable介面或自己的Clone方法,並分別實現Shadow Clone和Deep Clone的方式來複製物件。在C#中,可以使用ICloneable介面或自己的Clone方法來實現Prototype模式,並透過複製建構子來複製成員變數,從而實現Shadow Clone和Deep Clone的方式。