.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

相关文章
相关标签/搜索