官术网_书友最值得收藏!

3.2 Immutable Object模式的架構(gòu)

Immutable Object模式將現(xiàn)實(shí)世界中狀態(tài)可變的實(shí)體建模為狀態(tài)不可變的對象,并通過創(chuàng)建不同的狀態(tài)不可變的對象來反映實(shí)現(xiàn)世界實(shí)體的狀態(tài)變更。

Immutable Object模式的主要參與者有以下幾種,其類圖如圖3-1所示。

圖3-1 Immutable Object模式的類圖

? ImmutableObject:負(fù)責(zé)存儲一組不可變狀態(tài)。該參與者不對外暴露任何可以修改其狀態(tài)的方法,其主要方法及職責(zé)如下。

? getStateX、getStateN:這些getter方法返回其所屬ImmutableObject實(shí)例維護(hù)的狀態(tài)相關(guān)變量的值。這些變量在對象實(shí)例化時通過其構(gòu)造器的參數(shù)獲得值。

? getStateSnapshot:返回其所屬ImmutableObject實(shí)例維護(hù)的一組狀態(tài)的快照。

? Manipulator:負(fù)責(zé)維護(hù)ImmutableObject所建模的現(xiàn)實(shí)世界實(shí)體狀態(tài)的變更。當(dāng)相應(yīng)的現(xiàn)實(shí)世界實(shí)體狀態(tài)變更時,該參與者負(fù)責(zé)生成新的ImmutableObject實(shí)例,以反映新的狀態(tài)。

? changeStateTo:根據(jù)新的狀態(tài)值生成新的ImmutableObject實(shí)例。

狀態(tài)不可變對象的使用情況主要包括以下幾種類型。

? 獲取單個狀態(tài)的值:調(diào)用不可變對象的相關(guān)getter方法即可實(shí)現(xiàn)。

? 獲取一組狀態(tài)的快照:狀態(tài)不可變對象可以提供一個getter方法,該方法需要對其返回值做防御性復(fù)制(Defensive Copy)或者返回一個只讀對象,以避免因其狀態(tài)對外泄露而被改變。

? 生成新的狀態(tài)不可變對象實(shí)例:當(dāng)被建模對象的狀態(tài)發(fā)生變化的時候,創(chuàng)建新的狀態(tài)不可變對象實(shí)例來反映這種變化。

Immutable Object模式的典型交互場景的序列圖如圖3-2所示。

圖3-2 Immutable Object模式的典型交互場景的序列圖

第1~4步:客戶端代碼獲取當(dāng)前ImmutableObject實(shí)例的各個狀態(tài)值。

第5步:客戶端代碼調(diào)用Manipulator的changeStateTo方法來更新應(yīng)用的狀態(tài)。

第6、7步:changeStateTo方法創(chuàng)建新的ImmutableObject實(shí)例,以反映應(yīng)用的新狀態(tài),并返回。

第8、9步:客戶端代碼獲取新的ImmutableObject實(shí)例的狀態(tài)快照。

一個嚴(yán)格意義上的狀態(tài)不可變對象需要滿足以下所有條件。

1. 類本身使用final修飾:防止其子類改變其定義的行為。

2. 所有字段都是用final修飾的:使用final修飾不僅僅是從語義上說明被修飾字段的引用不可改變,更重要的是這個語義在多線程環(huán)境下由JMM(Java Memory Model)保證了被修飾字段所引用對象的初始化安全,即final修飾的字段在其他線程可見時,它必定已完成初始化。相反,非final修飾的字段由于缺少這種保證,可能導(dǎo)致在一個線程“看到”一個字段的時候,它還未完成初始化,從而可能導(dǎo)致一些不可預(yù)料的結(jié)果。

3. 在創(chuàng)建對象的過程中沒有泄露this關(guān)鍵字給其他類:防止其他類(如該類的內(nèi)部匿名類)在對象創(chuàng)建過程中修改其狀態(tài)。

4. 若任何字段引用了其他狀態(tài)可變的對象(如集合、數(shù)組等),則這些字段必須是由private關(guān)鍵字修飾的,并且這些字段的值不能對外暴露。若有相關(guān)方法要返回這些字段的值,應(yīng)該進(jìn)行防御性復(fù)制。

主站蜘蛛池模板: 汶上县| 铅山县| 菏泽市| 汪清县| 雷波县| 西青区| 比如县| 钦州市| 松滋市| 白沙| 九江市| 公主岭市| 惠安县| 海晏县| 永德县| 翁牛特旗| 榆树市| 延安市| 宣城市| 临朐县| 深泽县| 渭源县| 师宗县| 鄂托克前旗| 巴马| 花垣县| 永宁县| 鲁山县| 栖霞市| 衡东县| 获嘉县| 永善县| 夏邑县| 亚东县| 拉孜县| 桃园县| 富民县| 茌平县| 东光县| 如东县| 天峻县|