原型模式
定义
以一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。用这种方式创建对象非常高效,根本无需知道对象创建的细节。简单描述就是“对象克隆”,在初始化的信息不发生变化的情况下,克隆是最好的办法,既隐藏了对象创建的细节,又大大提高了性能。因为如果不用clone,每次new都需要执行一次构造函数,如果构造函数的执行时间很长,那么多次的执行初始化操作就太低效了。
原型模式拷贝对象分为两种:”浅拷贝”和“深拷贝”
浅拷贝
被拷贝对象的所有变量都含有与原对象相同的值,而且对其他对象的引用仍然是指向原来的对象。即浅克隆只负责当前对象实例,对引用的对象不做拷贝(这句多理解下)
深拷贝
除了拷贝当前实例,同时对引用的对象也做了一次拷贝。深拷贝要深入到多少层,是一个不确定的问题。在决定以深拷贝的方式拷贝一个对象的时候,必须决定对间接拷贝的对象是采取浅拷贝还是深拷贝。因此,在采取深拷贝是,需要决定多深才算深。此外,在深拷贝过程中,很可能出现循环引用的问题。故原型模式实现深度拷贝比较困难。
原型模式类图
原型模式包含以下主要角色:
- 抽象原型类:规定了具体原型对象必须实现的接口
- 具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象
- 访问类:使用具体原型类中的 clone() 方法来复制新的对象
应用场景
- 对象之间相同或相似,即只是个别的几个属性不同的时候
- 创建对象成本较大,例如初始化时间长,占用cpu太多,或者占用网络资源太多等,需要优化资源
- 创建一个对象需要繁琐的数据准备或访问权限等,需要提高性能或者提高安全性
- 系统中大量使用该类对象,且各个调用者都需要给他们属性重新赋值
简单示例
public class IdInfo
{
//身份证号码
public int IdNumber;
public IdInfo(int IdNumber)
{
this.IdNumber = IdNumber;
}
}
public class Person
{
public string Name;
public IdInfo IdInfo;
//浅克隆
public Person Clone()
{
return (Person)this.MemberwiseClone();
}
//深度克隆
public Person DeepClone()
{
Person other = (Person)this.MemberwiseClone();
other.IdInfo = new IdInfo(IdInfo.IdNumber);
other.Name = String.Copy(Name);
return other;
}
}