Java設計模式——原型模式

概述

原型模式是一個創建型的模式。該模式有一個樣板實例,用戶從這個樣板對象中複製出一個內部屬性一致的對象,這個過程也就是俗稱的“克隆”。被複制的實例就是所稱的“原型”。

原型模式:用原型實例指定創建對象的種類,並通過拷貝這些原型創建新的對象

使用場景

  • 類初始化需要消耗非常多的資源,包括數據、硬件資源等,通過原型拷貝避免這些消耗

  • 通過new產生一個對象需要非常繁瑣的數據準備或訪問權限。這時可以使用原型拷貝

  • 一個對象需要提供給其他對象調用者使用,而且各個調用者都需要修改其值,可以考慮通過原型模式拷貝多個對象供調用者使用,即保護性拷貝

原型模式的簡單實現

通過實現Cloneable接口:

首先創建一個文檔對象,即WordDocument,這個文檔中含有文字和圖片,編輯時在文檔副本上修改。

public class WordDocument implements Cloneable {

    private String mText;

    private ArrayList<String> mImages = new ArrayList<>();

    public WordDocument() {
        System.out.println("---------- WordDocument構造函數 -------------");
    }

    @Override
    protected WordDocument clone() {
        try {
            WordDocument doc = (WordDocument) super.clone();
            doc.mText = this.mText;
            doc.mImages = this.mImages; // 淺拷貝
            doc.mImages = (ArrayList<String>) mImages.clone(); // 深拷貝,引用類型
            return doc;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public String getmText() {
        return mText;
    }

    public void setmText(String mText) {
        this.mText = mText;
    }

    public List<String> getmImages() {
        return mImages;
    }

    public void addImage(String img) {
        this.mImages.add(img);
    }
}

淺拷貝: 也稱影子拷貝,副本並不是將原型所有字段都重新構造,而是引用。
深拷貝: 即拷貝對象時,對引用型的字段也要採用拷貝形式,並不是單純的引用

需要拷貝時調用clone()

        WordDocument originDoc = new WordDocument();
        originDoc.setmText("這是一篇文章");
        originDoc.addImage("圖片1");
        originDoc.addImage("圖片2");


        WordDocument doc = originDoc.clone();

Android中的原型模式

  • ArrayList:
public Object clone() {
        try {
            ArrayList<?> v = (ArrayList<?>) super.clone();
            v.elementData = Arrays.copyOf(elementData, size);
            v.modCount = 0;
            return v;
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError(e);
        }
    }
  • Intent:
    @Override
    public Object clone() {
        return new Intent(this);
    }
  • …………

總結

使用原型模式可以解決構建複雜對象的資源消耗問題,能夠在某些場景提升創建對象的效率。還有一個重要用途就是保護性拷貝,也就是某個對象對外可能是隻讀的,爲了防止外部對這個只讀對象修改,通常可以返回一個對象拷貝的形式實現只讀的限制。

注意淺拷貝、深拷貝的區別

優點: 原型模式是在內存中二進制流的拷貝,要比直接new一個對象性能好很多,特別是在一個循環體內產生大量的對象時,原型模型可以更好地體現其優點

缺點: 直接在內存中拷貝,構造函數是不會執行的,實際開發要考慮這個潛在問題

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章