转载:一、 原型(Prototype)模式

http://www.cnblogs.com/zhenyulu/articles/39257.aspx
<script type="text/javascript"> </script> <script type="text/javascript" src="http://www.cnblogs.com/WebResource.axd?d=PyW-m2hLmppJ9byT1bYEqw2&t=633198062182656250"></script> <script language="JavaScript" type="text/javascript"> function ctlent(evt,id) { if(evt.ctrlKey && evt.keyCode == 13) { try { TempSave(id); } catch(ex) { } finally { __doPostBack('AjaxHolder$PostComment$btnSubmit','') } } }</script> <script language="JavaScript" type="text/javascript">function SetReplyAuhor(author){document.getElementById('AjaxHolder_PostComment_tbComment').value+="@"+author+"/n";document.getElementById('AjaxHolder_PostComment_tbComment').focus();return false}</script> <script type="text/javascript" src="http://www.cnblogs.com/ScriptResource.axd?d=keXr1l0ODizNGwpG5umihnLbiZlZFmnBNv9PADikeydJNFn_nnzWP6nCtj5LEvCjoGqazIbHl5iuU6pakvSNXw2&t=633198062182656250"></script> <script type="text/javascript" src="http://www.cnblogs.com/ScriptResource.axd?d=keXr1l0ODiwWLTaLPM0Wf405seaw-kJY_J94dRUexb3hftiy5dT0X5GxWLiqANj30&t=633065726447066250"></script> <script type="text/javascript" src="http://www.cnblogs.com/ScriptResource.axd?d=keXr1l0ODiwWLTaLPM0Wf405seaw-kJY_J94dRUexb1YLr7RQriMsNXsDWOxc8wQub8O_qeSuZ41&t=633065726447066250"></script> <script type="text/javascript"> </script>
  博客园 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  183 随笔 :: 111 文章 :: 2652 评论 :: 142 Trackbacks
<2007年8月>
2930311234
567891011
12131415161718
19202122232425
2627282930311
2345678

公告


<script type="text/javascript">/**/ </script> <script language="javascript" type="text/javascript"> function CopyCode(key) { var divElements = document.getElementsByTagName("div"); var i; occur = 0; for(i = 0; i < divElements.length; ++i) { if(key.parentElement.parentElement.parentElement == divElements[i].parentElement) { if(occur == 1) { if(navigator.appName.indexOf('Microsoft') != -1) copyToClipboard(divElements[i].innerText); else copyToClipboard(Html2Txt(divElements[i].innerHTML)); } occur++; } } } function Html2Txt(htmlText) { str = htmlText.replace(//r/n/g, " "); str = str.replace(//r/g, " "); str = str.replace(//n/g, " "); str = str.replace(//t/g, ""); str = str.replace(/
/gi,"/r/n"); str = str.replace(/<[^>]+?>/g,""); str = str.replace(/ /g, " "); str = str.replace(/>/g, ">"); str = str.replace(/</g, "<"); str = str.replace(/&/g, "&"); return str; } function copyToClipboard(txt) { if(window.clipboardData) { window.clipboardData.clearData(); window.clipboardData.setData("Text", txt); } else if(navigator.userAgent.indexOf("Opera") != -1) { window.location = txt; } else if (window.netscape) { try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); } catch (e) { alert("您的firefox安全限制限制您进行剪贴板操作,请在地址栏中输入“about:config”将“signed.applets.codebase_principal_support”设置为“true”之后重试"); return false; } var clip = Components.classes['@mozilla.org/widget/clipboard;1'].createInstance(Components.interfaces.nsIClipboard); if (!clip) return; var trans = Components.classes['@mozilla.org/widget/transferable;1'].createInstance(Components.interfaces.nsITransferable); if (!trans) return; trans.addDataFlavor('text/unicode'); var str = new Object(); var len = new Object(); var str = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString); var copytext = txt; str.data = copytext; trans.setTransferData("text/unicode",str,copytext.length*2); var clipid = Components.interfaces.nsIClipboard; if (!clip) return false; clip.setData(trans,null,clipid.kGlobalClipboard); } } </script>

常用链接

留言簿(235)

我参与的团队

随笔档案

文章分类

文章档案

相册

<script language="JavaScript" type="text/javascript"> function SearchGoogle(key,evt,site) { if(evt.keyCode==13 || evt.keyCode==0 || evt.type =='click') { key.focus(); var keystr = encodeURIComponent(key.value); url = "http://www.google.com/search?q="; url = url+keystr; url += "&ie=UTF-8&oe=GB2312&hl=zh-CN&domains="+site+"&sitesearch="+site; window.location=url; return false; } } </script>

搜索

  •  

最新评论

评论排行榜

  • <script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"> </script> width="180" scrolling="no" height="150" frameborder="0" allowtransparency="true" hspace="0" vspace="0" marginheight="0" marginwidth="0" src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-4210569241504288&dt=1186550827750&lmt=1186550803&prev_fmts=468x60_as&format=180x150_as&output=html&correlator=1186550826477&url=http%3A%2F%2Fwww.cnblogs.com%2Fzhenyulu%2Farticles%2F39257.aspx&ad_type=text&cc=6&ga_vid=1287732182.1186550826&ga_sid=1186550826&ga_hid=2104796095&flash=9&u_h=1024&u_w=1280&u_ah=987&u_aw=1280&u_cd=32&u_tz=480&u_his=1&u_java=true&u_nplug=27&u_nmime=113" name="google_ads_frame">

一、 原型(Prototype)模式

原型模式的用意是:通过给出一个原型对象来指明所要创建的对象类型,然后用复制这个原型对象的办法创建出更多的同类型对象。

从孙大圣的手段谈起

孙悟空在与黄风怪的战斗中,"使一个身外身的手段:把毫毛揪下一把,用口嚼得粉碎,望上一喷,叫声'变',变有百十个行者,都是一样得打扮,各执一根铁棒,把那怪围在空中。"换而言之,孙悟空可以根据自己的形象,复制出很多"身外身"来。

老孙这种身外身的手段在面向对象设计领域里叫原型(Prototype)模式。

C#对原型模式的支持

在C#里面,我们可以很容易的通过Clone()方法实现原型模式。任何类,只要想支持克隆,必须实现C#中的ICloneable接口。 ICloneable接口中有一Clone方法,可以在类中复写实现自定义的克隆方法。克隆的实现方法有两种:浅拷贝(shallow copy)与深拷贝(deep copy)。

(以下摘自:《.NET框架程序设计(修订版)》,李建忠译)浅拷贝是指当对象的字段值被拷贝时,字段引用的对象不会被拷贝。例如,如果一个对象有 一个指向字符串的字段,并且我们对该对象做了一个浅拷贝,那么两个对象将引用同一个字符串。而深拷贝是对对象实例中字段引用的对象也进行拷贝的一种方式, 所以如果一个对象有一个指向字符串的字段,并且我们对该对象做了一个深拷贝的话,我们将创建一个新的对象和一个新的字符串--新对象将引用新字符串。需要 注意的是执行深拷贝后,原来的对象和新创建的对象不会共享任何东西;改变一个对象对另外一个对象没有任何影响。


二、 Prototype模式的结构:

 

客户(Client)角色:客户类提出创建对象的请求。
抽象原型(Prototype)角色:这是一个抽象角色,通常由一个C#接口或抽象类实现。此角色给出所有的具体原型类所需的接口。在C#中,抽象原型角色通常实现了ICloneable接口。
具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象原型角色所要求的接口。


三、 程序举例:

下面的程序给出了一个示意性的实现:

//  Prototype pattern -- Structural example  
using  System;

//  "Prototype"
abstract   class  Prototype
{
  
// Fields
  private string id;

  
// Constructors
  public Prototype( string id )
  
{
    
this.id = id;
  }


  
public string Id
  
{
    
getreturn id; }
  }


  
// Methods
  abstract public Prototype Clone();
}


//  "ConcretePrototype1"
class  ConcretePrototype1 : Prototype
{
  
// Constructors
  public ConcretePrototype1( string id ) : base ( id ) {}

  
// Methods
  override public Prototype Clone()
  
{
    
// Shallow copy
    return (Prototype)this.MemberwiseClone();
  }

}


//  "ConcretePrototype2"
class  ConcretePrototype2 : Prototype
{
  
// Constructors
  public ConcretePrototype2( string id ) : base ( id ) {}

  
// Methods
  override public Prototype Clone()
  
{
    
// Shallow copy
    return (Prototype)this.MemberwiseClone();
  }

}


/// <summary>
/// Client test
/// </summary>

class  Client
{
  
public static void Main( string[] args )
  
{
    
// Create two instances and clone each
    ConcretePrototype1 p1 = new ConcretePrototype1( "I" );
    ConcretePrototype1 c1 
= (ConcretePrototype1)p1.Clone();
    Console.WriteLine( 
"Cloned: {0}", c1.Id );

    ConcretePrototype2 p2 
= new ConcretePrototype2( "II" );
    ConcretePrototype2 c2 
= (ConcretePrototype2)p2.Clone();
    Console.WriteLine( 
"Cloned: {0}", c2.Id );
  }

}

这个例子实现了一个浅拷贝。其中MemberwiseClone()方法是Object类的一个受保护方法,实现了对象的浅拷贝。如果希望实现一个深拷贝,应该实现ICloneable接口,并自己编写ICloneable的Clone接口方法。


四、 带Prototype Manager的原型模式

原型模式的第二种形式是带原型管理器的原型模式,其UML图如下:

 

客户(Client)角色:客户端类向原型管理器提出创建对象的请求。
抽象原型(Prototype)角色:这是一个抽象角色,通常由一个C#接口或抽象类实现。此角色给出所有的具体原型类所需的接口。在C#中,抽象原型角色通常实现了ICloneable接口。
具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口。
原型管理器(Prototype Manager)角色:创建具体原型类的对象,并记录每一个被创建的对象。


下面这个例子演示了在原型管理器中存储用户预先定义的颜色原型,客户通过原型管理器克隆颜色对象。

//  Prototype pattern -- Real World example  
using  System;
using  System.Collections;

//  "Prototype"
abstract   class  ColorPrototype
{
  
// Methods
  public abstract ColorPrototype Clone();
}


//  "ConcretePrototype"
class  Color : ColorPrototype
{
  
// Fields
  private int red, green, blue;

  
// Constructors
  public Color( int red, int green, int blue)
  
{
    
this.red = red;
    
this.green = green;
    
this.blue = blue;
  }


  
// Methods
  public override ColorPrototype Clone()
  
{
    
// Creates a 'shallow copy'
    return (ColorPrototype) this.MemberwiseClone();
  }


  
public void Display()
  
{
    Console.WriteLine( 
"RGB values are: {0},{1},{2}",
      red, green, blue );
  }

}


//  Prototype manager
class  ColorManager
{
  
// Fields
  Hashtable colors = new Hashtable();

  
// Indexers
  public ColorPrototype thisstring name ]
  
{
    
getreturn (ColorPrototype)colors[ name ]; }
    
set{ colors.Add( name, value ); }
  }

}


/// <summary>
///  PrototypeApp test
/// </summary>

class  PrototypeApp
{
  
public static void Main( string[] args )
  
{
    ColorManager colormanager 
= new ColorManager();

    
// Initialize with standard colors
    colormanager[ "red" ] = new Color( 25500 );
    colormanager[ 
"green" ] = new Color( 02550 );
    colormanager[ 
"blue" ] = new Color( 00255 );

    
// User adds personalized colors
    colormanager[ "angry" ] = new Color( 255540 );
    colormanager[ 
"peace" ] = new Color( 128211128 );
    colormanager[ 
"flame" ] = new Color( 2113420 );

    
// User uses selected colors
    string colorName = "red";
    Color c1 
= (Color)colormanager[ colorName ].Clone();
    c1.Display();

    colorName 
= "peace";
    Color c2 
= (Color)colormanager[ colorName ].Clone();
    c2.Display();

    colorName 
= "flame";
    Color c3 
= (Color)colormanager[ colorName ].Clone();
    c3.Display();
  }

}



