设计模式 -- 原型模式

当克隆优于建立java

原型模式属于对象的建立模式。经过给出一个原型对象来指明全部建立的对象的类型,而后用复制这个原型对象的办法建立出更多同类型的对象。安全

场景

  • 当你的系统并不想关心一个对象的建立,组合的细节.
  • 一个对象须要提供给其余对象访问,并且各个调用者可能都须要修改其值时,能够考虑使用原型模式拷贝多个对象供调用者使用
  • 当一个类的实例只有几种状态的时候,先建立好这几种实例,须要时clone,好过每次建立新的,而后设置到合适的状态.
  • 当建立对象的代价大于克隆

用法

原型模式要求对象实现一个能够“克隆”自身的接口,这样就能够经过复制新的实例出来.
clone是Object类的方法,其实原型模式在某种程度上和java融为一体.
有时原型模式和工厂模式结合在一块儿,用于为工厂创造新的对象.
在原型模式的使用中,浅拷贝和深拷贝是须要注意的地方.设计

克隆

Java的全部类都是从java.lang.Object类继承而来的,而Object类提供protected Object clone()方法对对象进行复制,子类固然也能够把这个方法置换掉,提供知足本身须要的复制方法。对象的复制有一个基本问题,就是对象一般都有对其余的对象的引用。当使用Object类的clone()方法来复制一个对象时,此对象对其余对象的引用也同时会被复制一份.对象

Java语言提供的Cloneable接口只起一个做用,就是在运行时期通知Java虚拟机能够安全地在这个类上使用clone()方法。经过调用这个clone()方法能够获得一个对象的复制。因为Object类自己并不实现Cloneable接口,所以若是所考虑的类没有实现Cloneable接口时,调用clone()方法会抛出CloneNotSupportedException异常。继承

克隆知足的条件:
clone()方法将对象复制了一份并返还给调用者。“复制”的含义即clone()方法是怎么实现的。
通常而言,clone()方法知足如下的要求:接口

  1. 对任何的对象x,都有:x.clone()!=x。换言之,克隆对象与原对象不是同一个对象。
  2. 对任何的对象x,都有:x.clone().getClass() == x.getClass(),换言之,克隆对象与原对象的类型同样。
  3. 若是对象x的equals()方法定义其恰当的话,那么x.clone().equals(x)应当成立的。
    在JAVA语言的API中,凡是提供了clone()方法的类,都知足上面的这些条件。JAVA语言的设计师在设计本身的clone()方法时,也应当遵照着三个条件。通常来讲,上面的三个条件中的前两个是必需的,而第三个是可选的。

浅拷贝

只负责克隆按值传递的数据(好比基本数据类型、String类型),而不复制它所引用的对象.
换言之,全部的对其余对象的引用都仍然指向原来的对象
Object默认的clone方式是这样作的.get

深拷贝

除了浅度克隆要克隆的值外,还负责克隆引用类型的数据。那些引用其余对象的变量将指向被复制过的新对象,而再也不是原有的那些被引用的对象.换言之,深度克隆把要复制的对象所引用的对象都复制了一遍,而这种对被引用到的对象的复制叫作间接复制。
深拷贝通常有两种方式:原型

  1. 经过实现Cloneable接口,复写clone方法,咱们能够自定义一个对象的克隆.
  2. 经过序列化和反序列化实现克隆. 这样作的前提就是对象以及对象内部全部引用到的对象都是可序列化的,不然,就须要仔细考察那些不可序列化的对象能否设成transient,从而将之排除在复制过程以外。
相关文章
相关标签/搜索