原型模式的结构
原型模式包含以下3个角色:
•Prototype(抽象原型类)
•ConcretePrototype(具体原型类)
•Client(客户类)
浅克隆与深克隆
浅克隆(Shallow Clone):当原型对象被复制时,只复制它本身和其中包含的值类型的成员变量,而引用类型的成员变量并没有复制
深克隆(Deep Clone):除了对象本身被复制外,对象所包含的所有成员变量也将被复制
原型核心代码
/// <summary> /// 班级 /// </summary> [Serializable] public class Class { public int Num { get; set; } public string Remark { get; set; } } [Serializable] public class StudentPrototype { public int Id { get; set; } public string Name { get; set; } public Class Class { get; set; } private StudentPrototype() { } private static readonly StudentPrototype _studentPrototype = null; static StudentPrototype() { _studentPrototype = new StudentPrototype() { Id = 0, Name = "复制", Class = new Class() { Num = 100, Remark = "100" } }; } public static StudentPrototype CreateInstanceClone() { StudentPrototype studentPrototype = (StudentPrototype)_studentPrototype.MemberwiseClone(); //这样就是深clone,如果没有这段,Class实例就是浅克隆 studentPrototype.Class = new Class() { Num = 1, Remark = "软谋高级班" }; return studentPrototype; } public static StudentPrototype CreateInstanceSerialize() { //序列化方式创建克隆,需要保证被克隆的对象具有 serialize 特性标签 return SerializeHelper.DeepClone<StudentPrototype>(_studentPrototype); } }
原型模式的理解
原型模式在我的理解中时基于单例模式的一个扩展,在保证实例对象唯一的情况下,能快递new出不同的新实例
对外提供一个接口 CreateCloneInstance创建克隆对象
浅层次克隆
Console.WriteLine("*****浅层次克隆Start**********"); var box1 = StudentPrototype.CreateInstanceClone(); Console.WriteLine($"Id={box1.Id} name={box1.Name}"); var box2 = StudentPrototype.CreateInstanceClone(); box2.Id = 10; box2.Name = "测试"; Console.WriteLine($"Id={box2.Id} name={box2.Name}"); Console.WriteLine("*****浅层次克隆End**********");
深层次克隆1 失败+成功方法
{ //对值类型的克隆修改值,不会影响克隆出的新对象的内容。但是引用类型的克隆有需要注意的点,Class是引用类型的值,具有Num和Remark俩个属性。如果使用下面的写法 box1.Class.Num=***,实际上源对象Class地址和克隆对象地址相同,修改一个相当于全部修改了,并没有实现我们想要的克隆效果 Console.WriteLine("*****深层次克隆 Start**********"); var box1 = StudentPrototype.CreateInstanceClone(); box1.Class.Num = 10; box1.Class.Remark = "备注"; Console.WriteLine($"Id={box1.Id} name={box1.Name} ClassNum={box1.Class.Num } Remark={box1.Class.Remark }"); var box2 = StudentPrototype.CreateInstanceClone(); box2.Id = 10; box2.Name = "测试"; Console.WriteLine($"Id={box2.Id} name={box2.Name} ClassNum={box2.Class.Num } Remark={box2.Class.Remark }"); Console.WriteLine("*****深层次克隆 End**********"); }
深层次克隆2 序列化
{ //使用序列化的方式进行克隆原理,因为深层次克隆的主要问题是引用类型克隆时还是相同地址 //我们先将初始对象序列化,在将得到的值进行反序列化,这样便能保证生成的对象存在不同的地址引用 Console.WriteLine("*****深层次克隆2 序列化Start**********"); var box1 = StudentPrototype.CreateInstanceSerialize(); box1.Class.Num = 10; box1.Class.Remark = "备注"; Console.WriteLine($"Id={box1.Id} name={box1.Name} ClassNum={box1.Class.Num } Remark={box1.Class.Remark }"); var box2 = StudentPrototype.CreateInstanceSerialize(); box2.Id = 10; box2.Name = "测试"; Console.WriteLine($"Id={box2.Id} name={box2.Name} ClassNum={box2.Class.Num } Remark={box2.Class.Remark }"); Console.WriteLine("*****深层次克隆2 序列化End**********"); }
作者:HapplyFox
链接:https://www.jianshu.com/p/f9be55a79fa8
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