原型模式个人以为最适合的场景:参照现有的某一个对象实例,快速得到多个完整的实例副本。(通常是深拷贝的副本)
深拷贝在c#中实现的最简单方式莫过于通过反序列化得到一个全新的对象实例。(当然如果浅拷贝的话,方法就很多了,比如利用MemberwiseClone或反射属性自动赋值都可以)
场景:还是游戏场景,就拿三国来说吧,打仗时可能需要小兵若干,每个小兵可能还要骑马...(简单起见其它东东就不提了,比如可能每个小兵还要带兵器若干),这些个实例的数量是动态的,
但是几乎每个小兵的属性都完全相同,每匹战马的属性也相同,很显然写一堆的new()造出若干实例,再逐一对属性赋值是可行的,但是并非最好的做法,下面看看原型的实现:
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 }
类图:
ps:原型模式其实最早的应用不是计算机领域,而是中国古代的活字印刷术。