七.创建型设计模式——Prototype Pattern(原型模式)
-
定义
原型模式指定创建对象的种类,并且通过拷贝这些原型创建新的对象。Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何创建的细节。工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝原型自己来实施创建过程。
UML类图如下:
其中的类和对象之间的关系为:
1. Prototype(抽象原型类):定义具有克隆自己的方法的接口。
2. ConcretePrototype(具体原型类):实现具体的克隆方法。
3. Clinet(客户):通过克隆生成一个新的对象。
典型应用的顺序图如下:
-
实例1——颜色管理器
颜色管理器首先创建了各种颜色,并将其保存在一个哈希表中,当客户需要时,就返回一个颜色的克隆。
其类结构如图:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//定义抽象原型Prototype
abstract class ColorPrototype
{
//Clone Methods克隆方法
public abstract ColorPrototype Clone();
}
//ConcretePrototype具体原型
class Color : ColorPrototype
{
private int red;
private int green;
private int blue;
public Color(int Red, int Green, int Blue)
{
this.red = Red;
this.green = Green;
this.blue = Blue;
}
public override ColorPrototype Clone()
{
//创建一个浅表拷贝
return (ColorPrototype)this.MemberwiseClone();
}
public void Display()
{
Console.WriteLine("RGB values are:{0},{1},{2}", red, green, blue);
}
}
//原型管理者
class ColorManager
{
Hashtable colors = new Hashtable();
public ColorPrototype this[string name]
{
get { return (ColorPrototype)colors[name]; }
set { colors.Add(name, value); }
}
}
//客户应用测试
class Client
{
[STAThread]
static void Main(string[] args)
{
ColorManager colorManager = new ColorManager();
//初始化标准的颜色
colorManager["red"] = new Color(255, 0, 0);
colorManager["green"] = new Color(0, 255, 0);
colorManager["blue"] = new Color(0, 0, 255);
//增加个性化的颜色
colorManager["angry"] = new Color(255, 54, 0);
colorManager["peace"] = new Color(128, 211, 128);
colorManager["flame"] = new Color(211, 34, 20);
//用户选择了定义的颜色
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();
Console.Read();
}
}
-
优势和缺陷
原型模式得到了广泛的应用,特别是在创建对象成本较大的情况下(初始化需占用较长时间,占用太多CPU资源或网络资源。比如通过Webservice或DCOM创建对象,或者创建对象要装载大文件),系统如果需要重复利用,新的对象可以通过原型模式对已有对象的属性进行复制并稍作修改来取得。另外,如果系统要保存对象的状态而对象的状态变化很小,或者对象本身占内存不大的时候,也可以用原型模式配合备忘录模式来应用。相反地,如果对象的状态变化很大,或者对象占用内存很大,那么采用状态模式会比原型模式更好。原型模式的缺点是在实现深层复制时需要编写复杂的代码。
-
应用情景
下面的情景很适合应用原型模式:
1. 类的实例化是动态的。
2. 你需要避免使用分层次的工厂类来创建分层次的对象。
3. 类的实例对象只有一个或很少的几个组合状态。