原型模式个人以为最适合的场景:参照现有的某一个对象实例,快速得到多个完整的实例副本。(通常是深拷贝的副本)
深拷贝在c#中实现的最简单方式莫过于通过反序列化得到一个全新的对象实例。(当然如果浅拷贝的话,方法就很多了,比如利用MemberwiseClone或反射属性自动赋值都可以)
场景:还是游戏场景,就拿三国来说吧,打仗时可能需要小兵若干,每个小兵可能还要骑马...(简单起见其它东东就不提了,比如可能每个小兵还要带兵器若干),这些个实例的数量是动态的,
但是几乎每个小兵的属性都完全相同,每匹战马的属性也相同,很显然写一堆的new()造出若干实例,再逐一对属性赋值是可行的,但是并非最好的做法,下面看看原型的实现:
原型模式代码示例-by 菩提树下的杨过
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Runtime.Serialization.Formatters.Binary;
5
6 namespace Prototype
7 {
8 class Program
9 {
10 static void Main(string[] args)
11 {
12 #region 构造原型库
13 PrototypeManager pm = new PrototypeManager();
14 string _solider = "solider",_horse = "horse";
15 pm[_solider] = new Soldier() { Name = "小兵", Life = 300 };
16 pm[_horse] = new Horse() { Life = 250 };
17 #endregion
18
19 //从原型库里批量复制出若干实例
20 Soldier s1 = pm[_solider].Clone() as Soldier;
21 Soldier s2 = pm[_solider].Clone() as Soldier;
22 Soldier s3 = pm[_solider].Clone() as Soldier;
23
24 Horse h1 = pm[_horse].Clone() as Horse;
25 Horse h2 = pm[_horse].Clone() as Horse;
26
27 //测试对象引用是否相同
28 Console.WriteLine(object.ReferenceEquals(s1, s2));
29 Console.WriteLine(object.ReferenceEquals(h1, h2));
30
31 Console.Read();
32
33 }
34
35
36 }
37
38 [Serializable]
39 public class Prototype //原型 父类
40 {
41 public Prototype Clone()
42 {
43 MemoryStream ms = new MemoryStream();
44 BinaryFormatter bf = new BinaryFormatter();
45 bf.Serialize(ms, this);
46 ms.Position = 0;
47 return bf.Deserialize(ms) as Prototype;
48 }
49 }
50
51 /// <summary>
52 /// 小兵
53 /// </summary>
54 [Serializable]
55 public class Soldier : Prototype
56 {
57 public string Name//名称
58 {
59 set;
60 get;
61 }
62
63 public int Life //生命值
64 {
65 set;
66 get;
67 }
68 }
69
70
71 /// <summary>
72 /// 战马
73 /// </summary>
74 [Serializable]
75 public class Horse : Prototype
76 {
77
78 public int Life //生命值
79 {
80 set;
81 get;
82 }
83 }
84
85 /// <summary>
86 /// 原型管理器(即原型库,注:并非必需的,但通常保留一个,方便用此来创建原型实例)
87 /// </summary>
88 public class PrototypeManager
89 {
90 Dictionary<string, Prototype> dic = new Dictionary<string, Prototype>();
91
92 public Prototype this[string name]
93 {
94 set
95 {
96 dic[name] = value;
97 }
98
99 get
100 {
101 return dic[name];
102 }
103 }
104 }
105
106 }
107
类图:
ps:原型模式其实最早的应用不是计算机领域,而是中国古代的活字印刷术.