前言

设计模式目录:

本篇目录:

  其实说到原型模式,大家可能会想到Clone,其实也不尽然,在我们的日常生活中,原型(Prototype)模式也可以经常看到:

你觉得某位明星的发型很好看,你也想做个和他一样的发型,于是你拿个照片去理发店说:我要做个和这个一模一样的发型。

  其实那个明星的发型某种意义上说就是原型,因为已经有发型参考了,所以发型师会很快的做出来。就像我们在编程时,当创建一些对象(特别是大对象)非常耗时时,或者创建过程非常复杂时,原型模式就会很有用。

概述

  我们看下GoF对原型(Prototype)模式下的定义:

使用原型模型实例指定将要创建的对象类型,通过复制这个实例创建新的对象。

  从这个定义中,我们可以分解下,其实说的意思就是:指定类型,复制对象。就像上面的例子,造型就是一个指定的类型,然后去复制此类型的对象。原型模型的简单静态类图:

小菜学习设计模式(四)—原型(Prototype)模式

  Client使用Prototype的Clone()方法得到这个对象的副本,我们先看下引用类型的存储:引用类型的变量在栈中分配一个内存空间,这个内存空间包含的是对另一个内存位置的引用,这个位置是托管堆中的一个地址,即存放此变量实际值的地方。.NET自动维护一个堆指针,它包含堆中下一个可用内存空间的地址。就是说引用类型在栈中存储一个托管堆的地址,托管堆存储这个变量的实际值。上面所说的“复制对象”在原型(Prototype)模式中分为两种,一种是只复制栈中的托管堆地址,就是说副本对象和原对象指向的托管堆的地址是一样的,这种复制称为浅拷贝(Shallow Copy);另一种是栈中存放的地址和托管堆中实际值都复制,就是说生成一个和原对象一样的全新对象,这种复制称为深拷贝(Deep Copy)。

  我们用一张示意图可以简单概述下:

小菜学习设计模式(四)—原型(Prototype)模式

  其实关于浅拷贝和深拷贝在我们现实生活中也有相应类似的例子,比如双胞胎,长的一样就像一个模子刻出来的一样,而且各自有各自的身体互不影响,在某种意义上说可以称为深拷贝;在双胞胎中也有一些特殊的,比如连体双胞胎,有的两个身体公用一个心脏什么的,怎么说呢,在某种意义上这种你也可以称为浅拷贝。这个例子只是形象说明下原型模式中复制对象的含义,可能有些不恰当的地方。

实现

  其实在.net中关于浅拷贝提供了一个方法MemberwiseClone();

小菜学习设计模式(四)—原型(Prototype)模式

  MemberwiseClone()方法返回的是Object类型,注意方法的修饰符是protected,就是说,如果想让外部对象使用它,必须在子类重写该方法,设定其访问范围是public。还有就是实现对象的复制必须实现ICloneable接口,并实现其Clone()方法。就上面说的双胞胎的例子,我们做一个简单的示例:

 1     /// <summary>
 2     /// 心脏类
 3     /// </summary>
 4     public class Heart
 5     {
 6         private int _size;
 7         private int _volume;
 8         /// <summary>
 9         /// 大小
10         /// </summary>
11         public int Size
12         {
13             get { return _size; }
14             set { _size = value; }
15         }
16         /// <summary>
17         /// 体积
18         /// </summary>
19         public int Volume
20         {
21             get { return _volume; }
22             set { _volume = value; }
23         }
24     }
25 
26     /// <summary>
27     /// baby类
28     /// </summary>
29     public class Baby : ICloneable
30     {
31         private string _name;
32         private string _description;
33         private Heart _hearttype;
34         /// <summary>
35         /// 名称
36         /// </summary>
37         public string Name
38         {
39             get { return _name; }
40             set { _name = value; }
41         }
42         /// <summary>
43         /// 描述
44         /// </summary>
45         public string Description
46         {
47             get { return _description; }
48             set { _description = value; }
49         }
50         /// <summary>
51         /// 心脏特征
52         /// </summary>
53         public Heart HeartType
54         {
55             get { return _hearttype; }
56             set { _hearttype = value; }
57         }
58 
59         #region ICloneable 成员
60         public object Clone()
61         {
62             return this.MemberwiseClone();
63         }
64         #endregion
65     }
View Code

相关文章:

  • 2021-11-13
  • 2021-10-24
  • 2021-11-10
  • 2021-11-20
  • 2021-12-31
  • 2021-10-16
  • 2021-06-13
  • 2021-08-09
猜你喜欢
  • 2022-01-21
  • 2022-12-23
  • 2021-07-18
  • 2021-05-08
  • 2021-11-11
相关资源
相似解决方案