23种设计模式之原型模式(Prototype Pattern)

原型模式

使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象

分析:

孙悟空:根据自己的形状复制(克隆)出多个身外身
软件开发:通过复制一个原型对象得到多个与原型对象一模一样的新对象
 
工作原理:将一个原型对象传给要发动创建的对象(即客户端对象),这个要发动创建的对象通过请求原型对象复制自己来实现创建过程
创建新对象(也称为克隆对象)的工厂就是原型类自身,工厂方由负责复制原型对象的克隆方法来实现
通过克隆方法所创建的对象是全新的对象,它们在内存中拥有新的地址,每一个克隆对象都是独立
通过不同的方式对克隆对象进行修改以后,可以得到一系列相似但不完全相同的对象
 
原型模式的结构
原型模式包含以下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     }
View Code

前端调用

 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                 }
View Code

执行结果

23种设计模式之原型模式(Prototype Pattern)

深度拷贝就是利用序列化与反序列化创建对象,这种方法好像也走构造函数,那么还不如直接new 就失去了原型模式的意义了

本文参考文档:https://www.cnblogs.com/genesis/p/6097528.html