五、 浅拷贝与深拷贝

下面给出浅拷贝与深拷贝的两个例子,例子使用了ICloneable接口。C#中的数组是引用型的变量,我们通过数组来进行演示:

浅拷贝:

using  System;

class  ShallowCopy : ICloneable
{
  
public int[] v = {1,2,3};

  
public Object Clone()
  
{
    
return this.MemberwiseClone();
  }


  
public void Display()
  
{
    
foreach(int i in v)
      Console.Write( i 
+ "");
    Console.WriteLine();
  }

}


class  Client
{
  
public static void Main()
  
{
    ShallowCopy sc1 
= new ShallowCopy();
    ShallowCopy sc2 
= (ShallowCopy)sc1.Clone();
    sc1.v[
0= 9;

    sc1.Display();
    sc2.Display();
  }

}


ShallowCopy对象实现了一个浅拷贝,因此当对sc1进行克隆时,其字段v并没有克隆,这导致sc1与sc2的字段v都指向了同一个v,因此,当修改了sc1的v[0]后,sc2的v[0]也发生了变化。

深拷贝:

using  System;

class  DeepCopy : ICloneable
{
  
public int[] v = {1,2,3};

  
// 默认构造函数
  public DeepCopy()
  
{
  }


  
// 供Clone方法调用的私有构造函数
  private DeepCopy(int[] v)
  
{
    
this.v = (int[])v.Clone();
  }


  
public Object Clone()
  
{
    
// 构造一个新的DeepCopy对象,构造参数为
    
// 原有对象中使用的 v 
    return new DeepCopy(this.v);
  }


  
public void Display()
  
{
    
foreach(int i in v)
      Console.Write( i 
+ "");
    Console.WriteLine();
  }

}


class  Client
{
  
public static void Main()
  
{
    DeepCopy dc1 
= new DeepCopy();
    DeepCopy dc2 
= (DeepCopy)dc1.Clone();
    dc1.v[
0= 9;

    dc1.Display();
    dc2.Display();
  }

}


这次在克隆的时候,不但克隆对象本身,连里面的数组字段一并克隆。因此,最终打印出来的dc1与dc2不同。


六、 Prototype模式的优点与缺点

Prototype模式的优点包括

1、Prototype模式允许动态增加或减少产品类。由于创建产品类实例的方法是产批类内部具有的,因此增加新产品对整个结构没有影响。

2、Prototype模式提供了简化的创建结构。工厂方法模式常常需要有一个与产品类等级结构相同的等级结构,而Prototype模式就不需要这样。

3、Portotype模式具有给一个应用软件动态加载新功能的能力。由于Prototype的独立性较高,可以很容易动态加载新功能而不影响老系统。

4、产品类不需要非得有任何事先确定的等级结构,因为Prototype模式适用于任何的等级结构。


Prototype模式的缺点:

Prototype模式的最主要缺点就是每一个类必须配备一个克隆方法。而且这个克隆方法需要对类的功能进行通盘考虑,这对全新的类来说不是很难,但对已有的类进行改造时,不一定是件容易的事。


参考文献:
阎宏,《Java与模式》,电子工业出版社
[美]James W. Cooper,《C#设计模式》,电子工业出版社
[美]Alan Shalloway  James R. Trott,《Design Patterns Explained》,中国电力出版社
[美]Robert C. Martin,《敏捷软件开发-原则、模式与实践》,清华大学出版社
[美]Don Box, Chris Sells,《.NET本质论 第1卷:公共语言运行库》,中国电力出版社

posted on 2004-09-03 13:10 吕震宇 阅读(8710) 评论(32)   编辑  收藏 引用 网摘 所属分类: 设计模式
<script type="text/javascript"> // </script>

评论

#  re: C#设计模式(9)-Prototype Pattern 2004-09-03 14:36 wayfarer
很好的设计模式系列啊,希望吕震宇继续哦   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2004-09-03 15:34 风前絮~~
好系列啊,23个模式齐全还需时日,加油啊!
   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2004-09-05 08:56 吕震宇
@wayfarer

说起原型模式,我在做局域网内部的Remoting时,希望消息收发方从消息中知道对方的一些信息,比如IP,MAC,URL等,如果每次从计算 机中都提取IP等信息是很繁琐的。所以我就做了个“消息原型”,在这个原型中,将IP, MAC等信息事先初始化好,然后每次发消息都克隆一份,然后填入消息类型以及消息内容再发送。不知道这算不算一个“原型模式”的应用。    回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2004-09-05 11:37 wayfarer
@吕震宇

这是个好例子,谢谢:)

btw:我做Remoting时,也希望能从服务器端获得客户端的相关信息,例如IP。我知道在Socket中是很容易获得的,不知Remoting应该怎么获得?

从你的描述来说,似乎是从客户端发送已经订制好的信息,而非服务器端捕获的?
   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2004-09-05 17:40 吕震宇
@wayfarer

我们在作安全项目时,我的一个同事做过C#上的Sniffer,主要是将网卡置为混杂模式后,监听IP包。没经过她的同意,我不好把代码放上来。 不过如果监听Remoting的端口,我想不是件容易的事,而且在Sniffer中IP地址获取是在IP数据包中截获的,没有什么应用意义。所以当我在做 Remoting时,将IP地址做在了Message中。

我定义了一个Message的Structure,该Structure可以被序列化成XML,因此可以在Remoting中当作参数传递。同时 在这个结构中定义一些成员,包括IP、MAC、客户端Remoting监听的URL等信息。服务器接受到消息后,可以从该Message结构中解出URL 等信息。服务器维护了一个HASHTABLE,可以选择MAC或URL做hash,这样就知道是谁发过来的消息了。

当需要进行消息转发时,也可以采用这种技术。只不过需要预先知道对方URL地址。这可以在服务器上做一个查询功能实现。

整体方案使用中介模式,服务器负责所有消息的转发、登记、日志、数据库记录等操作。

本来想把这个内容在BLOG上发篇文章,一直没有腾出时间来。以后有机会再写吧。
   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2004-09-19 17:33 jcaomao
我看不出来在类内部做一个clone方法生成新实例,和用 new 生成一个新实例有什么不一样,能解释一下吗?   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2004-09-20 09:27 吕震宇
还是从构造函数说起:构造函数相当于对类实例的一个初始化操作,如果构造函数的执行时间很长,例如获取一些远程配置信息之类。如果每NEW一次,都需要执行一次构造函数,那么无疑效率是很低的。如果配置信息不发生变化的化,克隆是最好的办法。   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2004-09-20 14:17 jcaomao
谢谢, 不过我在csdn上插了一下也有人问这个问题,其实有一个人的回答我觉得更贴切于这个模式。

“原型实际上是动态抽取当前对象运行时的状态”,我觉得这个才是原型的本意。   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2004-09-20 14:32 吕震宇
@jcaomao

不错!长见识了!谢谢!   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2004-09-20 22:10 寒枫天伤
对你的文章继续期待中。
热切盼望你能够全部写完   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2004-11-20 11:21 jiangyu
深考贝的时候,又使用了new Object,这样与新生成一个实例从性能差不多吧。
我觉得还是 jcaomao 说得准确。:)   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2004-11-20 14:07 吕震宇
@jiangyu

