[Design Pattern] 原型模式(Portotype)

[Design Pattern] 原型模式(Portotype)

所謂的原型模式,就是利用原本已經有的物件,然後進行複製的操作,來節省重覆的邏輯和運算。例如:很多件一樣大小、顏色的衣服,但只有上面寫的英文字不同,這時候只要先製造出第一件衣服,接下來的衣服都可以用複製的方式製造,最後再修改一下上面印的英文字就可以了。

 

在程式中,因為有實質形別和參考形別的區別,所以在使用原型模式時,也有區分所謂的「淺複製」以及「深複製」。

淺複製:複製所有的欄位,但參考形別只複製參考,不是複製被參考的件物。

深複製:複製並建立全新的物件。

 

淺複製我們可以用Object.MemberwiseClone來看:(建立一個Color的物件,裡面包含一個RGB物件,然後利用MemberwiseClone做淺複製)


Color b = (Color)a.ShallowClone();
a.ID = 1;
Console.WriteLine(b.ToString());
a.RGB.R = 0;
Console.WriteLine(b.ToString());
Console.ReadKey();

當我變更了原型a的實質形別欄位時,並不會影響複本b,但因為a和b同樣都是參考到同一個RGB物件,所以就會受到影響:

image

 

深複製因為操作比較複雜,可以用序列化來處理比較快速,我們可以宣告實作ICloneable來進行這件事:


public class RGB
{
    public int R { get; set; }
    public int G { get; set; }
    public int B { get; set; }

    public RGB(int r, int g, int b)
    {
        this.R = r;
        this.G = g;
        this.B = b;
    }
}

[Serializable]
public class Color:ICloneable
{
    public int ID { get; set; }
    public RGB RGB { get; set; }

    public Color(int id, int r, int g, int b)
    {
        ID = id;
        this.RGB = new RGB(r, g, b);
    }

    public override string ToString()
    {
        return String.Format("ID:{0}, RGB({1}, {2}, {3})", ID, RGB.R, RGB.G, RGB.B); ;
    }

    public Color ShallowClone()
    {
        //淺複製
        return (Color)this.MemberwiseClone();
    }

    public object Clone()
    {
        MemoryStream stream = new MemoryStream();
        BinaryFormatter formatter = new BinaryFormatter();
        formatter.Serialize(stream, this);
        stream.Position = 0;
        return formatter.Deserialize(stream) as Color;
    }
}

這時候b就會是一個全新的物件了~

image

 

Dotblogs 的標籤: