天天看點

原型模式原型模式接口Cloneablehashcode和引用回歸正題--原型模式總結

原型模式

原型模式中,誰涉及到對象的克隆,對象的引用和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)是用于建立重複的對象,同時又能保證性能。這種類型的設計模式屬于建立型模式,它提供了一種建立對象的最佳方式。

類圖

原型模式原型模式接口Cloneablehashcode和引用回歸正題--原型模式總結

代碼實作

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方法.