設計模式學習總結-原型模式(Prototype Method)

來源:互聯網
上載者:User

問題:
在程式設計中,我們可能由於某種特定的需要,複製一個對象的結構,與對象的值,動態擷取擷取對象運行時的狀態,最簡單的解決辦法是 new 一個對象新的對象,然後將對象的屬性值一一賦值給新的對象,這樣要一一列出對象的屬性賦值,操作起來太複雜,而且及其容易出錯,落下某個屬性的賦值。能否讓對象本身提供一個自我複製的功能,用戶端只需簡單的調用這個方法就能完成對象的複製。

定義:

用原型執行個體指定建立對象的種類,並且通過拷貝這些原型建立新的對象。 

意圖:
Prototype模式允許一個已存在的對象通過建立的介面(Clone),通過拷貝自己來實施建立另外一個可定製的對象(定製好屬性值然後批量複製),根本無需知道任何如何建立的細節。Clone)。
Clone()實現和具體的實現語言相關。.NET中一般使用Object的MemberwiseClone()方法建立對象的淺表副本實現淺複製。
參與者:
•Prototype(抽象原型)角色:
抽象原型角色:這是一個抽象角色,通常由一個介面或抽象類別實現。此角色給出所有的具體原型類所需的介面(.NET提供了一個定義方法Clone()方法的ICloneable介面,作為系統中的通用Prototype)。

•ConcretePrototype(抽象原型)角色:
被複製的對象。此角色需要實現抽象的原型角色所要求的介面。實現具體的對象複製方法。

UML:

 

淺複製與深複製:

•淺複製:如果欄位是實值型別的(包括string),則對該欄位執行逐位複製,如欄位是參考型別,則複製引用但不自製引用的對象。因此,原始對象及其複本引用同一對象。通過Object的MemberwiseClone()方法即可實現。
•深複製:如果欄位是實值型別的,則對該欄位執行逐位複製,如欄位是參考型別,則複製引用對象的變數指向複製過的新對象,而不是原有的被引用的對象。讓子類也繼承Prototype角色幾口實現Clone()方法,使用逐層複製賦值參考型別欄位的辦法完成。

執行個體說明:

諾基亞手機工廠
同款型號的手機生產多個不用每次都要通過生產工廠,可以根據已生產好的某款通過複製的辦法來完成。

uml圖如下:

 

代碼:

淺複製:

/// <summary>
/// 抽象原型角色
/// </summary>
public interface IPrototypePhone
{
    object Clone();
}
/// <summary>
/// 具體原型角色
/// </summary>
public class ConcretePrototypePhone : IPrototypePhone
{
    public string Name { get; set; }
    public string Cpu { get; set; }
    public string Mb { get; set; }
    public float MemorySize { get; set; }
    public string System { get; set; }

    public object Clone()
    {
        //使用內建MemberwiseClone()方法複製對象
        return this.MemberwiseClone();
    }
}
public void PrototypeTest()
{

    ConcretePrototypePhone obj = new ConcretePrototypePhone();
    obj.Cpu = "ARM_27";
    obj.Mb = "N8_1op";
    obj.MemorySize = 375;
    obj.Name = "N8";
    obj.System = "塞班";
    var n8 = obj.Clone();
}

深複製:

/// <summary>
/// 具體原型角色,實現.net提供的通用 抽象原型角色System.ICloneable
/// </summary>
public class ConcretePrototypePhone : System.ICloneable
{
    public string Name { get; set; }
    public ConcretePrototypeCpu Cpu { get; set; }
    public string Mb { get; set; }
    public float MemorySize { get; set; }
    public string System { get; set; }

    public object Clone()
    {
        //看複製父物件
        ConcretePrototypePhone obj = (ConcretePrototypePhone)this.MemberwiseClone();
        //複製子物件,將子物件的引用指向複製出的新對象
        obj.Cpu = (ConcretePrototypeCpu)this.Cpu.Clone();
        return obj;
    }
}
public class ConcretePrototypeCpu : System.ICloneable
{
    public string Name { get; set; }
    public float Frequency { get; set; }
    public object Clone()
    {
        return this.MemberwiseClone();
    }
}
public void PrototypeTest()
{

    ConcretePrototypePhone obj = new ConcretePrototypePhone();
    obj.Cpu = new ConcretePrototypeCpu() { Frequency = 2.4F, Name = "Ar700" };
    obj.Mb = "N8_1op";
    obj.MemorySize = 375;
    obj.Name = "N8";
    obj.System = "塞班";
    ConcretePrototypePhone n8 = (ConcretePrototypePhone)obj.Clone();
    n8.Cpu = new ConcretePrototypeCpu() { Frequency = 2.0F, Name = "Ar70" };
}

 優點:
•可在不用重新初始化對象,而是動態地擷取對象運行時的狀態。
•屏蔽對象的複製細節,用戶端無需關心複製細節,對象的複製被封閉在對象內部,怎麼樣複製有對象本身決定。
•在某些環境下,複製對象比建立新對象更有效,因為對象的建構函式是不會執行的。
缺點:
•實現深層複製時實現比較複雜。

應用情景:
•複製對象的結構與資料。
•希望對目標對象的修改不影響既有的原型對象。
•建立對象成本較大的情況下(初始化需佔用較長時間,佔用太多CPU資源或網路資)
PS:
•在調用MemberwiseClone進行淺複製時,原型模式是記憶體二進位流的拷貝,建構函式是不會執行的。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.