23种设计模式之原型模式(Prototype Pattern)
原型模式
使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象
分析:
孙悟空:根据自己的形状复制(克隆)出多个身外身
软件开发:通过复制一个原型对象得到多个与原型对象一模一样的新对象
工作原理:将一个原型对象传给要发动创建的对象(即客户端对象),这个要发动创建的对象通过请求原型对象复制自己来实现创建过程
View Code
View Code
创建新对象(也称为克隆对象)的工厂就是原型类自身,工厂方法由负责复制原型对象的克隆方法来实现
通过克隆方法所创建的对象是全新的对象,它们在内存中拥有新的地址,每一个克隆对象都是独立的
通过不同的方式对克隆对象进行修改以后,可以得到一系列相似但不完全相同的对象
原型模式的结构
原型模式包含以下3个角色:
•Prototype(抽象原型类)
•ConcretePrototype(具体原型类)
•Client(客户类)
浅克隆与深克隆
浅克隆(Shallow Clone):当原型对象被复制时,只复制它本身和其中包含的值类型的成员变量,而引用类型的成员变量并没有复制
深克隆(Deep Clone):除了对象本身被复制外,对象所包含的所有成员变量也将被复制
1 /// <summary> 2 /// 原型模式:单例的基础上升级了一下,把对象从内存层面复制了一下,然后返回 3 /// 是个新对象,但是又不是new出来的 4 /// </summary> 5 [Serializable] 6 public class Prototype 7 { 8 /// <summary> 9 /// 构造函数耗时耗资源 10 /// </summary> 11 private Prototype() 12 { 13 long lResult = 0; 14 for (int i = 0; i < 10000000; i++) 15 { 16 lResult += i; 17 } 18 Thread.Sleep(2000); 19 Console.WriteLine("{0}被构造一次", this.GetType().Name); 20 } 21 /// <summary> 22 /// 3 全局唯一静态 重用这个变量 23 /// </summary> 24 private static volatile Prototype _Prototype = new Prototype() 25 { 26 CurrentEmployee = "admin", 27 Member = new Member { Id=1,Name="aaa"} 28 }; 29 /// <summary> 30 /// 2 公开的静态方法提供对象实例 31 /// </summary> 32 /// <returns></returns> 33 public static Prototype CreateInstance() 34 { 35 Prototype prototype = (Prototype)_Prototype.MemberwiseClone(); 36 return prototype; 37 } 38 public static Prototype DeepClone() 39 { 40 Prototype prototype = JsonConvert.DeserializeObject<Prototype>(JsonConvert.SerializeObject(_Prototype)); 41 return prototype; 42 } 43 public Member Member { get; set; } 44 public string CurrentEmployee { get; set; } 45 } 46 [Serializable] 47 public class Member 48 { 49 public int Id { get; set; } 50 public string Name { get; set; } 51 }
前端调用
1 {//浅拷贝 2 Prototype prototype1 = Prototype.CreateInstance(); 3 Prototype prototype2 = Prototype.CreateInstance(); 4 prototype1.CurrentEmployee = "prototype1"; 5 prototype1.Member.Id = 2; 6 prototype1.Member.Name = "bbb"; 7 prototype2.CurrentEmployee = "prototype2"; 8 prototype2.Member.Id = 3; 9 prototype2.Member.Name = "ccc"; 10 Console.WriteLine(prototype1.CurrentEmployee); 11 Console.WriteLine(prototype1.Member.Id); 12 Console.WriteLine(prototype1.Member.Name); 13 Console.WriteLine(prototype2.CurrentEmployee); 14 Console.WriteLine(prototype2.Member.Id); 15 Console.WriteLine(prototype2.Member.Name); 16 } 17 {//深拷贝 18 Prototype prototype1 = Prototype.DeepClone(); 19 Prototype prototype2 = Prototype.DeepClone(); 20 prototype1.CurrentEmployee = "prototype1"; 21 prototype1.Member.Id = 2; 22 prototype1.Member.Name = "bbb"; 23 prototype2.CurrentEmployee = "prototype2"; 24 prototype2.Member.Id = 3; 25 prototype2.Member.Name = "ccc"; 26 Console.WriteLine(prototype1.CurrentEmployee); 27 Console.WriteLine(prototype1.Member.Id); 28 Console.WriteLine(prototype1.Member.Name); 29 Console.WriteLine(prototype2.CurrentEmployee); 30 Console.WriteLine(prototype2.Member.Id); 31 Console.WriteLine(prototype2.Member.Name); 32 }
执行结果
深度拷贝就是利用序列化与反序列化创建对象,这种方法好像也走构造函数,那么还不如直接new 就失去了原型模式的意义了
作者:德乌姆列特
本博客所有文章仅用于学习、研究和交流目的,欢迎非商业性质转载。
博主的文章没有高度、深度和广度,只是凑字数。由于博主的水平不高,不足和错误之处在所难免,希望大家能够批评指出。
博主是利用读书、参考、引用、抄袭、复制和粘贴等多种方式打造成自己的文章,请原谅博主成为一个无耻的文档搬运工!