实现Prototype设计模式

** 实现 ** ** Prototype ** ** 设计模式 ** ** **

** Implementing the Prototype design Pattern **

当我建立一个类的实例很复杂时,我们可以使用 Prototype 模式。与其建立很多类的实例,还不如进行适当的修改后,使用最初的实例的副本。使用 ** Prototype ** ** 模式 ** ,可以通过克隆一个原型,减少子类的数量。 Prototype 模式可以减少类的实例的数量。

在这个模式中,通过克隆来创建对象。我们有时创建很多的子类,除了通过很多的子类来创建不同的对象,我们还可以只需要唯一的一个子类,这个子类保持对每个对象基类的引用,并通过这个子类创建对象。通过向子类的构造函数传递参数并克隆对象。每个对象都实现 clone 方法,所以可以被克隆。我们可以使用 ** Prototype ** ** 模式,通过克隆 ** 原型 ** 来减少子类的数量。 ** ** **

** ** ** 克隆可以通过实现 ** Icloneable 接口来实现。 Icloneable 接口中唯一的方法是 Clone ,并返回一个新的类的实例。

** ICloneable.Clone method signature
** [VisualBasic] **_Function Clone() As Object
_ ** [C#] **_object Clone();

_ **

**_
_ ** 我们必须了解 Clone() 方法只是一种浅表复制( Shallow copy ),而不是深层复制( Deep copy )。所以它只是返回一个引用,而不象深层复制( Deep copy )那样创建一个复制的实例。我们可以通过使用 Iserializable 接口来实现深层复制( Deep copy )。

另一个缺点就是原型的每个子类必须实现 Clone() 方法,有时候,增加 clone 方法是很困难的。

在这个例子中,我建立了 EmpData 类,并且实现了 Icloneable 接口和 Iserializable 接口。 Icloneable 接口需要实现 Clone 方法,使得类可以被复制。 Iserializable 接口为了实现对 EmpData 类的深层复制( Deep copy )。使用的方法为:将 EmpData 对象序列化为一个文件,也可以将这个文件反序列化为一个 EmpData 对象。

EmpData 类包含两个方法: GetEmpData 和 ChangeEmpData 。这两个方法被用来以一个字符串( string )的形式获取 EmpData 对象、更改 EmpData 类。每个方法都可以被调用,来检验浅表复制( Shallow copy )和深层复制( Deep copy )的不同。浅表复制( Shallow copy )时,如果 EmpData 类改变时,这个变化也会同时出现在 EmpData 的克隆对象中;而在深层复制( Deep copy ),如果 EmpData 对象发生改变时,这个变化不会出现在 EmpData 的克隆对象中。

EmpData 类的构造函数读取 XML 文件并创建 Emp 对象。

** XML ** ** 文件 ** ** **


** VB.Net ** ** 实现 ** ** **

Imports System.Xml

Imports System.IO

Imports System.Collections

Imports System.Runtime.Serialization

Imports System.Runtime.Serialization.Formatters.Binary

  1<serializable()> Public  Class  CEmpData 
  2
  3Implements  ICloneable, ISerializable 
  4
  5Private  ArrEmp  As  ArrayList 
  6
  7Public  Sub  New  () 
  8
  9Dim  xmldoc  As  New  XmlDocument 
 10
 11Dim  node  As  XmlNode 
 12
 13Dim  objEmp  As  CEmp 
 14
 15ArrEmp =  New  ArrayList 
 16
 17xmldoc.Load("empdata.xml") 
 18
 19For  Each  node  In  xmldoc.DocumentElement.ChildNodes 
 20
 21objEmp =  New  CEmp 
 22
 23objEmp.FName = node.SelectSingleNode("firstname").InnerText 
 24
 25objEmp.LName = node.SelectSingleNode("lastname").InnerText 
 26
 27ArrEmp.Add(objEmp) 
 28
 29Next 
 30
 31End  Sub 
 32
 33Public  Sub  New  (  ByVal  info  As  SerializationInfo,  ByVal  context  As  StreamingContext) 
 34
 35Dim  intIndex  As  Integer 
 36
 37Dim  intCount  As  Integer 
 38
 39Dim  objEmp  As  CEmp 
 40
 41ArrEmp =  New  ArrayList 
 42
 43intCount =  CInt  (info.GetValue("emp_count",  GetType  (  String  ))) 
 44
 45For  intIndex = 0  To  intCount - 1 
 46
 47objEmp =  New  CEmp(info, context, intIndex) 
 48
 49ArrEmp.Add(objEmp) 
 50
 51Next 
 52
 53End  Sub 
 54
 55Public  Function  Clone()  As  Object  Implements  ICloneable.Clone 
 56
 57Try 
 58
 59Return  Me 
 60
 61Catch  ex  As  Exception 
 62
 63MsgBox(ex.ToString) 
 64
 65End  Try 
 66
 67End  Function 
 68
 69Public  Function  Clone(  ByVal  Deep  As  Boolean  )  As  Object 
 70
 71Try 
 72
 73If  Deep  Then 
 74
 75Return  CreateDeepCopy() 
 76
 77Else 
 78
 79Return  Clone() 
 80
 81End  If 
 82
 83Catch  ex  As  Exception 
 84
 85MsgBox(ex.ToString) 
 86
 87End  Try 
 88
 89End  Function 
 90
 91Private  Function  CreateDeepCopy()  As  CEmpData 
 92
 93Dim  objEmpCopy  As  CEmpData 
 94
 95Dim  objStream  As  Stream 
 96
 97Dim  objBinFormatter  As  New  BinaryFormatter 
 98
 99Try 
100
101objStream = File.Open("Empdata.bin", FileMode.Create) 
102
103objBinFormatter.Serialize(objStream,  Me  ) 
104
105objStream.Close() 
106
107objStream = File.Open("Empdata.bin", FileMode.Open) 
108
109objEmpCopy =  CType  (objBinFormatter.Deserialize(objStream), CEmpData) 
110
111objStream.Close() 
112
113CreateDeepCopy = objEmpCopy 
114
115Catch  ex  As  Exception 
116
117MsgBox(ex.ToString) 
118
119End  Try 
120
121End  Function 
122
123Public  Sub  GetObjectData(  ByVal  info  As  System.Runtime.Serialization.SerializationInfo,  ByVal  context  As  System.Runtime.Serialization.StreamingContext)  Implements  System.Runtime.Serialization.ISerializable.GetObjectData 
124
125Dim  intIndex  As  Integer 
126
127Dim  objEmp  As  CEmp 
128
129info.AddValue("emp_count", ArrEmp.Count) 
130
131For  intIndex = 0  To  ArrEmp.Count - 1 
132
133objEmp = ArrEmp(intIndex) 
134
135objEmp.GetObjectData(info, context, intIndex) 
136
137Next 
138
139End  Sub 
140
141Public  Function  GetEmpData()  As  String 
142
143Dim  intCount  As  Integer 
144
145Dim  strEmpData  As  String 
146
147For  intCount = 0  To  ArrEmp.Count - 1 
148
149strEmpData = strEmpData &amp; CType  (ArrEmp(intCount), CEmp).FName &amp; Chr(9) &amp; CType  (ArrEmp(intCount), CEmp).LName &amp; Chr(13) 
150
151Next 
152
153GetEmpData = strEmpData 
154
155End  Function 
156
157Public  Sub  ChangeEmpData() 
158
159Dim  objEmp  As  CEmp 
160
161For  Each  objEmp  In  ArrEmp 
162
163objEmp.FName = "FirstName" 
164
165objEmp.LName = "LastName" 
166
167Next 
168
169End  Sub 
170
171End  Class 
172
173Public  Class  CEmp 
174
175Private  mstrFName  As  String 
176
177Private  mstrLName  As  String 
178
179Public  Property  FName()  As  String 
180
181Get 
182
183FName = mstrFName 
184
185End  Get 
186
187Set  (  ByVal  Value  As  String  ) 
188
189mstrFName = Value 
190
191End  Set 
192
193End  Property 
194
195Public  Property  LName()  As  String 
196
197Get 
198
199LName = mstrLName 
200
201End  Get 
202
203Set  (  ByVal  Value  As  String  ) 
204
205mstrLName = Value 
206
207End  Set 
208
209End  Property 
210
211Public  Sub  New  () 
212
213End  Sub 
214
215&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-l   
216---</serializable()>
Published At
Categories with Web编程
Tagged with
comments powered by Disqus