原型模式
原型模式中,誰涉及到對象的克隆,對象的引用和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)是用于建立重複的對象,同時又能保證性能。這種類型的設計模式屬于建立型模式,它提供了一種建立對象的最佳方式。
類圖
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcugjMmFGM1UzNiFTM0UTM0M2MidTY0ImY2UTNxQGZ5YmNfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.png)
代碼實作
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方法.