1. 程式人生 > 其它 >JAVA學習設計模式——原型模式

JAVA學習設計模式——原型模式

技術標籤:JAVA設計模式學習記錄設計模式學習java設計模式

目錄

原型模式簡介

原型模式是一種建立型設計模式,Prototype模式允許一個物件再建立另外一個可定製的物件,根本無需知道任何如何建立的細節,工作原理是:通過將一個原型物件傳給那個要發動建立的物件,這個要發動建立的物件通過請求原型物件拷貝它們自己來實施建立。

原型模式應用場景

原型模式適用於一些結構比較複雜的物件的建立,另外,由於原型模式是通過拷貝進行物件的建立,比直接new一個物件效能上更優,所以在需要建立大量物件時,也可以使用原型模式。

原型模式

使用原型模式時要用到一個介面Cloneable,該介面會提供一個clone方法,該函式是我們使用原型模式的核心。通過一個物件直接呼叫該方法就可以實現clone的功能
如下

 		Shape shape = new Shape();
        shape.setName("Circle");
        try {
            Shape shape1 = (Shape) shape.clone1();
            shape1.setName("Rectangle");

需要注意的一點是,在呼叫clone函式生成shape1時,該過程不會呼叫建構函式。

淺拷貝和深拷貝

java中記憶體分配

java把記憶體分兩種:一種是棧記憶體,另一種是堆記憶體
(1)在函式中定義的基本型別變數和物件的引用變數都在函式的棧記憶體中分配;
(2)堆記憶體用來存放由new建立的物件和陣列以及物件的例項變數。在函式(程式碼塊)中定義一個變數時,java就在棧中為這個變數分配記憶體空間,當超過變數的作用域後,java會自動釋放掉為該變數所分配的記憶體空間;在堆中分配的記憶體由java虛擬機器的自動垃圾回收器來管理
堆和棧的優缺點
堆的優勢是可以動態分配記憶體大小,生存期也不必事先告訴編譯器,因為它是在執行時動態分配記憶體的。
缺點就是要在執行時動態分配記憶體,存取速度較慢;棧的優勢是,存取速度比堆要快,僅次於直接位於CPU中的暫存器。

另外,棧資料可以共享。但缺點是,存在棧中的資料大小與生存期必須是確定的,缺乏靈活性。

淺拷貝和深拷貝的區別

首先說明 上面說過的介面中自帶的clone方法是淺拷貝

這兩種拷貝方法對於基本資料型別來說都是一樣的,但是對於引用資料型別,淺拷貝只是將其引用複製給另一個物件,也就是說這時兩個物件中的該變數共用同一塊記憶體空間。而深拷貝則是重新在記憶體中分配一塊地址空間給新的物件的該變數使用。

在我寫的例子程式碼中,使用淺拷貝和深拷貝執行結果並不相同(在此處,String型別變數賦新值時會自動建立一個新的地址控制元件,但是它不是基本資料型別,只是在這裡涉及到了java String池概念,感興趣的可以自己瞭解)

在淺拷貝時,分別列印shape和shape1中的內容如下圖

在這裡插入圖片描述

而使用深拷貝時,如下圖

在這裡插入圖片描述
這應該就能看出兩者的不同之處了

原始碼如下所示

User.java
package Prototype;

public class User {
    public static void main(String[] args) {
        Shape shape = new Shape();
        shape.setName("Circle");
        try {
            Shape shape1 = (Shape) shape.clone1();
            shape1.setName("Rectangle");
            shape.printAddress();
            shape1.printAddress();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

Shape.java(其中clone是淺拷貝,clone1是深拷貝)
package Prototype;

import java.util.HashMap;

public class Shape implements Cloneable{
    String name;
    HashMap<Integer,String> hashMap = new HashMap<>();
    public void setName(String n){
        name = n;
        hashMap.put(1,name);
    }
    public String getName(){
        return name;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    protected Object clone1() throws CloneNotSupportedException {
        Shape shape1 =null;
        try{
            shape1 = (Shape) super.clone();
            shape1.hashMap=new HashMap<>();

        }catch (CloneNotSupportedException e){
            e.getMessage();
        }
        return shape1;
    }


    public void printAddress(){
        System.out.println("name:"+name+"   hashMap:"+hashMap.get(1));
    }
}


文章參考:https://www.cnblogs.com/bupt-liqi/p/10896489.html
https://www.cnblogs.com/fengyumeng/p/10646487.html

專案程式碼上傳至Github中,需要可前往下載
連結:https://github.com/jianqiang-Zhang/ProtoTypePattern