原型模式(Prototype Pattern)

用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。

它通过复制一个已经存在的实例来返回新的实例,而不是新建实例.被复制的实例就是我们所称的原型,这个原型是可定制的.

原型模式多用于创建复杂的或者耗时的实例, 因为这种情况下,复制一个已经存在的实例可以使程序运行更高效,或者创建值相等,只是命名不一样的同类数据.

原型模式中的拷贝分为"浅拷贝"和"深拷贝":
浅拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量只复制引用,不复制引用的对象.
深拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量也进行引用对象的复制.

客户(Client)角色:客户端类向原型管理器提出创建对象的请求.
抽象原型(Prototype)角色:这是一个抽象角色,通常由一个C#接口或抽象类实现。此角色给出所有的具体原型类所需的接口。在C#中,抽象原型角色通常实现了ICloneable接口。
具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口。
原型管理器(Prototype Manager)角色:创建具体原型类的对象,并记录每一个被创建的对象。是一个关联存储器( associative store) ,它返回一个与给定关键字相匹配的原
型。它有一些操作可以用来通过关键字注册原型和解除注册。客户可以在运行时更改甚或浏
览这个注册表。这使得客户无需编写代码就可以扩展并得到系统清单。

原型模式的优点及适用场景

       使用原型模式创建对象比直接new一个对象在性能上要好的多,因为Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。

       使用原型模式的另一个好处是简化对象的创建,使得创建对象就像我们在编辑文档时的复制粘贴一样简单。

       当一个系统应该独立于它的产品创建、构成和表示时,要使用Prototype模式;在需要重复地创建相似对象时可以考虑使用原型模式。

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

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

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

       需要在一个循环体内创建对象,假如对象创建过程比较复杂或者循环次数很多的话,使用原型模式不但可以简化创建过程,而且可以使系统的整体性能提高很多。

 效果
对客户隐藏了具体的产品类,因此减少了客户知道的名字的数目。此外,使客户无需改变即可使用与特定应用相关的类。
1 ) 运行时刻增加和删除产品 :   Prototype允许只通过客户注册原型实例就可以将一个新的具体产品类并入系统。它比其他创建型模式更为灵活,因为客户可以在运行时刻建立和删除原型。
2 ) 改变值以指定新对象:   高度动态的系统允许你通过对象复合定义新的行为—例如,通过为一个对象变量指定值—并且不定义新的类。你通过实例化已有类并且将这些实例注册为客户对象的原型,就可以有效定义新类别的对象。客户可以将职责代理给原型,从而表现出新的行为。
3) 改变结构以指定新对象:   许多应用由部件和子部件来创建对象。
4 ) 减少子类的构造:  Factory Method(3.3)经常产生一个与产品类层次平行的Creator类层次。Prototype模式使得你克隆一个原型而不是请求一个工厂方法去产生一个新的对象。因此你根本不需要Creator类层次。
5) 用类动态配置应用: 一些运行时刻环境允许你动态将类装载到应用中。
Prototype的主要缺陷:
是每一个Prototype的子类都必须实现Clone操作,这可能很困难。例如,当所考虑的类已经存在时就难以新增Clone操作。当内部包括一些不支持拷贝或有循环引用的对象时,实现克隆可能也会很困难的。
.Net在System命名空间中提供了ICloneable接口,其唯一的一个方法Clone(),只需实现ICloneable接口就可以完成原型模式了;
posted @ 2016-09-21 13:43  池塘ddjyds  阅读(206)  评论(0编辑  收藏  举报