原型设计模式及其java实现

原型设计模式思想

  原型模式的思想在于可以不必了解一个对象本来的构造过程,仅根据这个对象本身构造一个跟他一样的对象。
  有时候我无从得知一个对象的构建过程,抑或是我们无法调用该过程(比如从网络获取并反序列化一个对象),或者该过程开销太大。这时候就该原型模式发挥作用了。
  对象可以将一些“公有字段”转发到自己原型上去。众所周知, javascript的动态类型系统是基于原型链的。也就是说,使用原型模式,你完全可以构造一套自己的(动态)类型系统出来。
  在这里有两个问题需要回答,1. 为什么不使用静态类型系统表示这种“持有公共字段”。2. 为什么原型表达的是动态类型系统。(也许这两个问题实际上是一个问题)

为什么不使用静态类型系统

  静态类型系统是零抽象成本的,在可以使用静态类型系统的任何时候,都应该优先使用静态类型系统。但是开发中难免遇到静态类型系统无法解决的问题,或者解决起来很棘手的问题。最典型的难以在编译期确定的事情就是 – 用户交互的运行时行为。比如上文提到的该对象必须从网络反序列化获取。亦或者考虑如下的例子。
  在某个游戏开发环境中,构建一个“敌军”对象需要从文本文件中读取配置,经过大量的判断语句(因为无法预知运行时的情况,所以必须使用大量判断,而文件IO和判断语句都是非常消耗性能的。)才能构建出来,但是一局游戏中所有敌军都是大体相同的。于是乎我们可采取如下的模式:从复杂逻辑中构建出一个原型,然后从该原型大量复制对象,并做轻量级的定制。因为复制一个字段往往是很快的,所以这个办法要比每次都从文件读取配置信息然后经过大量判断语句要快,且清晰。

为什么原型表达的是动态类型系统

  有时候我们会想要将一些对象的行为转发到他的原型上去。比如拷贝自统一原型的敌军总是有相同的血条颜色。那么我们就没有必要给每个对象复制血条颜色这个属性,而是直接指向原型的血条颜色属性即可。这样一来原型就表达了类型的信息,而原型作为类型本身是一个实打实的对象,这实际上就是动态类型系统了。

拷贝与转发

  上面提到,有时候我们希望将对象的行为转发到它的原型上去,但有时候我们又希望每一个原型都有自己的某个字段。不难想到,转发使用指针/引用就可以完成,“私有”字段通过深拷贝就可以实现。

原型模式的Java实现

(深)拷贝

  与python不同, Java没有提供默认的deepcopy标准库。我们需要自己来实现深拷贝。 深拷贝实际上是一个非常困难的事情,因为我们必须非常仔细的处理循环引用,所以这里不得不使用一些图论算法,由于本文不是讲算法的,我这里就不手写了(其实是懒+怕写错,不过以后说不定会写一个的)。
  值得一提的是,序列化本身就是深拷贝的过程,所以我们可以借助序列化实现深拷贝,不过Java中并非每一个字段都可以序列化的,比如枚举类在序列化上存在一定的限制,文件描述符这种本地信息的序列化也没有意义,其中复杂本文这里暂不叙述了。

浅拷贝(转发)

  Java的Object类自带的clone方法就是浅拷贝的。不过基本类型的浅拷贝就是深拷贝,所以如果需要转发基本类型到原型对象的话,需要使用包装类型,然后用引用转发。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值