java設(shè)計模式-不變模式(Immutable)

定義

一個對象的狀態(tài)在對象被創(chuàng)建成功之后就不再變化,這就是所謂的不變模式。

不變模式的結(jié)構(gòu)

不變模式可增強對象的強壯性(robustness)。不變模式允許多個對象共享某一個對象,降低了對該對象進行并發(fā)訪問的同步化開銷。如果需要修改一個不變對象的狀態(tài),那么就需要建立一個新的同類型對象,并在創(chuàng)建時將這個新的狀態(tài)存儲在新對象里。

不變模式只涉及到一個類。一個類的內(nèi)部狀態(tài)創(chuàng)建后,在整個生命周期都不會發(fā)生變化時,這樣的類成為不變類。這種使用不變類的做法叫做不變模式。不變模式有兩種形式:一種是弱不變模式,另一種是強不變模式。

弱不變模式

一個類的實例的狀態(tài)時不可改變的;但是這個類的子類的實例具有可能會變化的狀態(tài),這樣的類符合弱不變的定義。要實現(xiàn)弱不變模式,一個類必須滿足下列條件:

  • 第一、所考慮的對象沒有任何方法會修改對象的狀態(tài);這樣一來,當對象的構(gòu)造函數(shù)將對象的狀態(tài)初始化之后,對象的狀態(tài)便不再改變。
  • 第二、所有屬性都應(yīng)當是私有的。不要聲明任何公開的屬性,以防客戶端對象直接修改任何的內(nèi)部狀態(tài)。
  • 第三、這個對象所引用到的其他對象如果是可變對象的話,必須設(shè)法限制外界對這些可變對象的訪問,以防止外界修改這些對象。如果可能,應(yīng)當盡量在不變對象內(nèi)部初始化這些被引用的對象,而不要在客戶端初始化,然后再傳入到不變對象內(nèi)部來。如果某個可變對象必須在客戶端初始化,然后再傳入不變對象里的話,就應(yīng)當考慮在不變對象初始化的時候,將這個可變對象復(fù)制一份,而不要使用原來的拷貝。

弱不變模式的缺點是:

  • 第一、一個弱不變對象的子對象可以是可變對象;換而言之,一個弱不變對象的子對象可能是可變的。
  • 第二、這個可變的子對象可能可以修改父對象的狀態(tài),從而可能會允許外界修改父對象的狀態(tài)。

強不變模式

一個類的實例不會改變,同時它的子類的實例也具有不可變化的狀態(tài)。這樣的類符合強不變模式。要實現(xiàn)強不變模式,一個類必須首先滿足弱不變模式所要求的任何條件,并且還要滿足下面條件之一:

  • 第一、所考慮的類的所有方法都應(yīng)當是final,這樣這個類的子類不能夠置換掉此類的方法。
  • 第二、這個類本身就是final的,那么這個類就不可能會有子類,從而也就不可能有被子類修改的問題。

“不變”和“只讀”的區(qū)別

“不變”(Immutable)與“只讀”(ReadOnly)是不同的。當一個變量是“只讀”時,變量的值不能直接改變,但是可以在其他變量發(fā)生改變時發(fā)生改變。

比如,一個人的出生年月日是“不變”屬性,而一個人的年齡便是“只讀”屬性,而不是“不變”屬性。隨著時間的變化,一個人的年齡會隨之發(fā)生變化,而人的出生年月日則不會變化。這就是“不變”和“只讀”的區(qū)別

不變模式在Java中的應(yīng)用

不變模式在Java中最著名的應(yīng)用便是Java.lang.String類。String類是一個強不變類型,在出現(xiàn)如下的語句時:

String a = "test";
String b = "test";
String c = "test";

Java虛擬機中其實只會創(chuàng)建這樣一個字符串的實例,而這三個String對象都在共享這一個值。

不變模式的優(yōu)點和缺點

不變模式有很明顯的優(yōu)點:

  1. 因為不能修改一個不變對象的狀態(tài),所以可以避免由此引起的不必要的程序錯誤;換而言之,一個不變的對象要比可變的對象更加容易維護。
  2. 因為沒有任何一個線程能夠修改不變對象的內(nèi)部狀態(tài),一個不變對象自動就是線程安全的,這樣就可以省掉處理同步化的開銷。一個不變對象可以自由的被不同的客戶端共享。

不變模式的唯一缺點是:

一旦需要修改一個不變對象的狀態(tài),就只好創(chuàng)建一個新的同類對象。在需要頻繁修改不變對象的環(huán)境里,會有大量的不變對象作為中間結(jié)果被創(chuàng)建出來,再被Java垃圾收集器收集走。這是一種資源上的浪費。

在設(shè)計任何一個類的時候,應(yīng)當慎重考慮其狀態(tài)是否有需要變化的可能性。除非其狀態(tài)有變化的需要,不然應(yīng)當將它設(shè)計成不變類。

參考

《JAVA與模式》之不變模式

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 國家電網(wǎng)公司企業(yè)標準(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 11,185評論 6 13
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,778評論 18 399
  • 設(shè)計模式匯總 一、基礎(chǔ)知識 1. 設(shè)計模式概述 定義:設(shè)計模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 3,984評論 1 15
  • 設(shè)計模式基本原則 開放-封閉原則(OCP),是說軟件實體(類、模塊、函數(shù)等等)應(yīng)該可以拓展,但是不可修改。開-閉原...
    西山薄涼閱讀 3,891評論 3 14
  • 邯鄲的一切都讓我感到新奇,這是一座真實的城市。大街小巷琳瑯滿目的各色拉面、煎餅晝夜不停地蒸騰著美味的氣息,無形...
    往亦云閱讀 250評論 0 0