您的位置:首页 > 其它

设计模式之Prototype原型设计模式

2006-11-12 22:52 597 查看
意图Intent:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
适用性:

当要实例化的类是在运行时刻指定时,例如,通过动态装载;或者

为了避免创建一个与产品类层次平行的工厂类层次时;或者

当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。

Definition
Specify the kind of objects to create using a prototypical instance, and create new objects by copying this prototype.

[align=left]participants[/align]
[align=left] The classes and/or objects participating in this pattern are: [/align]

Prototype (ColorPrototype)

declares an interace for cloning itself

ConcretePrototype (Color)

implements an operation for cloning itself

Client (ColorManager)

creates a new object by asking a prototype to clone itself

This structural code demonstrates the Prototype pattern in which new objects are created by copying pre-existing objects (prototypes) of the same class.
[align=left]using System;

namespace DoFactory.GangOfFour.Prototype.Structural
{

// MainApp test application

class MainApp
{

static void Main()
{
// 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);

// Wait for user
Console.Read();
}
}

// "Prototype"

abstract class Prototype
{
private string id;

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

// Property
public string Id
{
get{ return id; }
}

public abstract Prototype Clone();
}

// "ConcretePrototype1"

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

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

// "ConcretePrototype2"

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

public override Prototype Clone()
{
// Shallow copy
return (Prototype)this.MemberwiseClone();
}
}
}[/align]
[align=left]
Output[/align]
[align=left]Cloned: I
Cloned: II[/align]
This real-world code demonstrates the Prototype pattern in which new Color objects are created by copying pre-existing, user-defined Colors of the same type.
[align=left]// Prototype pattern -- Real World example [/align]
[align=left] [/align]
[align=left]using System;
using System.Collections;

namespace DoFactory.GangOfFour.Prototype.RealWorld
{

// MainApp test application

class MainApp
{
static void Main()
{
ColorManager colormanager = new ColorManager();

// Initialize with standard colors
colormanager["red" ] = new Color(255, 0, 0);
colormanager["green"] = new Color( 0, 255, 0);
colormanager["blue" ] = new Color( 0, 0, 255);

// User adds personalized colors
colormanager["angry"] = new Color(255, 54, 0);
colormanager["peace"] = new Color(128, 211, 128);
colormanager["flame"] = new Color(211, 34, 20);

Color color;

// User uses selected colors
string name = "red";
color = colormanager[name].Clone() as Color;

name = "peace";
color = colormanager[name].Clone() as Color;

name = "flame";
color = colormanager[name].Clone() as Color;

// Wait for user
Console.Read();
}
}

// "Prototype"

abstract class ColorPrototype
{
public abstract ColorPrototype Clone();
}

// "ConcretePrototype"

class Color : ColorPrototype
{
private int red;
private int green;
private int blue;

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

// Create a shallow copy
public override ColorPrototype Clone()
{
Console.WriteLine(
"Cloning color RGB: {0,3},{1,3},{2,3}",
red, green, blue);

return this.MemberwiseClone() as ColorPrototype;
}
}

// Prototype manager

class ColorManager
{
Hashtable colors = new Hashtable();

// Indexer
public ColorPrototype this[string name]
{
get
{
return colors[name] as ColorPrototype;
}
set
{
colors.Add(name, value);
}
}
}
}[/align]
[align=left]
Output[/align]
[align=left]Cloning color RGB: 255, 0, 0
Cloning color RGB: 128,211,128
Cloning color RGB: 211, 34, 20[/align]
原来原型模式也是挺简单的阿,主要就是一个copy了。正如意图所说的一样,用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。这么简单。。。为什么要搞一个设计模式呢?当然肯定是有它的原因了。不过俺才疏学浅,经验太少了,还是比较难以理解其中的奥妙阿。上面的real world example应该是适用性三的一个例子。因为颜色种类是一定的,是有限的(应该是无限的,不过我们用到的是有限的),然后每种色对应一个值,上面的那个example非常合适。恩。总得来说,原型模式还是比较简单的,呵呵。

附:浅拷贝和深拷贝的区别
上面的MemberwiseClone 方法创建一个浅表副本,方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。例如,考虑一个名为 X 的对象,该对象引用对象 A 和 B。对象 B 又引用对象 C。X 的浅表副本创建一个新对象 X2,该对象也引用对象 A 和 B。与此相对照,X 的深层副本创建一个新对象 X2,该对象引用新对象 A2 和 B2,它们分别是 A 和 B 的副本。B2 又引用新对象 C2,C2 是 C 的副本。使用实现 ICloneable 接口的类执行对象的浅表或深层复制。
[align=left]浅拷贝(bitwise)正如其名就是二进制级的拷贝,就是把对象里的值完全复制给了另一个对象。如果是值类型的话,则进行逐位复制;如果是引用类型的话,则复制引用但不复制引用的对象,因此,原始对象及其复本引用同一对象。[/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: