记录《Head First 设计模式》
参考 Graphic Design Patterns网站 与 深入设计模式
目的是检查学习情况,同时方便以后复习。
文章目录
一、间述
1-1 意图
**原型模式 PrototypePattern:使你能够复制已有的对象,而无需使代码依赖它们所属的类。 又称为单件模式或单态模式。该模式是一种 创建型模式 。
1-2 动机
1-3 结构图
1-4 时序图
二、代码示例:
1-1 浅拷贝与深拷贝代码实现
代码实现
/// <summary>
/// 原型模式:是一种创建型结构,可以复制当前对象,而不需要依赖
/// </summary>
public class Person
{
public int Age;
public DateTime BirthDate;
public string Name;
public IdInfo IdInfo;
/// <summary>
/// 浅拷贝:当前对象被拷贝,但当前对象的字段不会被拷贝(举例Name、IdInfo)。
/// </summary>
/// <returns></returns>
public Person ShallowCopy()
{
return (Person)this.MemberwiseClone();
}
/// <summary>
/// 深拷贝:对对象实例中字段引用的对象也进行拷贝。
/// </summary>
/// <returns>返回一个全新的Persom对象</returns>
public Person DeepCopy()
{
Person clone = (Person)this.MemberwiseClone();
//深拷贝重新定义引用类型的字段
clone.IdInfo = new IdInfo(IdInfo.IdNumber);
clone.Name = string.Copy(Name);
return clone;
}
}
/// <summary>
/// Id信息
/// </summary>
public class IdInfo
{
public int IdNumber;
public IdInfo(int idNumber)
{
this.IdNumber = idNumber;
}
}
测试调用
class Program
{
static void Main(string[] args)
{
Person p1 = new Person();
p1.BirthDate = Convert.ToDateTime("1995-01-01");
p1.Age = DateTime.Now.Year-p1.BirthDate.Year;
p1.Name = "Prototype";
p1.IdInfo = new IdInfo(123123);
// 将P1浅拷贝为P2
Person p2 = p1.ShallowCopy();
// 将P1深拷贝为P3
Person p3 = p1.DeepCopy();
// 展示P1、P2、P3的值
Console.WriteLine("展示 p1, p2, p3值:");
Console.WriteLine(" p1 : ");
DisplayValues(p1);
Console.WriteLine(" p2 :");
DisplayValues(p2);
Console.WriteLine(" p3:");
DisplayValues(p3);
// 改变原型P1的值
p1.Age = 32;
p1.BirthDate = Convert.ToDateTime("1900-01-01");
p1.Name = "Frank";
p1.IdInfo.IdNumber = 123456;
Console.WriteLine("P1改变后,展示 p1, p2, p3值");
Console.WriteLine(" P1: ");
DisplayValues(p1);
Console.WriteLine(" p2 :");
DisplayValues(p2);
Console.WriteLine(" p3 :");
DisplayValues(p3);
Console.ReadKey();
}
执行结果
![](https://i-blog.csdnimg.cn/blog_migrate/4d62036c525aee674161cff1021306b1.png)
其中 Console.ReadKey(); 进行断言,调试–>找到"即时窗口",输入“&P1.IdInfo回车”,查看P1、P2、P3的IdInfo的内存地址是否是同一个。
![](https://i-blog.csdnimg.cn/blog_migrate/4e346cfc726223c51a489864df913fcd.png)
1-2 浅拷贝与深拷贝区别
- 浅拷贝:指当对象的字段值被拷贝时,字段引用的对象不会被拷贝。
当前对象字符串类型字段改变数据,浅拷贝对象的字段会改变值。
例如:如果一个对象有一个指向字符串的字段,同时我们对该对象做了一个浅拷贝,那么这两个对象将引用同一个字符串。 - 深拷贝:指当对象的字段值被拷贝时,字段引用的对象会被拷贝。
当前对象字段串类型的字段改变数据,深拷贝对象的字段不会改变值。
例如:如果一个对象有一个指向字符串的字段,同时我们对该对象进行了深拷贝的话,那么我们将创建一个对象和一个新的字符串,新的对象将引用新的字符串。
也就是说,执行深拷贝创建的新对象和原来对象不会共享任何东西,改变一个对象对另外一个对象没有任何影响。而执行浅拷贝创建的新对象与原来对象共享成员,改变一个对象,另外一个对象的成员也会改变。
三 总结
1-1 模式优缺点
优点:
- 提供让客户产生未知类型对象的选项。
- 可以克隆预生成原型,避免反复运行初始化代码。
- 在某些环境下,复制对象比创建对象更有用
缺点:
- 克隆包含循环引用的复杂对象可能会非常麻烦
1-2 适合场景
适用场景:
- 在一个复杂的类层次中,当系统必须从其中的许多类型中创建对象,可以考虑原型。
- 如果需要复制一些对象,同时希望复制的对象独立于这些对象所属的具体类,可以使用原型模式。
- 如果子类的区别仅在于对象的初始化方式,那么你可以使用该模式来减少子类的数量。别人创建这些子类的目的可能是为了创建特定类的对象。
1-3 模式应用
模式应用:
- 细胞分裂。
1-4 总结
- 客户代码在不知道要实例化何种特定类的情况下,可以制造出新的实例。
- 通常需要创建一个中心化原型注册表,用于存储常用原型
- 原型模式可以通过 clone 或 copy 等方法识别。
- 当创建给定类的实例很昂贵或复杂时,可以使用原型模式。