如果是文章中的例子,那不错,深拷贝和重新生成一个实例的性能差不多。但从以下几个角度出发,深拷贝要具有优势:

1、当new一个对象时,构造函数将被调用。如果构造函数的运行时间比较长(例如获取当前机器的配置信息),那么不如克隆一份更方便,更高效。

2、另外程序在复杂环境中运行时,一个对象的当前状态恐怕很难了解的清清楚楚(也不需要了解清楚)。在这种情况下很难使用new制作个一模一样的对象出来,而使用深拷贝很好的符合了最小知识原则-知道的越少越好。

3、学习了Builder模式后知道,有很多对象创建过程如此复杂,需要在一个Director指导下进行构建,克隆就方便的多了。

不知这算不算使用深拷贝的一个原因。   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2004-11-22 09:09 jiangyu
谢谢 吕震宇。
看过GOF的23种模式,觉得它上面的例子都讲得挺有道理,但在实际应用中却不太会用,就连工厂模式也只是在支持多数据库时用过(就如petshop)。
功力还不够啊,呵呵。还渴望大哥能多写一些这样的好文章,然后再结合您在工作中的具体实例来说明,这样更好理解,也更有说服力:)   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2004-11-22 11:22 姚茂彪
原型模式的应用有两种Context:
1.客户端需要大量复制与原型对象的状态一样的对象。2.客户端并不知道具体需要复制的对象的类型,他只有其父类(抽象类)指针。主要是将客户端与具体的产品隔离(bridge pattern的设计意图)

