wordpress自適應(yīng)模版seow
文章目錄
- 設(shè)計(jì)模式概述
- 1、原型模式
- 2、原型模式的使用場(chǎng)景
- 3、優(yōu)點(diǎn)
- 4、缺點(diǎn)
- 5、主要角色
- 6、代碼示例
- 7、總結(jié)
- 題外話關(guān)于使用序列化實(shí)現(xiàn)深拷貝
設(shè)計(jì)模式概述
創(chuàng)建型模式:工廠方法、抽象方法、建造者、原型、單例。
結(jié)構(gòu)型模式有:適配器、橋接、組合、裝飾器、外觀、享元、代理。
行為型模式有:責(zé)任鏈、命令、解釋器、迭代器、中介、備忘錄、觀察者、狀態(tài)、策略、模板方法、訪問者。
常用設(shè)計(jì)模式:
單例模式、工廠模式、代理模式、策略模式&模板模式、門面模式、責(zé)任鏈模式、裝飾器模式、組合模式、builder模式。
1、原型模式
- 原型模式(Prototype Pattern)是用于創(chuàng)建重復(fù)的對(duì)象,同時(shí)又能保證性能。這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式之一。
- 這種模式是實(shí)現(xiàn)了一個(gè)原型接口,該接口用于創(chuàng)建當(dāng)前對(duì)象的克隆。當(dāng)直接創(chuàng)建對(duì)象的代價(jià)比較大時(shí),則采用這種模式。
2、原型模式的使用場(chǎng)景
- 在需要一個(gè)類的大量對(duì)象的時(shí)候,使用原型模式是最佳選擇,因?yàn)樵湍J绞窃趦?nèi)存中對(duì)這個(gè)對(duì)象進(jìn)行拷貝,要比直接new這個(gè)對(duì)象性能要好很多,在這種情況下,需要的對(duì)象越多,原型模式體現(xiàn)出的優(yōu)點(diǎn)越明顯。
- 如果一個(gè)對(duì)象的初始化需要很多其他對(duì)象的數(shù)據(jù)準(zhǔn)備或其他資源的繁瑣計(jì)算,那么可以使用原型模式。
- 當(dāng)需要一個(gè)對(duì)象的大量公共信息,少量字段進(jìn)行個(gè)性化設(shè)置的時(shí)候,也可以使用原型模式拷貝出現(xiàn)有對(duì)象的副本進(jìn)行加工處理。
3、優(yōu)點(diǎn)
- 原型模式允許在運(yùn)行時(shí)動(dòng)態(tài)改變具體的實(shí)現(xiàn)類型。原型模式可以在運(yùn)行期間,由客戶來注冊(cè)符合原型接口的實(shí)現(xiàn)類型,也可以動(dòng)態(tài)地改變具體的實(shí)現(xiàn)類型,看起來接口沒有任何變化,但其實(shí)運(yùn)行的已經(jīng)是另外一個(gè)類實(shí)例了。因?yàn)榭寺∫粋€(gè)原型就類似于實(shí)例化一個(gè)類。
4、缺點(diǎn)
- 原型模式最主要的缺點(diǎn)是每一個(gè)類都必須配備一個(gè)克隆方法。配備克隆方法需要對(duì)類的功能進(jìn)行通盤考慮,這對(duì)于全新的類來說不是很難,而對(duì)于已經(jīng)有的類不一定很容易,特別是當(dāng)一個(gè)類引用不支持序列化的間接對(duì)象,或者引用含有循環(huán)結(jié)構(gòu)的時(shí)候。
5、主要角色
(1)客戶(Client)角色:客戶類提出創(chuàng)建對(duì)象的請(qǐng)求。
(2)抽象原型(Prototype)角色:這是一個(gè)抽象角色,通常由一個(gè)Java接口或Java抽象類實(shí)現(xiàn)。此角色給出所有的具體原型類所需的接口。
(3)具體原型(Concrete Prototype)角色:被復(fù)制的對(duì)象。此角色需要實(shí)現(xiàn)抽象的原型角色所要求的接口。
6、代碼示例
1)UML圖
2)源代碼
(1)抽象原型角色
public interface Prototype{/*** 克隆自身的方法* @return 一個(gè)從自身克隆出來的對(duì)象*/public Object clone();
}
(2)具體原型角色
public class ConcretePrototype1 implements Prototype {public Prototype clone(){//最簡(jiǎn)單的克隆,新建一個(gè)自身對(duì)象,由于沒有屬性就不再復(fù)制值了Prototype prototype = new ConcretePrototype1();return prototype;}
}public class ConcretePrototype2 implements Prototype {public Prototype clone(){//最簡(jiǎn)單的克隆,新建一個(gè)自身對(duì)象,由于沒有屬性就不再復(fù)制值了Prototype prototype = new ConcretePrototype2();return prototype;}
}
(3)客戶端角色
public class Client {public static void main(String[]args){try{Prototype p1 = new ConcretePrototype1();//獲取原型來創(chuàng)建對(duì)象Prototype p2 = p1.clone();//有人動(dòng)態(tài)的切換了實(shí)現(xiàn)Prototype p3 = new ConcretePrototype2();Prototype p4 = p3.clone();}catch(Exception e){e.printStackTrace();}}
}
}
7、總結(jié)
- 這種情況就是淺拷貝,java只拷貝你指定的對(duì)象,至于你指定的對(duì)象里面的別的對(duì)象,它不拷貝,還是把引用給你,共享變量,這是一種非常不安全的方式,需要特別注意。
- 內(nèi)部的數(shù)組和引用對(duì)象不會(huì)拷貝,其他的原始基本類型和String類型會(huì)被拷貝。
- 如果需要可以使用深拷貝,結(jié)合具體對(duì)象的情況進(jìn)行處理(可以自己實(shí)現(xiàn)深拷貝邏輯;或者利用序列化和反序列化實(shí)現(xiàn)深拷貝,前提是所有需要復(fù)制的對(duì)象都需要實(shí)現(xiàn)java.io.Serializable接口。)
題外話關(guān)于使用序列化實(shí)現(xiàn)深拷貝
利用序列化實(shí)現(xiàn)深度克隆:
- 把對(duì)象寫到流里的過程是序列化(Serialization)過程;而把對(duì)象從流中讀出來的過程則叫反序列化(Deserialization)過程。應(yīng)當(dāng)指出的是,寫到流里的是對(duì)象的一個(gè)拷貝,而原對(duì)象仍然存在于JVM里面。
- 在Java語言里深度克隆一個(gè)對(duì)象,常??梢韵仁箤?duì)象實(shí)現(xiàn)Serializable接口,然后把對(duì)象(實(shí)際上只是對(duì)象的拷貝)寫到一個(gè)流里(序列化),再從流里讀回來(反序列化),便可以重建對(duì)象。
public Object deepClone() throws IOException, ClassNotFoundException{//將對(duì)象寫到流里ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos);oos.writeObject(this);//從流里讀回來ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bis);return ois.readObject();}
-
這樣做的前提就是對(duì)象以及對(duì)象內(nèi)部所有引用到的對(duì)象都是可序列化的,否則,就需要仔細(xì)考察那些不可序列化的對(duì)象可否設(shè)成transient,從而將之排除在復(fù)制過程之外。
-
淺度克隆顯然比深度克隆更容易實(shí)現(xiàn),因?yàn)镴ava語言的所有類都會(huì)繼承一個(gè)clone()方法,而這個(gè)clone()方法所做的正式淺度克隆。