技术开发 频道

GOF设计模式 --- Prototype模式

老板说:“给我盖一座大楼。”

工程师说:“盖什么样的大楼呢?”

老板指着身后的一座楼说:“和那个一模一样的。”

    从老板的角度来讲,他采用的就是,Prototype模式,即原型模式。否则,他需要再花费一些时间和工程师一点一点的探讨关于大楼的一些设计问题。

    所谓的原型模式,就是用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

    JAVA的Object.clone()的存在,使得这个模型的学习变得简单了许多。

一、搭桥过河,过河是一门大学问

首先研究一下JAVA的clone技术。

我理解的很简单,无非是把一个对象进行复制粘贴。那么,来看一下JAVA语言中是如何来实现的这个步骤的。我们依次需要知道以下这些事。

1.Object对象中有一个clone()方法。而且是protected。

2.继承于Object的类一般都可以实现这个方法(有特殊的,比如StringBuffer等,官方定的,不去研究它)。

3.想被clone的对象需要实现接口Cloneable。如果此对象的类不能实现接口Cloneable,则会抛出CloneNotSupportedExcetion。

4.所有的数组都被视为实现接口Cloneable。

5.clone分为浅clone(又称影子clone)和深clone。

6.Object类本身不实现接口Cloneable,所以在类为Object的对象上调用clone方法,将会导致在运行时抛出异常。

首先来看一个能够实现clone类的小例子。

class CloneClass implements Cloneable { public int aInt; public Object clone() { CloneClass o = null; try { o = (CloneClass) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return o; } }
class UnCloneA { private int i; public UnCloneA(int ii) { i = ii; } public void doublevalue() { i *= 2; } public String toString() { return Integer.toString(i); } } class CloneB implements Cloneable { public int aInt; public UnCloneA unCA = new UnCloneA(111); public Object clone() { CloneB o = null; try { o = (CloneB) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return o; } } class CloneMain { public static void main(String[] a) { CloneB b1 = new CloneB(); b1.aInt = 11; System.out.println("before clone,b1.aInt = " + b1.aInt); System.out.println("before clone,b1.unCA = " + b1.unCA); CloneB b2 = (CloneB) b1.clone(); b2.aInt = 22; b2.unCA.doublevalue(); System.out.println("================================="); System.out.println("after clone,b1.aInt = " + b1.aInt); System.out.println("after clone,b1.unCA = " + b1.unCA); System.out.println("================================="); System.out.println("after clone,b2.aInt = " + b2.aInt); System.out.println("after clone,b2.unCA = " + b2.unCA); } }

至于浅clone和深clone,无非就是一个程度问题。再来看一个例子。
输出结果为:
/** RUN RESULT:
before clone,b1.aInt = 11
before clone,b1.unCA = 111
=================================
after clone,b1.aInt = 11
after clone,b1.unCA = 222
=================================
after clone,b2.aInt = 22
after clone,b2.unCA = 222
*/

   可见,当执行clone这个动作的时候,系统首先开辟一个和它一样的空间。然后分别对其内容进行复制。复制过程中,如果是基本类型,没什么说的,直接把值复制过来。如果不是基本类型,复制的则是该类型对象的引用。

    这样的clone就是所谓的浅clone。那很显然,如果上面复制的过程中,对于非基本类型实现的不是一个引用复制,而是创建一个新的一样的对象(其实也是一个clone步骤),那么就是所谓的深clone。对于深度克隆只不过是clone的一种扩展,还有N深clone等等。对于这些,和我们要研究的原型模式没有多少关系。不想去研究。


   关于JAVA的clone技术,对我来说,理解这些就够了。其它的,就是进一步的扩展及应用。

 二、以长克短,什么时候会想到用原型模式呢

这个我们学习任何一项技术都要问自己的问题。


    要用它,就要知道它的优点。合理的利用它的优点来为我们服务。做人也一样,不要总拿自己的短处去比别人的长处。要知道,每个人都是不一样的,每个人都有自己的长处和短处。这就是以长克短。

    JAVA中的clone方法,其实现是native的。这也就意味着它的执行效率是远高于new一个新对象的。所以,当需要生成大量相似对象的时候,可以考虑下应用clone,也就是原形模式。

    我的项目经验几乎为0,单纯从理解的角度去想的。

    至于其它的应用,还有待前辈们指点。我再不断补充。

0
相关文章