导航

原型模式

Posted on 2017-08-08 00:45  清浅ヾ  阅读(95)  评论(0编辑  收藏  举报
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace 原型模式
 7 {
 8     /// <summary>
 9     /// 原型类
10     /// 浅克隆vs深克隆
11     /// 原型创建对象速度更快,与单例不同,当某一个克隆对象的属性进行更改时,其它的克隆对象不会更改
12     /// </summary>
13    [Serializable]
14     class StudentPrototype
15     {
16         public string id { get; set; }
17         public string name { get; set; }
18         public Family family { get; set; }
19         private StudentPrototype()
20         {
21 
22         }
23         private static StudentPrototype _prototype = null;
24 
25         /// <summary>
26         /// 静态构造函数创建对象
27         /// </summary>
28         static StudentPrototype()
29         {
30             _prototype = new StudentPrototype()
31             {
32                 id = "001",
33                 name = "张三",
34                 family = new Family()
35                 {
36                     Member="父母,自己",
37                     Address="大街"
38                 }
39             };
40         }
41 
42         /// <summary>
43         ///浅克隆
44         /// </summary>
45         /// 
46         public static StudentPrototype ShallowClone
47         {
48           get
49           {
50             // 与单例稍微有点差别,浅克隆,该对象的属性是值类型可进行
51             StudentPrototype proto = (StudentPrototype)_prototype.MemberwiseClone();
52             return proto;
53           } 
54         }
55 
56         /// <summary>
57         /// 深克隆
58         /// </summary>
59         public static StudentPrototype DeepClone
60         {
61             get
62             {
63                 return SerializeHelper.DeepClone<StudentPrototype>(_prototype);
64             }
65         }
66     }
67 
68     [Serializable]
69     class Family
70     {
71         public string Member { get; set; }
72         public string Address { get; set; }
73     }
74 }
View Code

接下来写一个序列化和反序列化类供原型类调用

 1 using System;
 2 using System.Collections.Generic;
 3 using System.IO;
 4 using System.Linq;
 5 using System.Runtime.Serialization.Formatters.Binary;
 6 using System.Text;
 7 using System.Web.Script.Serialization;
 8 
 9 namespace 原型模式
10 {
11     class SerializeHelper
12     {
13         public static string Serlizer<T>(T data)
14         {
15             try
16             {
17                 using (var stream=new MemoryStream())
18                 {
19                     new BinaryFormatter().Serialize(stream, data);
20                     return Convert.ToBase64String(stream.ToArray());
21                 }
22                
23             }
24             catch (Exception)
25             {
26                 return null;
27             }
28         }
29         public static T DeSerlizer<T>(string data)
30         {
31             try
32             {
33                 byte[] buffer = Convert.FromBase64String(data);
34                 using (var stream=new MemoryStream(buffer))
35                 {
36                     return (T)new BinaryFormatter().Deserialize(stream);
37                 }
38             }
39             catch (Exception)
40             {
41                 return default(T);
42             }
43         }
44         public static T DeepClone<T>(T data)
45         {
46             return DeSerlizer<T>(Serlizer<T>(data));
47         }
48     }
49 }
View Code

在主程序中用调用原型类

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace 原型模式
 7 {
 8     class Program
 9     {
10         static void Main(string[] args)
11         {
12             try
13             {
14                 StudentPrototype pro1 = StudentPrototype.DeepClone; 
15                 StudentPrototype pro2 = StudentPrototype.DeepClone; //深克隆
16                 pro2.id = "002";
17                 pro2.name = "李四";
18                 pro2.family.Member = "只有我";
19                 pro2.family.Address = "小巷";
20                 Console.WriteLine("ID为{0},name为{1},成员为{2},地址为{3}", pro1.id, pro1.name, pro1.family.Member, pro1.family.Address);
21                 Console.WriteLine("ID为{0},name为{1},成员为{2},地址为{3}", pro2.id, pro2.name, pro2.family.Member, pro2.family.Address);
22                 Console.ReadLine();
23             }
24             catch (Exception)
25             {
26                 throw;
27             }
28         }
29     }
30 }
View Code

浅克隆与深克隆的区别
1.浅克隆:一个原型对象中的成员变量如果只为值类型,在调用它时,将复制一份给克隆对象。如果成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,当改变克隆对象的成员变量时,值类型会发生改变。如:成员变量int i=0; 现在克隆对象将 i=1;那么的到的结果也为1。当改变引用类型变量时,则不会发生变化。

2.深克隆:无论该原型对象的成员变量时值类型还是引用类型,调用时都将复制一份给克隆对象。当改变成员变量时,不管是值类型还是引用类型都将发生变化。