原型模式(Prototype Pattern)是創(chuàng)建模式的一種,其作用是提高創(chuàng)建效率,減少計算機資源開銷,與工廠模式類似的是,都屏蔽了對象實例化的過程…
概述
原型模式是23GOF模式的一種,其特點就是通過克隆/拷貝的方式來,節(jié)約創(chuàng)建成本和資源,被拷貝的對象模型就稱之為原型。
舉例:在寫PPT的時候,大多情況下模板風格都是一致的,只是其中部分描述內(nèi)容發(fā)生變化,這個時候你會選擇Ctrl+C/V還是新建一頁PPT一邊聽《從頭再來》一邊調(diào)整圖片和樣式?
JAVA中對原型模式提供了良好的支持,我們只需要實現(xiàn)Cloneable接口即可,它的目的就是將對象標記為可被復制
優(yōu)點
簡化對象創(chuàng)建過程,通過拷貝的方式構(gòu)建效率更高
可運行時指定動態(tài)創(chuàng)建的對象
缺點
需要實現(xiàn) Cloneable接口,clone位于內(nèi)部,不易擴展,容易違背開閉原則(程序擴展,不應該修改原有代碼)
默認的 clone 只是淺克隆,深度克隆需要額外編碼(比如:統(tǒng)一實現(xiàn)Cloneable接口,或者序列化方式,還有org.apache.commons:commons-lang3.SerializationUtils.java)
注意點
通過內(nèi)存拷貝的方式構(gòu)建出來的,會忽略構(gòu)造函數(shù)限制
需要注意深拷貝和淺拷貝,默認Cloneable 是淺拷貝,只拷貝當前對象而不會拷貝引用對象,除非自己實現(xiàn)深拷貝
與單例模式?jīng)_突,clone是直接通過內(nèi)存拷貝的方式,繞過構(gòu)造方法
常用克隆不可變對象,如果你克隆的對象10個字段改9個還不如實例化算了
clone只是一個語法,非強制方法命名
很少單獨出現(xiàn),常與工廠模式相伴
適用場景
常用在初始化步驟繁瑣,資源耗損嚴重的對象
案例
案例一:淺拷貝
分析:?從日志中可以發(fā)現(xiàn),我們無需通過new Object()的方式去實例化對象,而是調(diào)用Object.clone()同樣可以,Customer的hashCode也發(fā)生了改變,由此可以推斷出它們的引用已經(jīng)發(fā)生變化了,但是Address的hashCode一模一樣,前面說到過Cloneable是淺克隆的,并不會拷貝其它引用對象
案例二:淺拷貝
分析:?Customer本身的屬性值修改與原始對象并不沖突,它們都是各自一份,但集合類型修改后,克隆對象輸出的與原始對象如出一轍,不難發(fā)現(xiàn)Cloneable的淺克隆范圍只支持基本類型
案例三:深淺拷貝命名?
分析:?我們定義了兩個非clone的方法名,同樣可以做到克隆特性,此時從deep()中可以看到修改原始的Address并沒有影響到現(xiàn)有的克隆對象,這是因為內(nèi)部通過硬編碼的方式控制的,雖然引用的Address對象發(fā)生改變,但是List還是同一個引用,依舊做不到完全的深度克隆
案例四:序列化實現(xiàn)深度克隆
分析:?實現(xiàn)Serializable,通過序列化的方式與原始數(shù)據(jù)完全脫離關(guān)系,從而達到深度克隆效果,當然一般用SerializationUtils.clone(original)方式比我們自己寫的會更好
案例五:如何配合工廠模式使用?
總結(jié)
本章介紹了什么是原型模式以及使用它的優(yōu)缺點,其模式在開發(fā)過程中幾乎用不上(反正我沒用到過,歡迎探討),但這并不能說明它是無用,存在即合理,設(shè)計模式不僅用作與JAVA軟件編程,更多情況下模式的作用是在某種程度下避免復雜的設(shè)計。
