大话设计模式:原型模式
学无止境,精益求精
十年河东,十年河西,莫欺少年穷
学历代表你的过去,能力代表你的现在,学习代表你的将来
上篇博客介绍了C# 深浅复制,其实原型模式讲的主要就是对象的深浅复制 参考: C# 深浅复制 MemberwiseClone
OK,言归正传
原型模式的概念:
用原型实例指定创建对象的种类,并且通过拷贝这些原型对象来创建新的对象!
原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。
首先简单介绍下原型模式的应用场景,如下:
一般在初始化的信息不发生变动的情况下,不用重新初始化对象,而是动态的获得对象运行时的状态,克隆是最好的方法。这既隐藏了对象创建的细节,又对性能是大大的提高。
上述的解释似乎难以弄明白,现在我们来解释下:
我们知道,对象是通过构造函数来创建的,如果在构造函数中存在着大量的业务逻辑,那么这个对象的创建就会消耗不少的资源,这也意味着对象的创建过程会消耗掉一定的时间。如果我们需要一个‘类似’的对象,可以采用克隆的方式来创建这个对象,这样就可以不执行构造函数来创建一个新的对象,这个对象的创建将会大大提升性能!
因此,使用原型模式有以下条件:
1、初始化信息不发生变动时,可考虑使用原型模式来克隆对象
2、当通过构造函数创建一个新的实例会消耗过多资源时,可考虑使用原型模式来克隆对象
3、当需要动态获取对象运行时状态时,可考虑使用原型模式来克隆对象
总之:原型模式的基本理念就是在符合一定的场景下,通过克隆对象来动态获取对象的运行时状态并大大提升对象创建的效率!
何为克隆对象呢?
.net 在system 命名空间中提供了ICloneable 接口,其中就是唯一的一个方法Clone(),实现这个接口就可以完成原型模式了。
那么关于克隆的具体实现,大家还要参考上一篇博客:C# 深浅复制 MemberwiseClone
OK,上述从概念性的东西介绍原型模式,那么,我们现在进入实战:
1、原型模式的UML类图
2、原型模式在生活中的体现:
现实生活中,也有很多原型设计模式的例子,例如,细胞分裂的过程,一个细胞的有丝分裂产生两个相同的细胞;还有西游记中孙悟空变出后孙的本领和火影忍者中鸣人的隐分身忍术等。下面就以孙悟空为例子来演示下原型模式的实现。
具体的实现代码如下:
///孙悟空的的变化就是原型模式 class Client { static void Main(string[] args) { // 孙悟空 原型 MonkeyKingPrototype prototypeMonkeyKing = new ConcretePrototype("MonkeyKing"); // 变一个 MonkeyKingPrototype cloneMonkeyKing = prototypeMonkeyKing.Clone() as ConcretePrototype; Console.WriteLine("Cloned1:\t"+cloneMonkeyKing.Id); // 变两个 MonkeyKingPrototype cloneMonkeyKing2 = prototypeMonkeyKing.Clone() as ConcretePrototype; Console.WriteLine("Cloned2:\t" + cloneMonkeyKing2.Id); Console.ReadLine(); } } /// <summary> /// 孙悟空原型 /// </summary> public abstract class MonkeyKingPrototype { public string Id { get; set; } public MonkeyKingPrototype(string id) { this.Id = id; } // 克隆方法,即孙大圣说“变” public abstract MonkeyKingPrototype Clone(); } /// <summary> /// 创建具体原型 /// </summary> public class ConcretePrototype : MonkeyKingPrototype { public ConcretePrototype(string id) : base(id) { } /// <summary> /// 浅拷贝 /// </summary> /// <returns></returns> public override MonkeyKingPrototype Clone() { // 调用MemberwiseClone方法实现的是浅拷贝,另外还有深拷贝 return (MonkeyKingPrototype)this.MemberwiseClone(); } }
上述代码通过‘浅复制’来创建孙悟空的副本!并没有涉及到深复制。
关于深/浅复制,在我的上篇博客中已经非常详细的介绍了,在此不再列举其他案例!
原型模式的优点有:
- 原型模式向客户隐藏了创建新实例的复杂性
- 原型模式允许动态增加或较少产品类。
- 原型模式简化了实例的创建结构,工厂方法模式需要有一个与产品类等级结构相同的等级结构,而原型模式不需要这样。
- 产品类不需要事先确定产品的等级结构,因为原型模式适用于任何的等级结构
原型模式的缺点有:
- 配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。
最后,列举下C#中用到的深浅复制,比如:C#中的数据集对象DataSet,它就有Clone()方法和Copy()方法,其中Clone()是用来复制DataSet的结构,相当于浅复制。Copy()方法不仅复制DataSet的结构,也会复制DataSet的数据,因此,Copy()方法类似于深复制!
@陈卧龙的博客