今天要來介紹Prototype模式,簡單來說就是「複製」,在第19天時我們有提到說建立物件池去保存昂貴物件,那麼當我現在已經財富自由了,不用去管制購買機器的數量,只要求快點將昂貴的機器製造出來,這時候就可以使用「複製」的方式去複製昂貴物件,減少製作昂貴物件可能帶來的負擔。
我們先來介紹 淺拷貝 & 深拷貝
用原型的實例來指定創建的對象種類,並通過複製這些原型創造新的對象。
(圖片來源:https://www.dofactory.com/img/diagrams/net/prototype.png)
BookPrototype
為抽象類別,定義ShallowClone()
以及DeepClone()
兩種複製方法。MemberwiseClone()
方法。DeepClone()
中將 Color
(引用型別)重新建置並指派,因此新物件和原物件兩個的Color
就對應到不同參照位置的個體,就算有更動屬性值也不會互相影響。using System;
namespace DAY21_Prototype
{
internal class Program
{
static void Main(string[] args)
{
// 淺拷貝
Book BookShallow = new Book("雜誌",new Color(255, 0, 0));
var BookShallowCopy = (Book)BookShallow.ShallowClone();
BookShallowCopy.name = "漫畫";
BookShallowCopy.color.green = 100;
Console.WriteLine($"淺拷貝 | 書名:{BookShallow.name},顏色RGB:{BookShallow.color.red},{BookShallow.color.green},{BookShallow.color.blue}");
Console.WriteLine($"淺拷貝 | 書名:{BookShallowCopy.name},顏色RGB:{BookShallowCopy.color.red},{BookShallowCopy.color.green},{BookShallowCopy.color.blue}");
Console.WriteLine("-------------");
// 深拷貝
Book BookDeep = new Book("雜誌", new Color(255, 0, 0));
var BookDeepCopy = (Book)BookDeep.DeepClone();
BookDeepCopy.name = "漫畫";
BookDeepCopy.color.green = 100;
Console.WriteLine($"淺拷貝 | 書名:{BookDeep.name},顏色RGB:{BookDeep.color.red},{BookDeep.color.green},{BookDeep.color.blue}");
Console.WriteLine($"淺拷貝 | 書名:{BookDeepCopy.name},顏色RGB:{BookDeepCopy.color.red},{BookDeepCopy.color.green},{BookDeepCopy.color.blue}");
Console.ReadKey();
}
}
public abstract class BookPrototype
{
public abstract BookPrototype ShallowClone();
public abstract BookPrototype DeepClone();
}
public class Book : BookPrototype
{
public string name;
public Color color;
public Book(string name, Color color)
{
this.color = color;
this.name = name;
}
public override BookPrototype ShallowClone()
{
// C# 淺拷貝使用 MemberwiseClone() 方法
return (BookPrototype)this.MemberwiseClone();
}
public override BookPrototype DeepClone()
{
// C# 深拷貝,建立新 Color 物件,使指派的記憶體位置不同
BookPrototype deepClone = (BookPrototype)this.MemberwiseClone();
((Book)deepClone).color = new Color(color.red, color.green, color.blue);
return deepClone;
}
}
public class Color
{
public int red;
public int green;
public int blue;
public Color(int red, int green, int blue)
{
this.red = red;
this.green = green;
this.blue = blue;
}
}
}
我們今天介紹了Prototype模式,也簡單說明了淺拷貝與深拷貝,所以就Prototype模式而言,不管我們用淺拷貝(Shallow Clone)還是深拷貝(Deep Clone)的方式來複製物件,都還是透過一個已經存在的實例來返回新的實例,而不是新建實例。因此當要製作昂貴物件時,就能夠減少成本,增加物件建構的效率。