不變模式/Immutable
意圖/適用場景:
“不變類”是這樣一個類,它的內部狀態創建後,在整個生命期間都不會發生變化。使用不變類的做法叫做不變模式。
不變類允許被多個對象共享,降低了對該對象進行併發訪問時的同步化開銷。如果需要修改一個不變對象的狀態,那麼就需要建立一個新的同類型 對象,並在創建時將這個新的狀態存儲在新的對象裏。
不變模式有兩種形式:弱不變模式,以及強不變模式。
弱不變模式:
弱不變類的特徵是,這個類的實例的狀態是不可變化的,但是它的子類的實例具有可變化的狀態。
弱不變類必須滿足下面條件:
- 此類的對象只在構造子中初始化,沒有任何方法會修改其狀態。
- 所有的屬性都是私有的,客戶端對象無法直接修改其狀態。
- 如果對象的狀態是其所引用的其它可變對象所決定的話,必須限制外界對這些可變對象的訪問。可變對象的狀態應該只由不變類來決定,並且外界不可改變。
弱不變類的缺點:
- 弱不變類的子類的對象可以是可變的,這削弱了弱不變類的作用。
- 可變的子類的對象可能可能修改父對象的狀態,有機會允許外界修改父對象的狀態,破壞了不變性。
強不變模式:
強不變類的特徵是,這個類的實例的狀態不會改變,而且它的子類的實例也具有不可變化的狀態。 強不變類必須首先滿足弱不變類的所有條件,同時還要再滿足以下條件:
- 類的所有方法都應當是final,子類不能置換掉父類的方法。
- 類本身就是final,這樣就不會有子類。
不變模式的應用非常常見,比如Java語言中的String類和封裝類java.lang.*。比如,String類所持有的字符串必須在構造String對象的時候指定,一旦String對象生成了,字符串內容就不能再改變。
UML:
無
相關模式:
享元模式:
享元模式與不變模式有很大的相似之處,都強調對象的內部狀態不受外在環境的支配。
不過享元模式並不要求對象的狀態在構造期間指定後就再也不能變化,享元對象的狀態其實是可變的。享元模式更強調的是共享,共享性與可變性並不矛盾。如果享元對象具有某個可變的狀態,但只要不會影響享元對象的共享,也是允許的。
不變模式的性質則更強,它也滿足共享性,此外它的狀態還保持不變。
示例代碼:
無