引言:

原型,感觉就是拷贝,只是给拷贝分了深拷贝和浅拷贝。

理解:

在C#.Net里面,我们可以很容易的通过Clone()方法实现原型模式。

任何类,只要想支持克隆,必须实现C#中的ICloneable接口。

ICloneable接口中有一Clone方法,可以在类中复写实现自定义的克隆方法。

克隆的实现方法有两种:浅拷贝(shallow copy)与深拷贝(deep copy)。

说明:浅拷贝是指当对象的字段值被拷贝时,字段引用的对象不会被拷贝。而深拷贝是对对象实例中字段引用的对象也进行拷贝的一种方式。

UML图:(出之http://www.cnblogs.com/zhenyulu/articles/39257.html

示例代码:

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)

1、Prototype模式允许动态增加或减少产品类。由于创建产品类实例的方法是产批类内部具有的,因此增加新产品对整个结构没有影响。
2、Prototype模式提供了简化的创建结构。工厂方法模式常常需要有一个与产品类等级结构相同的等级结构,而Prototype模式就不需要这样。
3、Portotype模式具有给一个应用软件动态加载新功能的能力。由于Prototype的独立性较高,可以很容易动态加载新功能而不影响老系统。
4、产品类不需要非得有任何事先确定的等级结构,因为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

.Net设计模式_原型模式的更多相关文章

  1. 【GOF23设计模式】原型模式

    来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_原型模式.prototype.浅复制.深复制.Cloneable接口  浅复制 package com.test.prot ...

  2. java设计模式4——原型模式

    java设计模式4--原型模式 1.写在前面 本节内容与C++语言的复制构造函数.浅拷贝.深拷贝极为相似,因此建议学习者可以先了解C++的该部分的相关知识,或者学习完本节内容后,也去了解C++的相应内 ...

  3. 设计模式_11_原型模式(prototype)深拷贝、浅拷贝

    设计模式_11_原型模式(prototype) 浅拷贝: package designPatternOf23; /** * 定义:用原型实例,指定创建对象的种类,并通过拷贝这些原型创建新的对象 * P ...

  4. C#设计模式(6)——原型模式(Prototype Pattern)

    一.引言 在软件系统中,当创建一个类的实例的过程很昂贵或很复杂,并且我们需要创建多个这样类的实例时,如果我们用new操作符去创建这样的类实例,这未免会增加创建类的复杂度和耗费更多的内存空间,因为这样在 ...

  5. 乐在其中设计模式(C#) - 原型模式(Prototype Pattern)

    原文:乐在其中设计模式(C#) - 原型模式(Prototype Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 原型模式(Prototype Pattern) 作者:weba ...

  6. C#设计模式之六原型模式(Prototype)【创建型】

    一.引言 在开始今天的文章之前先说明一点,欢迎大家来指正.很多人说原型设计模式会节省机器内存,他们说是拷贝出来的对象,这些对象其实都是原型的复制,不会使用内存.我认为这是不对的,因为拷贝出来的每一个对 ...

  7. C#设计模式之五原型模式(Prototype Pattern)【创建型】

    一.引言 在开始今天的文章之前先说明一点,欢迎大家来指正.很多人说原型设计模式会节省机器内存,他们说是拷贝出来的对象,这些对象其实都是原型的复制,不会使用内存.我认为这是不对的,因为拷贝出来的每一个对 ...

  8. C#设计模式(6)——原型模式(Prototype Pattern)(转)

    一.引言 在软件系统中,当创建一个类的实例的过程很昂贵或很复杂,并且我们需要创建多个这样类的实例时,如果我们用new操作符去创建这样的类实例,这未免会增加创建类的复杂度和耗费更多的内存空间,因为这样在 ...

  9. C#设计模式(6)——原型模式(Prototype Pattern) C# 深浅复制 MemberwiseClone

    C#设计模式(6)——原型模式(Prototype Pattern)   一.引言 在软件系统中,当创建一个类的实例的过程很昂贵或很复杂,并且我们需要创建多个这样类的实例时,如果我们用new操作符去创 ...

随机推荐

  1. [译]GotW #3: Using the Standard Library (or, Temporaries Revisited)

    高效的代码重用是良好的软件工程中重要的一部分.为了演示如何更好地通过使用标准库算法而不是手工编写,我们再次考虑先前的问题.演示通过简单利用标准库中已有的算法来避免的一些问题. Problem JG Q ...

  2. 11个强大的Visual Studio调试小技巧(转)

    简介 调试是软件开发周期中很重要的一部分.它具有挑战性,同时也很让人疑惑和烦恼.总的来说,对于稍大一点的程序,调试是不可避免的.最近几年,调试工具的发展让很多调试任务变的越来越简单和省时. 这篇文章总 ...

  3. Linux学习之CentOS6下Mysql数据库的安装与配置

    转自:http://www.cnblogs.com/xiaoluo501395377/archive/2013/04/07/3003278.html 如果要在Linux上做j2ee开发,首先得搭建好j ...

  4. BZOJ2741: 【FOTILE模拟赛】L

    2741: [FOTILE模拟赛]L Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 1170  Solved: 303[Submit][Status] ...

  5. [转]ASP.NET MVC 入门2、项目的目录结构与核心的DLL

    我们新建一个ASP.NET MVC的Web Application后,默认的情况下,项目的目录结构如下: App_Data :这个目录跟我们一般的ASP.NET website是一样的,用于存放数据. ...

  6. arm linux kernel启动之start_kernel

    了解完kernel启动以前的汇编之后我们来看看正式的c语言启动代码,也就是我们的start_kernel函数了.start_kernel相当大,里面每一个调用到的函数都足够我们伤脑筋了,我这里只是浅尝 ...

  7. VMWare虚拟机USB连接问题

    错误31:连接到系统上的设备没有发挥作用 原文链接 描述 常用 VMware 虚拟机的有事应该遇到这种情况,就是装完 VMware ,启动时 VMware 下面会有个黄框中有" USB di ...

  8. HW2.3

    import java.util.Scanner; public class Solution { public static void main(String[] args) { final dou ...

  9. HDU4417 - Super Mario(主席树)

    题目大意 给定一个数列,每次要求你查询区间[L,R]内不超过K的数的数量 题解 和静态的区间第K大差不多,这题是<=K,先建立好n颗主席树,然后用第R颗主席树区间[1,K]内数的数量减去第L-1 ...

  10. JQuery Dialog 禁用X按钮关闭对话框,-摘自网络

    JQuery Dialog 禁用X按钮关闭对话框,禁用ESC键关闭代码如下:$("#div1").dialog({   closeOnEscape: false,   open: ...