小菜学习设计模式(四)—原型(Prototype)模式
2014-02-12 09:51
337 查看
前言
设计模式目录:小菜学习设计模式(一)—模板方法(Template)模式
小菜学习设计模式(二)—单例(Singleton)模式
小菜学习设计模式(三)—工厂方法(Factory Method)模式
小菜学习设计模式(四)—原型(Prototype)模式
小菜学习设计模式(五)—控制反转(Ioc)
持续更新中。。。
本篇目录:
概述
实现
深拷贝(Deep Copy)
后记
其实说到原型模式,大家可能会想到Clone,其实也不尽然,在我们的日常生活中,原型(Prototype)模式也可以经常看到:
你觉得某位明星的发型很好看,你也想做个和他一样的发型,于是你拿个照片去理发店说:我要做个和这个一模一样的发型。
其实那个明星的发型某种意义上说就是原型,因为已经有发型参考了,所以发型师会很快的做出来。就像我们在编程时,当创建一些对象(特别是大对象)非常耗时时,或者创建过程非常复杂时,原型模式就会很有用。
概述
我们看下GoF对原型(Prototype)模式下的定义:使用原型模型实例指定将要创建的对象类型,通过复制这个实例创建新的对象。
从这个定义中,我们可以分解下,其实说的意思就是:指定类型,复制对象。就像上面的例子,造型就是一个指定的类型,然后去复制此类型的对象。原型模型的简单静态类图:
/// <summary> /// 心脏类 /// </summary> public class Heart { private int _size; private int _volume; /// <summary> /// 大小 /// </summary> public int Size { get { return _size; } set { _size = value; } } /// <summary> /// 体积 /// </summary> public int Volume { get { return _volume; } set { _volume = value; } } } /// <summary> /// baby类 /// </summary> public class Baby : ICloneable { private string _name; private string _description; private Heart _hearttype; /// <summary> /// 名称 /// </summary> public string Name { get { return _name; } set { _name = value; } } /// <summary> /// 描述 /// </summary> public string Description { get { return _description; } set { _description = value; } } /// <summary> /// 心脏特征 /// </summary> public Heart HeartType { get { return _hearttype; } set { _hearttype = value; } } #region ICloneable 成员 public object Clone() { return this.MemberwiseClone(); } #endregion }
View Code
测试代码:
static void Main(string[] args) { Baby baby1 = new Baby(); baby1.Name = "I'm baby1"; baby1.Description = "I'm baby"; baby1.HeartType = new Heart() { Size = 111, Volume = 222 }; Baby baby2 = (Baby)baby1.Clone(); baby2.Name = "I'm baby2"; Console.WriteLine("baby1 info:"); Console.WriteLine(baby1.Name); Console.WriteLine(baby1.Description); Console.WriteLine("baby2 info:"); Console.WriteLine(baby2.Name); Console.WriteLine(baby2.Description); Console.WriteLine("The heart of the different:"); Console.WriteLine(baby1.HeartType == baby2.HeartType); }
运行结果:
我们可以看到baby1.HeartType和baby2.HeartType的引用地址是一样的,这种就是浅拷贝(Shallow Copy),就说明baby1和baby2公用一个心脏,是连体双胞胎。
深拷贝(Deep Copy)
其实上面的代码稍微修改下就是深拷贝,如下:static void Main(string[] args) { Baby baby1 = new Baby(); baby1.Name = "I'm baby1"; baby1.Description = "I'm baby"; baby1.HeartType = new Heart() { Size = 111, Volume = 222 }; Baby baby2 = (Baby)baby1.Clone(); baby2.HeartType = new Heart() { Size = 111, Volume = 222 };//重新创建对象 baby2.Name = "I'm baby2"; Console.WriteLine("baby1 info:"); Console.WriteLine(baby1.Name); Console.WriteLine(baby1.Description); Console.WriteLine("baby2 info:"); Console.WriteLine(baby2.Name); Console.WriteLine(baby2.Description); Console.WriteLine("The heart of the different:"); Console.WriteLine(baby1.HeartType == baby2.HeartType); }
上面给baby2重新创建一个和baby1一样的心脏,而不是公用一个,运行结果:
可以看到baby1.HeartType和baby2.HeartType的引用地址是不一样的,虽然是一样的心脏,但是是两个独立相同的心脏,其实上面的方法并不算是深拷贝,只是实现了深拷贝的效果,因为并不是在拷贝中完成的。这种气势有个不好的地方,当一个对象中有很多对象组合的时候,而且这个对象内部很复杂,我们不可能复制完之后,每个对象的去重新赋值,这样实现深拷贝就没有什么意义。当然还有一种实现深拷贝的方式就是序列化,必须在类的前面加上[Serializable]表示,指示这个类是可以序列化的,我们把Clone()的方法修改下:
public object Clone() { object result = null; MemoryStream stream = new MemoryStream(); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(stream, this); stream.Close(); byte[] streamByte = stream.ToArray(); MemoryStream stream2 = new MemoryStream(streamByte); result = formatter.Deserialize(stream2); stream2.Close(); return result; }
现在Clone()方法做的工作就是序列化和反序列化,我们使用浅拷贝的测试代码,运行结果为:
baby1.HeartType和baby2.HeartType的引用地址是不一样的,和上面重新赋值对象的效果是一样的,但是我们调用的时候没有做额外的操作,就可以实现此效果,但是序列化和反序列化是比较耗时的,这点也需要注意下。
示例代码下载:Prototype.rar
后记
关于创建型模式上面几篇说的差不多,还有个针对工厂方法模式出现问题的解决方案,下面就是结构型模式了,还在学习中,未完待续。。。相关文章推荐
- 小菜学习设计模式(四)—原型(Prototype)模式
- 设计模式学习笔记(四)——Prototype原型
- 设计模式学习笔记(六)——Prototype原型模式
- 【HeadFirst 设计模式学习笔记】18 原型(Prototype)模式拾零
- 步步为营 .NET 设计模式学习笔记 五、Prototype(原型模式)
- C#面向对象设计模式学习笔记(5) - Prototype 原型模式(创建型模式)
- 学习php设计模式 php实现原型模式(prototype)
- 设计模式入门学习 原型Prototype模式
- 设计模式学习笔记--工厂(Factory)、建造(Builder)和原型(Prototype)
- 设计模式学习笔记--Prototype原型模式
- 设计模式学习笔记(六)——Prototype原型模式
- 学习php设计模式 php实现原型模式(prototype)
- 设计模式系列学习四:原型模式(Prototype)
- HeadFirst 设计模式学习笔记19--原型(Prototype)模式拾零
- 设计模式学习笔记_原型模式(prototype)
- 设计模式学习笔记(六)——Prototype原型模式
- 设计模式学习笔记——原型(Prototype)框架
- 设计模式学习之--原型模式(Prototype)
- 设计模式学习-Prototype(原型)
- 设计模式学习之原型模式(Prototype,创建型模式)(5)