原型模式(Prototype Pattern)

一、簡述

原型模式屬于對象的創(chuàng)建模式,通過給出一個(gè)原型對象來指明所有創(chuàng)建的對象的類型,然后用復(fù)制這個(gè)原型對象的辦法創(chuàng)建出更多同類型的對象,這就是原型模式的用意。

二、原型模式結(jié)構(gòu)

原型模式要求對象實(shí)現(xiàn)一個(gè)可以克隆自身的接口,這樣就可以通過復(fù)制一個(gè)實(shí)例對象本身來創(chuàng)建一個(gè)新的實(shí)例。通過原型實(shí)例創(chuàng)建新的對象,就不再需要關(guān)心這個(gè)實(shí)例本身的類型,只要實(shí)現(xiàn)了克隆自身的方法,就可以通過這個(gè)方法來獲取新的對象,而無須再通過 new 去創(chuàng)建。原型模式涉及到三個(gè)角色:

1??客戶角色(Client)

客戶類提出創(chuàng)建對象的請求。

2??抽象原型角色(Prototype)

這是一個(gè)抽象角色,通常由一個(gè)接口或者抽象類實(shí)現(xiàn),此角色給出所有具體原型類所需的實(shí)現(xiàn)的接口。

3??具體原型角色(Concrete Prototype)

被復(fù)制的角色,此角色需要實(shí)現(xiàn)抽象的原型角色所要求的克隆相關(guān)的接口。

三、原型模式示例

1??定義一個(gè)抽象原型角色,抽象類,實(shí)現(xiàn) Cloneable 接口:

public abstract class Prototype implements Cloneable {
    public Prototype clone() {
        Prototype prototype = null;
        try {
            prototype = (Prototype) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return prototype;
    }
    public abstract void show();
}

2??定義一個(gè)具體原型角色,繼承 Prototype 類:

public class ConcretePrototype extends Prototype {
    @Override
    public void show() {
        System.out.println("ConcretePrototype.show()");
    }
}

3??定義一個(gè)客戶端調(diào)用:

public static void main(String[] args) {
    ConcretePrototype cp = new ConcretePrototype();
    for (int i = 0; i < 5; i++) {
        ConcretePrototype cpClone = (ConcretePrototype) cp.clone();
        cpClone.show();
    }
}

比方說一個(gè)類實(shí)例很有用的時(shí)候,就可以使用原型模式去復(fù)制它。不過原型模式單獨(dú)用得不多,一般是和其他設(shè)計(jì)模式一起使用。

四、原型模式的應(yīng)用及解讀

既然原型模式的關(guān)注點(diǎn)是在于通過克隆自身來獲取一個(gè)和自身一樣的對象,那其實(shí)只要是實(shí)現(xiàn)了 Cloneable 接口的類都可以算是原型模式的應(yīng)用,比如 ArrayList :

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
    ...
    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);
        }
    }
    ...
}

程序中獲取到了一個(gè) ArrayList 的實(shí)例 arrayList,完全可以通過調(diào)用 arrayList.clone() 獲取到原 ArrayList 的拷貝。

五、原型模式的優(yōu)點(diǎn)

原型模式是一種類的創(chuàng)建模式,可以看到到目前為止的四種創(chuàng)建型模式,客戶端(調(diào)用方)都沒有直接 new 一個(gè)類實(shí)例出來。把 new 一個(gè)類實(shí)例的動(dòng)作由客戶端(調(diào)用方)交給別人做而不是自己做,這就是創(chuàng)建型模式的宗旨。

使用原型模式創(chuàng)建對象比直接 new 一個(gè)對象在性能上好得多,因?yàn)?Object 類的 clone() 是一個(gè) native 方法,它直接操作內(nèi)存中的二進(jìn)制流,特別是復(fù)制大對象時(shí),性能的差別非常明顯。

使用原型模式的另一個(gè)好處是簡化對象的創(chuàng)建,使得創(chuàng)建對象就像普通的復(fù)制粘貼一樣簡單。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容