原型模式简述
定义: 使用原型实例指定待建立对象的类型,而且经过复制这个原型来建立新的对象
,也就是经过复制现有对象实例产生新的对象,也就是所谓的“克隆”java
实现方式:数组
一、实现Cloneable接口安全
Cloneable接口的做用是在运行时通知虚拟机能够安全地在实现了此接口的类上使用clone方法。在java虚拟机中,只有实现了这个接口的类才能够被拷贝,不然在运行时会抛出CloneNotSupportedException异常。ide
二、重写Object的clone方法函数
Java中,全部类的父类都是Object类,Object类中有一个clone方法,返回对象的一个拷贝,可是其做用域protected类型的,通常的类没法调用,所以,原型类须要将clone方法的做用域修改成public类型。测试
原型模式结构
原型模式包含3个角色:this
1)Prototype(抽象原型类):声明克隆方法的抽象类或接口,是全部具体原型类的父类spa
2)ConcretePrototype(具体原型类):实现抽象原型类声明的克隆方法,实现自我克隆的功能code
3)Client(客户端):请求原型对象克隆自身从而建立一个新的对象对象
代码事例
/** * 抽象原型类 * * @author kaifeng * @date 2018/8/26 */ public abstract class Prototype implements Cloneable { /** * 获取名称 * * @return */ public abstract String getName(); /** * 抽象拷贝方法 * * @return Object * @throws CloneNotSupportedException */ public abstract Object copy() throws CloneNotSupportedException; } /** * 具体原型类One * * @author kaifeng * @date 2018/8/26 */ public class ConcretePrototypeOne extends Prototype { private String name; public ConcretePrototypeOne(String name) { this.name = name; } /** * 获取名称 * * @return */ @Override public String getName() { return this.name; } /** * 抽象拷贝方法 * * @return Object * @throws CloneNotSupportedException */ @Override public Object copy() throws CloneNotSupportedException { return super.clone(); } } /** * 具体原型类Two * * @author kaifeng * @date 2018/8/26 */ public class ConcretePrototypeTwo extends Prototype { private String name; public ConcretePrototypeTwo(String name) { this.name = name; } /** * 获取名称 * * @return */ @Override public String getName() { return this.name; } /** * 抽象拷贝方法 * * @return Object * @throws CloneNotSupportedException */ @Override public Object copy() throws CloneNotSupportedException { return super.clone(); } } /** * 原型模式测试 * * @author kaifeng * @date 2018/8/26 */ public class ProtoTypeDemo { public static void main(String[] args) throws CloneNotSupportedException { Prototype p1 = new ConcretePrototypeTwo("two"); System.out.println(p1.getName()); Prototype p2 = (ConcretePrototypeTwo) p1.copy(); System.out.println(p2.getName()); } }
优势
一、隐藏了制造新实例的复杂性,使得建立对象就像咱们在编辑文档时的复制粘贴同样简单
二、当建立对象的实例较为复杂的时候,使用原型模式能够简化对象的建立过程,经过复制一个已有的实例能够提升实例的建立效率。
缺点
一、因为使用原型模式复制对象时不会调用类的构造方法,因此原型模式没法和单例模式组合使用,由于原型类须要将clone方法的做用域修改成public类型,那么单例模式的条件就没法知足了。
二、Object类的clone方法只会拷贝对象中的基本数据类型,对于数组,引用对象等只能另行拷贝
适用场景
一、若是建立新对象成本较大,咱们能够利用已有的对象进行复制来得到。
二、若是系统要保存对象的状态,而对象的状态变化很小,或者对象自己占内存不大的时候,也能够使用原型模式配合备忘录模式来应用。相反,若是对象的状态变化很大,或者对象占用的内存很大,那么采用状态模式会比原型模式更好。
三、须要避免使用分层次的工厂类来建立分层次的对象,而且类的实例对象只有一个或不多的几个组合状态,经过复制原型对象获得新实例可能比使用构造函数建立一个新实例更加方便。
深拷贝(克隆)与浅拷贝(克隆)
浅拷贝:
一个对象复制后,基本数据类型的变量都会从新建立,而引用类型,指向的仍是原对象所指向的。
深拷贝:
一个对象复制后,不管是基本数据类型还有引用类型,都是从新建立的。
java 的clone克隆是浅克隆,对于引用对象,克隆出来的对象和原对象中的引用将指向同一个对象。一般实现深克隆的方法是将对象进行序列化,而后再进行反序列化。