天天看點

一起談.NET技術,.Net Framework源代碼中的模式之Prototype(原型模式)

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

一起談.NET技術,.Net Framework源代碼中的模式之Prototype(原型模式)

  以.NET Framework 2.0 System.Collections中類為例。

一起談.NET技術,.Net Framework源代碼中的模式之Prototype(原型模式)

  System.Collections. ICollection

public interface ICollection : IEnumerable

{

}

  System.Collections. ICloneable 

public interface ICloneable

  object Clone();

  System.Collections. Stack

一起談.NET技術,.Net Framework源代碼中的模式之Prototype(原型模式)

public class Stack : ICollection, ICloneable

  public virtual Object Clone()

  {

    Stack s = new Stack(_size);

    s._size = _size;

    Array.Copy(_array, 0, s._array, 0, _size);

    s._version = _version;

    return s;

  }

  System.Collections. Queue

一起談.NET技術,.Net Framework源代碼中的模式之Prototype(原型模式)

public class Queue : ICollection, ICloneable

   Queue q = new Queue(_size);

   q._size = _size;

   int numToCopy = _size;

   int firstPart = (_array.Length - _head < numToCopy) ? _array.Length - _head : numToCopy;

   Array.Copy(_array, _head, q._array, 0, firstPart);

   numToCopy -= firstPart;

   if (numToCopy > 0)

   Array.Copy(_array, 0, q._array, _array.Length - _head, numToCopy);

   q._version = _version;

   return q;

  調用代碼

一起談.NET技術,.Net Framework源代碼中的模式之Prototype(原型模式)

public class Client

  public static void Main()

    Stack myStack = new Stack();

    myStack.Push("Hello");

    myStack.Push("World");

    myStack.Push("!");

    Stack myStackCopy = (Stack)myStack.Clone(); 

    foreach (string s in myStackCopy)

    {

      Console.Write(s);

    }

    Console.WriteLine();

    Console.ReadLine();

  在.NET Framework中,可以通過實作ICloneable接口來實作原型模式,ICloneable接口隻有一個Clone方法。克隆的實作方法有兩種:淺拷貝(shallow copy)與深拷貝(deep copy)。

  淺拷貝是指當對象的字段值被拷貝時,字段引用的對象不會被拷貝。例如,如果一個對象有一個指向字元串的字段,并且我們對該對象做了一個淺拷貝,那麼兩個對象将引用同一個字元串。而深拷貝是對對象執行個體中字段引用的對象也進行拷貝的一種方式,是以如果一個對象有一個指向字元串的字段,并且我們對該對象做了一個深拷貝的話,我們将建立一個新的對象和一個新的字元串--新對象将引用新字元串。需要注意的是執行深拷貝後,原來的對象和新建立的對象不會共享任何東西;改變一個對象對另外一個對象沒有任何影響。

  對于值類型,淺拷貝通過指派等操作直接實作,将對象中的值類型的字段拷貝到新的對象中;深拷貝和淺拷貝相同,通過指派等操作直接實作,将對象中的值類型的字段拷貝到新的對象中。 對于引用類型,淺拷貝通過MemberwiseClone 方法建立一個淺副本,方法是建立一個新對象,如果字段是值類型的,則對該字段執行逐位複制,如果字段是引用類型,則複制引用原始對象,與原對象引用同一對象;深拷貝拷貝對象應用,也拷貝對象實際内容,也就是建立了一個新的對象,改變新對象不會影響到原始對象的内容。

  在下列情況下,應當使用Prototype模式:

當一個系統應該獨立于它的産品建立,構成和表示時;

當要執行個體化的類是在運作時刻指定時,例如,通過動态裝載;

為了避免建立一個與産品類層次平行的工廠類層次時;

當一個類的執行個體隻能有幾個不同狀态組合中的一種時。建立相應數目的原型并克隆它們可能比每次用合适的狀态手工執行個體化該類更友善一些。