原型模式
原型模式中,谁涉及到对象的克隆,对象的引用和hashcode,以及原型的思想和创建.
在这里,自己将自己的理解和实践记录下来,和大家一起学习.
接口Cloneable
Note that this interface does <i>not</i> contain the <tt>clone</tt> method.
* Therefore, it is not possible to clone an object merely by virtue of the
* fact that it implements this interface. Even if the clone method is invoked
* reflectively, there is no guarantee that it will succeed.
大体意思是
cloneble 保证 你的对象能在jvm中 安全的 被克隆,这里没有clone方法.要想克隆需要 重写clone 方法.
hashcode和引用
对象的引用: reference(C++中引用的概念是是指针的地址,java中引用在栈中,对外不开放),不是hashCode!
hashCode是用hash算法(hash算法有很多种)在散列存储结构中确定对象的存储地址的,如Hashtable,HashMap中对象的存储.
Object中的hashCode是一个内存地址经过hash运算后得到的hash值,但是hash值也有可能相同.
hashCode相同,表示两个对象再同一个篮子,然后equals来寻找两个对象是不是相同.
等号(==):
对比对象实例的内存地址(也即对象实例的ID),来判断是否是同一对象实例;又可以说是判断对象实例是否物理相等();
1.重写equals时候,qual的规则要和重写的hashcode相同.否则,用hashmap时候,将会有因为当你用hashSet()等的时候,会存在不同的hashCode,导致保存了两个不同的对象.
关于hashcode,这是两篇不错的深入文章
[传送门1]
[传送门2]
Object中的native方法clone()
protected native Object clone() throws CloneNotSupportedException;
clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。
JVM为每个新创建的线程都分配一个堆栈.
深拷贝和浅拷贝
浅拷贝
使用一个已知实例对新创建实例的成员变量逐个赋值,这个方式被称为浅拷贝。java中的8中基本类型以及他们的封装类型,另外还有String.
所以,要想实现浅克隆,就要实现cloeable接口,重写clone()方法!
深拷贝
当一个类的拷贝构造方法,不仅要复制对象的所有非引用成员变量值,还要为引用类型的成员变量创建新的实例,并且初始化为形式参数实例值。这个方式称为深拷贝.
方法1:将逐层的对象进行 实现cloeable接口,重写clone()方法!
方法2:将对象串行化.
回归正题--原型模式
一般来讲,结合工厂模式,进行 队形缓存..
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
类图
代码实现
Shape抽象类进行浅克隆
public abstract class Shape implements Cloneable{
private String id;
protected String type;
abstract void draw();
/**
* 重写clone的方法
* 强转 super为Shape类型
*/
@Override
protected Shape clone() {
// TODO Auto-generated method stub
Shape object=null;
try {
object= (Shape)super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return object;
}
//...省略set,get方法
缓存类ShapeCache
public class ShapeCache {
/** @pdOid 568f3806-35b0-41de-8ba3-149c1027b27b */
private static HashMap<String, Shape> shapeCacheMap = new HashMap<>();
/**
* 简单---缓存
*
* @param type
* Traingle创建三角形traingle,Circle创建圆形Circle
* @return 缓存中的 Shape
*/
public static Shape getShape(String type) {
Shape shape = null;
shape = shapeCacheMap.get(type);
return shape.clone();
}
/**
* 当需要更新缓存时,调用
*
* @param type
* @return
*/
public static Shape loadChache(String type) {
Shape shape = null;
switch (type) {
case "Traingle":
shape=new Traingle();
shape.setId("1");
shapeCacheMap.put(type, shape);
break;
case "Circle":
shape=new Circle();
shape.setId("2");
shapeCacheMap.put(type, shape);
break;
default:
break;
}
return shape;
}
}
总结
原型模式,就是一种保存原数据不变的缓存策略.
作用:
备份源数据,当多次频繁调用源数据(多次连接数据库),此时,只需要调用缓存中的目标的clone,来节省时间和空间.
过程:
当调用clone的时候,并不会调用构造函数,创建新的对象,而是通过一个本地方法,直接将数据写入到另外一个地方.完成对象克隆.
注意点:
当拷贝一个对象时,会发生深拷贝的有java中的8中基本类型以及他们的封装类型,另外还有String类型。其余的都是浅拷贝.如果想实现深拷贝,需要将他的成员对象所在类中,继承cloneable,并实现clone方法.