PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN。因为CSDN也支持MarkDown语法了,牛逼啊!
要理解原型原型模式必须先理解Java里的浅复制和深复制。有的地方,复制也叫做克隆。Java提供这两种克隆方式。 因为Java中的提供clone()方法来实现对象的克隆,所以Prototype模式实现一下子变得很简单。
浅克隆:被克隆对象的所有变量都含有与原来的对象相同的值,而它所有的对其他对象的引用都仍然指向原来的对象。换一种说法就是浅克隆仅仅克隆所考虑的对象,而不克隆它所引用的对象。
深克隆:被克隆对象的所有变量都含有与原来的对象相同的值,但它所有的对其他对象的引用不再是原有的,而这是指向被复制过的新对象。换言之,深复制把要复制的对象的所有引用的对象都复制了一遍,这种叫做间接复制。
克隆必须满足的条件:
在java中实现clone()应该满足以上三个条件(前两个是必须的,第三个是推荐但不强制的)。
概念: 使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。原型模式是一种对象创建型模式。
重点: 原型模式结构重要核心模块:
实现Cloneable接口
在java语言有一个Cloneable接口,它的作用只有一个,就是在运行时通知虚拟机可以安全地在实现了此接口的类上使用clone方法。在java虚拟机中,只有实现了这个接口的类才可以被拷贝,否则在运行时会抛出CloneNotSupportedException异常。
重写Object类中的clone方法
Java中,所有类的父类都是Object类,Object类中有一个clone方法,作用是返回对象的一个拷贝,但是其作用域protected类型的,一般的类无法调用,因此,Prototype类需要将clone方法的作用域修改为public类型。
创建新对象成本较大(如初始化需要占用较长的时间,占用太多的CPU资源或网络资源),新的对象可以通过原型模式对已有对象进行复制来获得,如果是相似对象,则可以对其成员变量稍作修改。
如果系统要保存对象的状态,而对象的状态变化很小,或者对象本身占用内存较少时,可以使用原型模式配合备忘录模式来实现。
需要避免使用分层次的工厂类来创建分层次的对象,并且类的实例对象只有一个或很少的几个组合状态,通过复制原型对象得到新实例可能比使用构造函数创建一个新实例更加方便。
package yanbober.github.io;
//实现Cloneable接口,重写Object类中的clone方法
class MonkeyPrototype implements Cloneable {
@Override
protected MonkeyPrototype clone() throws CloneNotSupportedException {
MonkeyPrototype monkeyPrototype = (MonkeyPrototype) super.clone();
return monkeyPrototype;
}
}
//原型模式实现类
class ConcreteMonkeyPrototype extends MonkeyPrototype {
public void printHasCode() {
System.out.println("ConcreteMonkeyPrototype hascode="+this.hashCode());
}
}
public class Main {
public static void main(String[] args) {
ConcreteMonkeyPrototype type = new ConcreteMonkeyPrototype();
type.printHasCode();
for (int index=0; index<5; index++) {
try {
ConcreteMonkeyPrototype clone = (ConcreteMonkeyPrototype) type.clone();
clone.printHasCode();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
}
运行结果:
ConcreteMonkeyPrototype hascode=356573597
ConcreteMonkeyPrototype hascode=1735600054
ConcreteMonkeyPrototype hascode=21685669
ConcreteMonkeyPrototype hascode=2133927002
ConcreteMonkeyPrototype hascode=1836019240
ConcreteMonkeyPrototype hascode=325040804
使用原型模式复制对象不会调用类的构造方法
因为对象的复制是通过调用Object类的clone方法来完成的,它直接在内存中复制数据,因此不会调用到类的构造方法。不但构造方法中的代码不会执行,甚至连访问权限都对原型模式无效。还记得单例模式吗?单例模式中,只要将构造方法的访问权限设置为private型,就可以实现单例。但是clone方法直接无视构造方法的权限,所以,单例模式与原型模式是冲突的,在使用时要特别注意。
原型模式优点如下:
原型模式缺点如下:
设计模式(创建型)之原型模式(Prototype Pattern)
原文地址:http://blog.csdn.net/yanbober/article/details/45363525