以上是我的理解。   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2004-11-27 16:27 重粒子
"2.客户端并不知道具体需要复制的对象的类型,他只有其父类(抽象类)指针。" is key context.   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2004-12-31 14:18 我不懂原型
不知道楼上说的客户不知道具体要复制的对象类型怎么理解?
看上面的代码明明是需要知道的嘛!!

请高人指点   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2005-01-11 16:53 KingofSC
楼上,要知道Clone是virtual的
客户可以不用知道实际复制的对象类型   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2005-01-11 16:56 KingofSC
干脆叫克隆模式得了   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2005-02-23 16:57 someone
关于文中引用《Microsoft .NET 框架程序设计(修订版)》中的文字,小弟有一些疑问。
该书中提及,如果一个对象有一个指向字符串的字段,并且我们对该对象做了一个浅拷贝(shallow copy),那么两个对象将引用同一个字符串。
就文中的Structural example而言,如果将Prototype的id设置为可读写field,即:
public string Id
{
get{ return id; }
set{ this.id = value; }
}
如此一来,如果在Client.Main中,c1是从p1 shallow copy获得的,因此c1.id和p1.id应该是引用同一个字符串,也即,修改了p1.id,同时c1.id也会改变。
然而,实际情况却不是如此:
p1.Id = "III";
Console.WriteLine("Is Changed: {0}", c1.Id);   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2005-02-23 20:47 吕震宇
其实上面的代码之所以没能执行成功,是因为你在不经意间改变了指向字符串的指针。也就是说当执行p1.Id = "III"时,是将p1.Id的指针指向另外一个字符串了(这是.net字符串的特性),而c1.Id仍然指向老字符串。

建议读一读关于.net中string的资料。博客园以前有人讨论过这个问题以及copy-on-write技术等。可以参考鞠强的《对于string类的困惑》。地址:

http://www.cnblogs.com/juqiang/archive/2004/08/30/37549.html   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2005-02-24 09:36 someone
to 吕震宇
3ks,明白了。:)   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2005-03-20 20:18 feng
请问上面的深拷贝中为什么要使用
return new DeepCopy(this.v);
而不直接使用return new DeepCopy();呢?难到这样就不能把public int[] v = {1,2,3};进入深拷贝。?   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2005-03-31 19:27 feng
请问上面的深拷贝中为什么要使用
return new DeepCopy(this.v);
而不直接使用return new DeepCopy();呢?难到这样就不能把public int[] v = {1,2,3};进入深拷贝。?
   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2005-06-25 10:43 cv222
吕震宇 支持你 这样的好文章不多   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2005-07-15 17:53 Hansol
@ feng

return new DeepCopy() 的话,跟new一个没有区别。

n楼上的“原型实际上是动态抽取当前对象运行时的状态”很贴切。
比如一个类的封装了很多数据(通过属性的set()),那么这个时候的复制和new的效果显然是不一样的。

同时支持 吕震宇, 奇文共欣赏。
   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2005-09-15 00:53 汪峰
