Prototype 原型(创建型模式)
2006-12-22 22:42
399 查看
下面是李建忠老师WebCast中课件内容 还有小山老师Blog中的相应内容:
原型(Prototype)模式
依赖关系的倒置
– 抽象A直接依赖于实现细节b抽象不应该依赖于实现细节,实现细节应该依赖于抽象。
–抽象A依赖于抽象B,实现细节b依赖于抽象B
动机(Motivation)
在软件系统中,经常面临着“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥有比较稳定一致的接口。
如何应对这种变化?如何向“客户程序(使用这些对象的程序)”隔离出“这些易变对象” ,从而使得“依赖这些易变对象的客户程序”不随着需求改变而改变?
意图(Intent)
使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。
结构(Structure)
![](http://zhenyulu.cnblogs.com/images/cnblogs_com/zhenyulu/Pic55.gif)
客户(Client)角色:客户类提出创建对象的请求。
抽象原型(Prototype)角色:这是一个抽象角色,通常由一个C#接口或抽象类实现。此角色给出所有的具体原型类所需的接口。在C#中,抽象原型角色通常实现了ICloneable接口。
具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象原型角色所要求的接口。
Prototype模式的几个要点
• Prototype模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些“易变类”拥有“稳定的接口”。
• Prototype模式对于“如何创建易变类的实体对象”采用“原型克隆”的方法来做,它使得我们可以非常灵活地动态创建“拥有某些稳定接口”的新对象——所需工作仅仅是注册一个新类的对象(即原型),然后在任何需要的地方不断地Clone。
• Prototype模式中的Clone方法可以利用.NET中的Object类的MemberwiseClone()方法或者序列化来实现深拷贝。
有关创建性模式的讨论
• Singleton模式解决的是实体对象个数的问题。除了Singleton之外,其他创建型模式解决的都是new所带来的耦合关系。
• Factory Method, Abstract Factory, Builder都需要一个额外的工厂类来负责实例化“易变对象”,而Prototype则是通过原型(一个特殊的工厂类)来克隆“易变对象”。
• 如果遇到“易变类”,起初的设计通常从FactoryMethod开始,当遇到更多的复杂变化时,再考虑重构为其他三种工厂模式( Abstract Factory,Builder , Prototype )。
程序举例:
下面的程序给出了一个示意性的实现:
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
// Prototype pattern -- Structural example
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
using System;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
// "Prototype"
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
abstract class Prototype
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Fields
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private string id;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Constructors
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public Prototype( string id )
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
this.id = id;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public string Id
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
get{ return id; }
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Methods
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
abstract public Prototype Clone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
// "ConcretePrototype1"
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
class ConcretePrototype1 : Prototype
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Constructors
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
public ConcretePrototype1( string id ) : base ( id ) {}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Methods
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
override public Prototype Clone()
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Shallow copy
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return (Prototype)this.MemberwiseClone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
// "ConcretePrototype2"
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
class ConcretePrototype2 : Prototype
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Constructors
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
public ConcretePrototype2( string id ) : base ( id ) {}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Methods
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
override public Prototype Clone()
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Shallow copy
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return (Prototype)this.MemberwiseClone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
/**//// <summary>
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// Client test
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
/// </summary>
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
class Client
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public static void Main( string[] args )
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Create two instances and clone each
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ConcretePrototype1 p1 = new ConcretePrototype1( "I" );
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Console.WriteLine( "Cloned: {0}", c1.Id );
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ConcretePrototype2 p2 = new ConcretePrototype2( "II" );
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ConcretePrototype2 c2 = (ConcretePrototype2)p2.Clone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Console.WriteLine( "Cloned: {0}", c2.Id );
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
这个例子实现了一个浅拷贝。其中MemberwiseClone()方法是Object类的一个受保护方法,实现了对象的浅拷贝。如果希望实现一个深拷贝,应该实现ICloneable接口,并自己编写ICloneable的Clone接口方法。
下面这个例子演示了在原型管理器中存储用户预先定义的颜色原型,客户通过原型管理器克隆颜色对象。
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
// Prototype pattern -- Real World example
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
using System;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Collections;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
// "Prototype"
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
abstract class ColorPrototype
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Methods
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public abstract ColorPrototype Clone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
// "ConcretePrototype"
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
class Color : ColorPrototype
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Fields
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private int red, green, blue;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Constructors
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public Color( int red, int green, int blue)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
this.red = red;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
this.green = green;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
this.blue = blue;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Methods
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public override ColorPrototype Clone()
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Creates a 'shallow copy'
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return (ColorPrototype) this.MemberwiseClone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public void Display()
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Console.WriteLine( "RGB values are: {0},{1},{2}",
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
red, green, blue );
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
// Prototype manager
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
class ColorManager
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Fields
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Hashtable colors = new Hashtable();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Indexers
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public ColorPrototype this[ string name ]
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
get{ return (ColorPrototype)colors[ name ]; }
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
set{ colors.Add( name, value ); }
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
/**//// <summary>
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// PrototypeApp test
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
/// </summary>
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
class PrototypeApp
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public static void Main( string[] args )
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ColorManager colormanager = new ColorManager();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Initialize with standard colors
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
colormanager[ "red" ] = new Color( 255, 0, 0 );
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
colormanager[ "green" ] = new Color( 0, 255, 0 );
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
colormanager[ "blue" ] = new Color( 0, 0, 255 );
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// User adds personalized colors
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
colormanager[ "angry" ] = new Color( 255, 54, 0 );
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
colormanager[ "peace" ] = new Color( 128, 211, 128 );
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
colormanager[ "flame" ] = new Color( 211, 34, 20 );
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// User uses selected colors
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string colorName = "red";
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Color c1 = (Color)colormanager[ colorName ].Clone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
c1.Display();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
colorName = "peace";
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Color c2 = (Color)colormanager[ colorName ].Clone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
c2.Display();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
colorName = "flame";
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Color c3 = (Color)colormanager[ colorName ].Clone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
c3.Display();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
五、 浅拷贝与深拷贝
下面给出浅拷贝与深拷贝的两个例子,例子使用了ICloneable接口。C#中的数组是引用型的变量,我们通过数组来进行演示:
浅拷贝:
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
using System;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
class ShallowCopy : ICloneable
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
public int[] v = {1,2,3};
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public Object Clone()
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return this.MemberwiseClone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public void Display()
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
foreach(int i in v)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Console.Write( i + ", ");
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Console.WriteLine();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
class Client
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public static void Main()
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ShallowCopy sc1 = new ShallowCopy();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ShallowCopy sc2 = (ShallowCopy)sc1.Clone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
sc1.v[0] = 9;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
sc1.Display();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
sc2.Display();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
ShallowCopy对象实现了一个浅拷贝,因此当对sc1进行克隆时,其字段v并没有克隆,这导致sc1与sc2的字段v都指向了同一个v,因此,当修改了sc1的v[0]后,sc2的v[0]也发生了变化。
深拷贝:
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
using System;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
class DeepCopy : ICloneable
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
public int[] v = {1,2,3};
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 默认构造函数
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public DeepCopy()
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 供Clone方法调用的私有构造函数
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private DeepCopy(int[] v)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
this.v = (int[])v.Clone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public Object Clone()
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 构造一个新的DeepCopy对象,构造参数为
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 原有对象中使用的 v
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return new DeepCopy(this.v);
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public void Display()
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
foreach(int i in v)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Console.Write( i + ", ");
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Console.WriteLine();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
class Client
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public static void Main()
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
DeepCopy dc1 = new DeepCopy();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
DeepCopy dc2 = (DeepCopy)dc1.Clone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
dc1.v[0] = 9;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
dc1.Display();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
dc2.Display();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
这次在克隆的时候,不但克隆对象本身,连里面的数组字段一并克隆。因此,最终打印出来的dc1与dc2不同。
Prototype模式的优点与缺点
Prototype模式的优点包括
1、Prototype模式允许动态增加或减少产品类。由于创建产品类实例的方法是产批类内部具有的,因此增加新产品对整个结构没有影响。
2、Prototype模式提供了简化的创建结构。工厂方法模式常常需要有一个与产品类等级结构相同的等级结构,而Prototype模式就不需要这样。
3、Portotype模式具有给一个应用软件动态加载新功能的能力。由于Prototype的独立性较高,可以很容易动态加载新功能而不影响老系统。
4、产品类不需要非得有任何事先确定的等级结构,因为Prototype模式适用于任何的等级结构。
Prototype模式的缺点:
Prototype模式的最主要缺点就是每一个类必须配备一个克隆方法。而且这个克隆方法需要对类的功能进行通盘考虑,这对全新的类来说不是很难,但对已有的类进行改造时,不一定是件容易的事。
原型模式的用意是:通过给出一个原型对象来指明所要创建的对象类型,然后用复制这个原型对象的办法创建出更多的同类型对象。
C#对原型模式的支持
在C#里面,我们可以很容易的通过Clone()方法实现原型模式。任何类,只要想支持克隆,必须实现C#中的ICloneable接口。ICloneable接口中有一Clone方法,可以在类中复写实现自定义的克隆方法。克隆的实现方法有两种:浅拷贝(shallow copy)与深拷贝(deep copy)。
(以下摘自:《.NET框架程序设计(修订版)》,李建忠译)浅拷贝是指当对象的字段值被拷贝时,字段引用的对象不会被拷贝。例如,如果一个对象有一个指向字符串的字段,并且我们对该对象做了一个浅拷贝,那么两个对象将引用同一个字符串。而深拷贝是对对象实例中字段引用的对象也进行拷贝的一种方式,所以如果一个对象有一个指向字符串的字段,并且我们对该对象做了一个深拷贝的话,我们将创建一个新的对象和一个新的字符串--新对象将引用新字符串。需要注意的是执行深拷贝后,原来的对象和新创建的对象不会共享任何东西;改变一个对象对另外一个对象没有任何影响。
原型(Prototype)模式
依赖关系的倒置
– 抽象A直接依赖于实现细节b抽象不应该依赖于实现细节,实现细节应该依赖于抽象。
–抽象A依赖于抽象B,实现细节b依赖于抽象B
动机(Motivation)
在软件系统中,经常面临着“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥有比较稳定一致的接口。
如何应对这种变化?如何向“客户程序(使用这些对象的程序)”隔离出“这些易变对象” ,从而使得“依赖这些易变对象的客户程序”不随着需求改变而改变?
意图(Intent)
使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。
结构(Structure)
![](http://zhenyulu.cnblogs.com/images/cnblogs_com/zhenyulu/Pic55.gif)
客户(Client)角色:客户类提出创建对象的请求。
抽象原型(Prototype)角色:这是一个抽象角色,通常由一个C#接口或抽象类实现。此角色给出所有的具体原型类所需的接口。在C#中,抽象原型角色通常实现了ICloneable接口。
具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象原型角色所要求的接口。
Prototype模式的几个要点
• Prototype模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些“易变类”拥有“稳定的接口”。
• Prototype模式对于“如何创建易变类的实体对象”采用“原型克隆”的方法来做,它使得我们可以非常灵活地动态创建“拥有某些稳定接口”的新对象——所需工作仅仅是注册一个新类的对象(即原型),然后在任何需要的地方不断地Clone。
• Prototype模式中的Clone方法可以利用.NET中的Object类的MemberwiseClone()方法或者序列化来实现深拷贝。
有关创建性模式的讨论
• Singleton模式解决的是实体对象个数的问题。除了Singleton之外,其他创建型模式解决的都是new所带来的耦合关系。
• Factory Method, Abstract Factory, Builder都需要一个额外的工厂类来负责实例化“易变对象”,而Prototype则是通过原型(一个特殊的工厂类)来克隆“易变对象”。
• 如果遇到“易变类”,起初的设计通常从FactoryMethod开始,当遇到更多的复杂变化时,再考虑重构为其他三种工厂模式( Abstract Factory,Builder , Prototype )。
程序举例:
下面的程序给出了一个示意性的实现:
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
// Prototype pattern -- Structural example
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
using System;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
// "Prototype"
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
abstract class Prototype
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Fields
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private string id;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Constructors
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public Prototype( string id )
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
this.id = id;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public string Id
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
get{ return id; }
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Methods
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
abstract public Prototype Clone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
// "ConcretePrototype1"
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
class ConcretePrototype1 : Prototype
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Constructors
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
public ConcretePrototype1( string id ) : base ( id ) {}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Methods
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
override public Prototype Clone()
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Shallow copy
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return (Prototype)this.MemberwiseClone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
// "ConcretePrototype2"
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
class ConcretePrototype2 : Prototype
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Constructors
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
public ConcretePrototype2( string id ) : base ( id ) {}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Methods
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
override public Prototype Clone()
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Shallow copy
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return (Prototype)this.MemberwiseClone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
/**//// <summary>
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// Client test
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
/// </summary>
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
class Client
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public static void Main( string[] args )
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Create two instances and clone each
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ConcretePrototype1 p1 = new ConcretePrototype1( "I" );
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Console.WriteLine( "Cloned: {0}", c1.Id );
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ConcretePrototype2 p2 = new ConcretePrototype2( "II" );
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ConcretePrototype2 c2 = (ConcretePrototype2)p2.Clone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Console.WriteLine( "Cloned: {0}", c2.Id );
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
这个例子实现了一个浅拷贝。其中MemberwiseClone()方法是Object类的一个受保护方法,实现了对象的浅拷贝。如果希望实现一个深拷贝,应该实现ICloneable接口,并自己编写ICloneable的Clone接口方法。
下面这个例子演示了在原型管理器中存储用户预先定义的颜色原型,客户通过原型管理器克隆颜色对象。
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
// Prototype pattern -- Real World example
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
using System;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Collections;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
// "Prototype"
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
abstract class ColorPrototype
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Methods
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public abstract ColorPrototype Clone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
// "ConcretePrototype"
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
class Color : ColorPrototype
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Fields
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private int red, green, blue;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Constructors
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public Color( int red, int green, int blue)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
this.red = red;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
this.green = green;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
this.blue = blue;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Methods
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public override ColorPrototype Clone()
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Creates a 'shallow copy'
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return (ColorPrototype) this.MemberwiseClone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public void Display()
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Console.WriteLine( "RGB values are: {0},{1},{2}",
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
red, green, blue );
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
// Prototype manager
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
class ColorManager
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Fields
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Hashtable colors = new Hashtable();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Indexers
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public ColorPrototype this[ string name ]
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
get{ return (ColorPrototype)colors[ name ]; }
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
set{ colors.Add( name, value ); }
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
/**//// <summary>
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// PrototypeApp test
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
/// </summary>
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
class PrototypeApp
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public static void Main( string[] args )
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ColorManager colormanager = new ColorManager();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Initialize with standard colors
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
colormanager[ "red" ] = new Color( 255, 0, 0 );
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
colormanager[ "green" ] = new Color( 0, 255, 0 );
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
colormanager[ "blue" ] = new Color( 0, 0, 255 );
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// User adds personalized colors
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
colormanager[ "angry" ] = new Color( 255, 54, 0 );
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
colormanager[ "peace" ] = new Color( 128, 211, 128 );
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
colormanager[ "flame" ] = new Color( 211, 34, 20 );
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// User uses selected colors
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string colorName = "red";
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Color c1 = (Color)colormanager[ colorName ].Clone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
c1.Display();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
colorName = "peace";
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Color c2 = (Color)colormanager[ colorName ].Clone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
c2.Display();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
colorName = "flame";
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Color c3 = (Color)colormanager[ colorName ].Clone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
c3.Display();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
五、 浅拷贝与深拷贝
下面给出浅拷贝与深拷贝的两个例子,例子使用了ICloneable接口。C#中的数组是引用型的变量,我们通过数组来进行演示:
浅拷贝:
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
using System;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
class ShallowCopy : ICloneable
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
public int[] v = {1,2,3};
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public Object Clone()
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return this.MemberwiseClone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public void Display()
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
foreach(int i in v)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Console.Write( i + ", ");
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Console.WriteLine();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
class Client
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public static void Main()
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ShallowCopy sc1 = new ShallowCopy();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ShallowCopy sc2 = (ShallowCopy)sc1.Clone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
sc1.v[0] = 9;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
sc1.Display();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
sc2.Display();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
ShallowCopy对象实现了一个浅拷贝,因此当对sc1进行克隆时,其字段v并没有克隆,这导致sc1与sc2的字段v都指向了同一个v,因此,当修改了sc1的v[0]后,sc2的v[0]也发生了变化。
深拷贝:
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
using System;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
class DeepCopy : ICloneable
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
public int[] v = {1,2,3};
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 默认构造函数
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public DeepCopy()
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 供Clone方法调用的私有构造函数
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private DeepCopy(int[] v)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
this.v = (int[])v.Clone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public Object Clone()
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 构造一个新的DeepCopy对象,构造参数为
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 原有对象中使用的 v
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return new DeepCopy(this.v);
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public void Display()
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
foreach(int i in v)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Console.Write( i + ", ");
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Console.WriteLine();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/None.gif)
class Client
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public static void Main()
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
DeepCopy dc1 = new DeepCopy();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
DeepCopy dc2 = (DeepCopy)dc1.Clone();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
dc1.v[0] = 9;
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
dc1.Display();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
dc2.Display();
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://zhenyulu.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
这次在克隆的时候,不但克隆对象本身,连里面的数组字段一并克隆。因此,最终打印出来的dc1与dc2不同。
Prototype模式的优点与缺点
Prototype模式的优点包括
1、Prototype模式允许动态增加或减少产品类。由于创建产品类实例的方法是产批类内部具有的,因此增加新产品对整个结构没有影响。
2、Prototype模式提供了简化的创建结构。工厂方法模式常常需要有一个与产品类等级结构相同的等级结构,而Prototype模式就不需要这样。
3、Portotype模式具有给一个应用软件动态加载新功能的能力。由于Prototype的独立性较高,可以很容易动态加载新功能而不影响老系统。
4、产品类不需要非得有任何事先确定的等级结构,因为Prototype模式适用于任何的等级结构。
Prototype模式的缺点:
Prototype模式的最主要缺点就是每一个类必须配备一个克隆方法。而且这个克隆方法需要对类的功能进行通盘考虑,这对全新的类来说不是很难,但对已有的类进行改造时,不一定是件容易的事。
原型模式的用意是:通过给出一个原型对象来指明所要创建的对象类型,然后用复制这个原型对象的办法创建出更多的同类型对象。
C#对原型模式的支持
在C#里面,我们可以很容易的通过Clone()方法实现原型模式。任何类,只要想支持克隆,必须实现C#中的ICloneable接口。ICloneable接口中有一Clone方法,可以在类中复写实现自定义的克隆方法。克隆的实现方法有两种:浅拷贝(shallow copy)与深拷贝(deep copy)。
(以下摘自:《.NET框架程序设计(修订版)》,李建忠译)浅拷贝是指当对象的字段值被拷贝时,字段引用的对象不会被拷贝。例如,如果一个对象有一个指向字符串的字段,并且我们对该对象做了一个浅拷贝,那么两个对象将引用同一个字符串。而深拷贝是对对象实例中字段引用的对象也进行拷贝的一种方式,所以如果一个对象有一个指向字符串的字段,并且我们对该对象做了一个深拷贝的话,我们将创建一个新的对象和一个新的字符串--新对象将引用新字符串。需要注意的是执行深拷贝后,原来的对象和新创建的对象不会共享任何东西;改变一个对象对另外一个对象没有任何影响。
相关文章推荐
- 设计模式学习之--PROTOTYPE(原型)对象创建型模型
- 六、Prototype 原型(创建型模式)
- 设计模式(2)-创建型-原型模式(Prototype)
- prototype原型(创建型模式)
- 【创建型模式】原型模式(Prototype)之23种java设计模式
- Java设计模式(6)——创建型模式之原型模式(Prototype)
- 创建型设计模式---原型模式(Prototype)
- java语言实现创建型设计模式—原型模式(Prototype)
- 创建型-原型模式(prototype)
- [导入]C#面向对象设计模式纵横谈(6):Prototype 原型模式(创建型模式).zip(9.56 MB)
- 设计模式(四)原型模式Prototype(创建型)
- 设计模式(四)原型模式Prototype(创建型)
- 原型模式(Prototype)(创建型模式)
- 【设计模式基础】创建型模式 - 6 - 原型(Prototype)
- 设计模式(2)-创建型-原型模式(Prototype)
- 十四、原型模式Prototype(创建型模式)
- 设计模式之原型法(ProtoType)----对象创建型模式
- 设计模式--原型模式Prototype(创建型)
- Java经典设计模式-创建型模式-原型模式(Prototype)
- 23种设计模式之原型模式(创建型,5 Prototype,c++实现)