.Net設計模式_原型模式

引言:html

原型,感受就是拷貝,只是給拷貝分了深拷貝和淺拷貝。this

 

理解:spa

在C#.Net裏面,咱們能夠很容易的經過Clone()方法實現原型模式。.net

任何類,只要想支持克隆,必須實現C#中的ICloneable接口。設計

ICloneable接口中有一Clone方法,能夠在類中複寫實現自定義的克隆方法。指針

克隆的實現方法有兩種:淺拷貝(shallow copy)與深拷貝(deep copy)。code

說明:淺拷貝是指當對象的字段值被拷貝時,字段引用的對象不會被拷貝。而深拷貝是對對象實例中字段引用的對象也進行拷貝的一種方式。htm

UML圖:(出之http://www.cnblogs.com/zhenyulu/articles/39257.html對象

 

示例代碼:blog

public interface IObjectOne
{
    IObjectOne Clone();
    void Write();
}
// Object
public class Object1 : IObjectOne
{
    public String _val = "A";
    public User _user = new User();

    public IObjectOne Clone()
    {
        _user.Name = "A name";
        return (IObjectOne)this.MemberwiseClone();
    }

    public void Write()
    {
        Console.WriteLine(_user.Name);
        Console.WriteLine("Object " + _val);
    }
}
// 實體
public class User
{
    public String Name { get; set; }
}

調用

static void Main(string[] args)
{
    Object1 obj = new Object1();
    Object1 objCopy = (Object1)obj.Clone();
    // 值類型
    objCopy._val = "AA";
    // 引用類型
    objCopy._user.Name = "AA name";
    objCopy.Write();

    obj.Write();

    Console.ReadKey();
}

結果

從結果咱們看出,MemberwiseClone方法是淺拷貝,由於只有值類型的被拷貝了,引用類型的沒有被拷貝。

理解拷貝:

public interface IObjectTwo
{
    // 淺拷貝
    IObjectTwo Clone();
    // 深拷貝
    IObjectTwo DeepClone(String name);
    // 輸出
    void Write();
}

public class Object3 : IObjectTwo
{
    public String _val = "A";
    public User _user = new User();

    public Object3()
    {
        _user.Name = "A name";
    }
    // 淺拷貝
    public IObjectTwo Clone()
    {
        return (IObjectTwo)this.MemberwiseClone();
    }
    // 深拷貝
    public IObjectTwo DeepClone(String name)
    {
        Object3 nowObj = new Object3();
        User obj = new User();
        obj.Name = name;

        nowObj._val = this._val;
        nowObj._user = obj;

        return (IObjectTwo)nowObj;
    }
    // 輸出
    public void Write()
    {
        Console.WriteLine(_user.Name);
        Console.WriteLine("Object " + _val);
    }
}
static void Main(string[] args)
{
    Object1 obj = new Object1();
    Object1 objCopy = (Object1)obj.Clone();
    // 值類型
    objCopy._val = "AA";
    // 引用類型
    objCopy._user.Name = "AA name";
    objCopy.Write();
    obj.Write();

    Console.WriteLine();
    Console.WriteLine("--------------------");
    Console.WriteLine();

    Object3 nowObj = new Object3();

    Object3 objCopy2 = (Object3)nowObj.Clone();
    objCopy2._val = "XX";
    objCopy2._user.Name = "XX name";
    objCopy2.Write();
    // 深拷貝
    Object3 objCopy3 = (Object3)nowObj.DeepClone("My Name");
    objCopy3._val = "YY";
    objCopy3.Write();
    objCopy3._user.Name = "Test";
    objCopy3.Write();

    nowObj.Write();

    Console.ReadKey();
}
}

結果:

從結果知道,拷貝一個引用類型,必定是New這個對象。這個其實跟堆棧有關,當new一個對象時,會在堆上面新分配一個區域,用於新對象的存儲。

可是給一個引用對象賦值另外一個引用對象時,是把引用的指針給了對象,並無從新分配存儲區域,因此修改這個對象就會影響,整個上下文中的這個對象,

由於,修改的是一個存儲區域。

 

總結:(出之http://www.cnblogs.com/zhenyulu/articles/39257.html)

一、Prototype模式容許動態增長或減小產品類。因爲建立產品類實例的方法是產批類內部具備的,所以增長新產品對整個結構沒有影響。
二、Prototype模式提供了簡化的建立結構。工廠方法模式經常須要有一個與產品類等級結構相同的等級結構,而Prototype模式就不須要這樣。
三、Portotype模式具備給一個應用軟件動態加載新功能的能力。因爲Prototype的獨立性較高,能夠很容易動態加載新功能而不影響老系統。
四、產品類不須要非得有任何事先肯定的等級結構,由於Prototype模式適用於任何的等級結構。

 

應用場景:

如:一個方法,裏面的參數是一個實體類,ProcessMessage(User userInfo),而調用這個方法的方法是ReturnProcess()

public void ReturnProcess(){

  User userInfo = new User();
      // 調用前

  ......

  ProcessMessage(userInfo);

  

  //調用後

  ......
}

那麼,在ProcessMessage修改對象uerInfo,會直接影響到 調用後,userInfo的值。

因此在一些設計中須要考慮子方法中修改對象帶來的影響,

因此咱們須要深拷貝和淺拷貝。

也就是咱們說的原型模式。

 

代碼下載:

百度網盤 http://pan.baidu.com/s/1c0iSVlu

CSDN  http://download.csdn.net/detail/hater22/6847203

相關文章
相關標籤/搜索