个人认为“客户端并不知道具体需要复制的对象的类型”不是原形的本意,参数化构建对象而已
我认为原形模式邮两种主要用途
1:大量复制已存在的对象的实例。例如,系统重存在一个单例对象,我在很多地方需要用它来组合新对象,吕震宇的就是一例
2:复制一个已存在对象的不同状态下的实例。其实,Session就是这样的一个例子,只不过用赋值代替了克隆而已   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2005-10-16 15:59 lifecompass

为什么说用原型模式可以减少子类的构造?
有没有具体的例子说明少了哪些类?


   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2006-04-18 16:12 阿不
父类的Clone()行为会影响子类。就是说如果在子类调用Clone()函数,子类的属性也会被克隆。   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2006-06-13 00:35 i_single
如果说DeepCopy 是个抽象类,包含了众多的属性,该如何处理呢?   回复   更多评论
  

#  re: C#设计模式(9)-Prototype Pattern 2007-02-14 10:03 heqing
可能来晚了,但十分感谢,我终于看懂了。   回复   更多评论
  

#  C#设计模式--笔记[TrackBack] 2007-03-06 16:34 Dragon-China
转贴:http://www.cnblogs.com/zhenyulu/articles/36058.html来源:亚历山大的建筑模式、Gamma等人(1995)创作的   查看原文   回复   更多评论
  

#  原型模式(Prototype Pattern) 资料合集 [TrackBack] 2007-03-12 08:41 阿鸟
原型模式(Prototype Pattern) 资料合集   查看原文   回复   更多评论
  

<script type="text/javascript"> function pageLoad() { Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(handleInitializeRequest); //Sys.WebForms.PageRequestManager.getInstance().add_endRequest(handleEndRequest); } function handleInitializeRequest(sender, args) { var prm = Sys.WebForms.PageRequestManager.getInstance(); var eid = args.get_postBackElement().id; if (eid.indexOf("DeleteLink")>0) { args.get_postBackElement().innerHTML = " 正在删除..."; } else if (eid.indexOf("btnSubmit")>0) { document.getElementById("AjaxHolder_PostComment_ltSubmitMsg").innerHTML="正在提交..."; document.getElementById("AjaxHolder_PostComment_btnSubmit").disabled = true; } else if(eid.indexOf("refreshList")>0) { document.getElementById("AjaxHolder_PostComment_refreshList").innerHTML=" 正在刷新..."; } } function TempSave(ElementID) { try { CommentsPersistDiv.setAttribute("CommentContent",document.getElementById(ElementID).value); CommentsPersistDiv.save("CommentXMLStore"); } catch(ex) { } } function Restore(ElementID) { CommentsPersistDiv.load("CommentXMLStore"); document.getElementById(ElementID).value=CommentsPersistDiv.getAttribute("CommentContent"); } </script>


<script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"> </script> width="468" scrolling="no" height="60" frameborder="0" allowtransparency="true" hspace="0" vspace="0" marginheight="0" marginwidth="0" src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-4210569241504288&dt=1186550826477&lmt=1186550803&format=468x60_as&output=html&correlator=1186550826477&url=http%3A%2F%2Fwww.cnblogs.com%2Fzhenyulu%2Farticles%2F39257.aspx&color_link=6699CC&ad_type=text&cc=7&ga_vid=1287732182.1186550826&ga_sid=1186550826&ga_hid=2104796095&flash=9&u_h=1024&u_w=1280&u_ah=987&u_aw=1280&u_cd=32&u_tz=480&u_his=1&u_java=true&u_nplug=27&u_nmime=113" name="google_ads_frame">


   
标题
姓名
主页 
验证码*   
内容(请不要发表任何与政治相关的内容)
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
 
服务器托管服务商:零刻数据

width="468" scrolling="no" height="80" frameborder="0" allowtransparency="true" style="border: 0px solid rgb(102, 102, 102);" src="http://www.cnblogs.com/ad.htm" marginwidth="0" marginheight="0">
<script type="text/javascript"> </script> <script type="text/javascript"> </script> <script type="text/javascript"> </script> <script type="text/javascript"> </script>
<script src="http://www.cnblogs.com/script/ShowHidden.js" type="text/javascript"></script>  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值