实现Prototype设计模式

原创 2004年05月26日 16:28:00

      实现Prototype设计模式<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

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类包含两个方法:GetEmpDataChangeEmpData。这两个方法被用来以一个字符串(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

<Serializable()> Public Class CEmpData

    Implements ICloneable, ISerializable

    Private ArrEmp As ArrayList

    Public Sub New()

        Dim xmldoc As New XmlDocument

        Dim node As XmlNode

        Dim objEmp As CEmp

        ArrEmp = New ArrayList

        xmldoc.Load("empdata.xml")

        For Each node In xmldoc.DocumentElement.ChildNodes

            objEmp = New CEmp

            objEmp.FName = node.SelectSingleNode("firstname").InnerText

            objEmp.LName = node.SelectSingleNode("lastname").InnerText

            ArrEmp.Add(objEmp)

        Next

    End Sub

    Public Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)

        Dim intIndex As Integer

        Dim intCount As Integer

        Dim objEmp As CEmp

        ArrEmp = New ArrayList

        intCount = CInt(info.GetValue("emp_count", GetType(String)))

        For intIndex = 0 To intCount - 1

            objEmp = New CEmp(info, context, intIndex)

            ArrEmp.Add(objEmp)

        Next

    End Sub

    Public Function Clone() As Object Implements ICloneable.Clone

        Try

            Return Me

        Catch ex As Exception

            MsgBox(ex.ToString)

        End Try

    End Function

    Public Function Clone(ByVal Deep As Boolean) As Object

        Try

            If Deep Then

                Return CreateDeepCopy()

            Else

                Return Clone()

            End If

        Catch ex As Exception

            MsgBox(ex.ToString)

        End Try

    End Function

    Private Function CreateDeepCopy() As CEmpData

        Dim objEmpCopy As CEmpData

        Dim objStream As Stream

        Dim objBinFormatter As New BinaryFormatter

        Try

            objStream = File.Open("Empdata.bin", FileMode.Create)

            objBinFormatter.Serialize(objStream, Me)

            objStream.Close()

            objStream = File.Open("Empdata.bin", FileMode.Open)

            objEmpCopy = CType(objBinFormatter.Deserialize(objStream), CEmpData)

            objStream.Close()

            CreateDeepCopy = objEmpCopy

        Catch ex As Exception

            MsgBox(ex.ToString)

        End Try

    End Function

    Public Sub GetObjectData(ByVal info As System.Runtime.Serialization.SerializationInfo, ByVal context As System.Runtime.Serialization.StreamingContext) Implements System.Runtime.Serialization.ISerializable.GetObjectData

        Dim intIndex As Integer

        Dim objEmp As CEmp

        info.AddValue("emp_count", ArrEmp.Count)

        For intIndex = 0 To ArrEmp.Count - 1

            objEmp = ArrEmp(intIndex)

            objEmp.GetObjectData(info, context, intIndex)

        Next

    End Sub

    Public Function GetEmpData() As String

        Dim intCount As Integer

        Dim strEmpData As String

        For intCount = 0 To ArrEmp.Count - 1

            strEmpData = strEmpData & CType(ArrEmp(intCount), CEmp).FName & Chr(9) & CType(ArrEmp(intCount), CEmp).LName & Chr(13)

        Next

        GetEmpData = strEmpData

    End Function

    Public Sub ChangeEmpData()

        Dim objEmp As CEmp

        For Each objEmp In ArrEmp

            objEmp.FName = "FirstName"

            objEmp.LName = "LastName"

        Next

    End Sub

End Class

Public Class CEmp

    Private mstrFName As String

    Private mstrLName As String

    Public Property FName() As String

        Get

            FName = mstrFName

        End Get

        Set(ByVal Value As String)

            mstrFName = Value

        End Set

    End Property

    Public Property LName() As String

        Get

            LName = mstrLName

        End Get

        Set(ByVal Value As String)

            mstrLName = Value

        End Set

    End Property

    Public Sub New()

    End Sub

    Public Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext, ByVal intIndex As Integer)

        mstrFName = CStr(info.GetValue("emp_fname" & intIndex, GetType(String)))

        mstrLName = CStr(info.GetValue("emp_lname" & intIndex, GetType(String)))

    End Sub

    Public Sub GetObjectData(ByVal info As SerializationInfo, ByVal context As StreamingContext, ByVal intIndex As Long)

        info.AddValue("emp_fname" & intIndex, mstrFName)

        info.AddValue("emp_lname" & intIndex, mstrLName)

    End Sub

End Class

设计模式总结之Prototype Pattern(原型模式)

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
  • cooldragon
  • cooldragon
  • 2016年08月11日 00:43
  • 1455

设计模式(创建型)之原型模式(Prototype Pattern)

要理解原型原型模式必须先理解Java里的浅复制和深复制。有的地方,复制也叫做克隆。Java提供这两种克隆方式。 因为Java中的提供clone()方法来实现对象的克隆,所以Prototype模式实现一...
  • yanbober
  • yanbober
  • 2015年04月29日 11:28
  • 3042

我与C++设计模式(四)——prototype pattern

我故意将bia
  • guozhengdong
  • guozhengdong
  • 2014年10月01日 10:20
  • 497

设计模式之——设计模式使用率排行榜

Java设计模式使用率爬行榜 使用频率 所属类型 模式名称 模式 简单定义 5 创建型 Singleton 单例模式 保证一个类只有一个实例,并提供一个访问它的...
  • wind19
  • wind19
  • 2011年11月15日 14:29
  • 1173

哪些设计模式是降低资源使用率:----腾讯2016研发工程师笔试题(一)

哪些设计模式是降低资源使用率: 正确答案: B C  prototype singleton flyweight abstract factory...
  • chengonghao
  • chengonghao
  • 2016年07月11日 20:00
  • 1518

深拷贝、浅拷贝以及Prototype模式

我们在编码过程经常会碰到将一个对象传递给另一个对象,java中对于基本型变量采用的是值传递,而对于对象比如bean传递时采用的引用传递也就是地址传递,而很多时候对于对象传递我们也希望能够象值传递一样,...
  • u011510502
  • u011510502
  • 2016年04月25日 00:00
  • 651

js中的prototype和基于prototype的继承总结

与其他编译语言的继承相比,javascript也有一套继承实现方式,即使用prototype原型及其链的方式。1、我们先用一个简单的例子先理解原型链, (http://img.blog.csdn.n...
  • houyaowei
  • houyaowei
  • 2016年05月18日 15:00
  • 259

Prototype设计模式的实现

Prototype设计模式的实现Implementing the Prototype design Pattern       下载本文代码当我建立一个类的实例很复杂时,我们可以使用Prototype...
  • guoyan19811021
  • guoyan19811021
  • 2004年04月23日 13:25
  • 1077

实现Prototype设计模式

标题  实现Prototype设计模式     关键字  Prototype 设计模式 模式出处  http://www.dotnetextreme.com/articles/PrototypePat...
  • colayungnew
  • colayungnew
  • 2004年10月05日 13:17
  • 498

JavaScript 利用prototype原型实现封装继承多态

js基于原型prototype封装继承多态 function Person(name,age) { this.name=name; this.age=age; } Person.proto...
  • u012997311
  • u012997311
  • 2017年04月18日 17:10
  • 453
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:实现Prototype设计模式
举报原因:
原因补充:

(最多只允许输入30个字)