《JAVA與模式》第15天—不變模式 – JAVA編程語言程序開發技術文章

 一個對象的狀態在對象被創建之後就不再變化,這就是所謂的不變模式。

——————————————————————————–

不變模式的結構
  不變模式可增強對象的強壯型(robustness)。不變模式允許多個對象共享某一個對象,降低瞭對該對象進行並發訪問時的同步化開銷。如果需要修改一個不變對象的狀態,那麼就需要建立一個新的同類型對象,並在創建時將這個新的狀態存儲在新對象裡。

  不變模式隻涉及到一個類。一個類的內部狀態創建後,在整個生命周期都不會發生變化時,這樣的類稱作不變類。這種使用不變類的做法叫做不變模式。不變模式有兩種形式:一種是弱不變模式,另一種是強不變模式。

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

  第一、所考慮的對象沒有任何方法會修改對象的狀態;這樣一來,當對象的構造函數將對象的狀態初始化之後,對象的狀態便不再改變。

  第二、所有屬性都應當是私有的。不要聲明任何的公開的屬性,以防客戶端對象直接修改任何的內部狀態。

  第三、這個對象所引用到的其他對象如何是可變對象的話,必須設法限制外界對這些可變對象的訪問,以防止外界修改這些對象。如何可能,應當盡量在不變對象內部初始化這些被引用的對象,而不要在客戶端初始化,然後再傳入到不變對象內部來。如果某個可變對象必須在客戶端初始化,然後再傳入到不變對象裡的話,就應當考慮在不變對象初始化的時候,將這個可變對象復制一份,而不要使用原來的拷貝。

  弱不變模式的缺點是:

  第一、一個弱不變對象的子對象可以是可變對象;換言之,一個弱不變對象的子對象可能是可變的。

  第二、這個可變的子對象可能可以修改父對象的狀態,從而可能會允許外界修改父對象的狀態。

 

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

  第一、所考慮的類所有的方法都應當是final,這樣這個類的子類不能夠置換掉此類的方法。

  第二、這個類本身就是final的,那麼這個類就不可能會有子類,從而也就不可能有被子類修改的問題。

 

 “不變"和"隻讀"的區別
  "不變"(Immutable)與"隻讀"(Read Only)是不同的。當一個變量是”隻讀“時,變量的值不能直接改變,但是可以在其他變量發生改變的時候發生改變。

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

 

 

不變模式在JAVA中的應用
  不變模式在JAVA中最著名的應用便是java.lang.String類。String類是一個強不變類型,在出現如下的語句時:

[java] 
String a = "test"; 
String b = "test"; 
String c = "test"; 
        String a = "test";
        String b = "test";
        String c = "test";
 

 

  JAVA虛擬機其實隻會創建這樣一個字符串的實例,而這三個String對象都在共享這一個值。

 

不變模式的優點和缺點
  不變模式有很明顯的優點:

  (1)因為不能修改一個不變對象的狀態,所以可以避免由此引起的不必要的程序錯誤;換言之,一個不變的對象要比可變的對象更加容易維護。

  (2)因為沒有任何一個線程能夠修改不變對象的內部狀態,一個不變對象自動就是線程安全的,這樣就可以省掉處理同步化的開銷。一個不變對象可以自由地被不同的客戶端共享。

  不變模式的缺點:

  不變模式唯一的缺點是:一旦需要修改一個不變對象的狀態,就隻好創建一個新的同類對象。在需要頻繁修改不變對象的環境裡,會有大量的不變對象作為中間結果被創建出來,再被JAVA垃圾收集器收集走。這是一種資源上的浪費。

  在設計任何一個類的時候,應當慎重考慮其狀態是否有需要變化的可能性。除非其狀態有變化的必要,不然應當將它設計成不變類。

 作者:m13666368773
 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。