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

定義

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

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

不變模式可增強(qiáng)對(duì)象的強(qiáng)壯性(robustness)。不變模式允許多個(gè)對(duì)象共享某一個(gè)對(duì)象,降低了對(duì)該對(duì)象進(jìn)行并發(fā)訪問的同步化開銷兔港。如果需要修改一個(gè)不變對(duì)象的狀態(tài),那么就需要建立一個(gè)新的同類型對(duì)象仔拟,并在創(chuàng)建時(shí)將這個(gè)新的狀態(tài)存儲(chǔ)在新對(duì)象里衫樊。

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

弱不變模式

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

  • 第一盟蚣、所考慮的對(duì)象沒有任何方法會(huì)修改對(duì)象的狀態(tài);這樣一來卖怜,當(dāng)對(duì)象的構(gòu)造函數(shù)將對(duì)象的狀態(tài)初始化之后屎开,對(duì)象的狀態(tài)便不再改變。
  • 第二马靠、所有屬性都應(yīng)當(dāng)是私有的奄抽。不要聲明任何公開的屬性,以防客戶端對(duì)象直接修改任何的內(nèi)部狀態(tài)甩鳄。
  • 第三逞度、這個(gè)對(duì)象所引用到的其他對(duì)象如果是可變對(duì)象的話,必須設(shè)法限制外界對(duì)這些可變對(duì)象的訪問娩贷,以防止外界修改這些對(duì)象第晰。如果可能,應(yīng)當(dāng)盡量在不變對(duì)象內(nèi)部初始化這些被引用的對(duì)象彬祖,而不要在客戶端初始化茁瘦,然后再傳入到不變對(duì)象內(nèi)部來。如果某個(gè)可變對(duì)象必須在客戶端初始化储笑,然后再傳入不變對(duì)象里的話甜熔,就應(yīng)當(dāng)考慮在不變對(duì)象初始化的時(shí)候,將這個(gè)可變對(duì)象復(fù)制一份突倍,而不要使用原來的拷貝腔稀。

弱不變模式的缺點(diǎn)是:

  • 第一、一個(gè)弱不變對(duì)象的子對(duì)象可以是可變對(duì)象羽历;換而言之焊虏,一個(gè)弱不變對(duì)象的子對(duì)象可能是可變的。
  • 第二秕磷、這個(gè)可變的子對(duì)象可能可以修改父對(duì)象的狀態(tài)诵闭,從而可能會(huì)允許外界修改父對(duì)象的狀態(tài)。

強(qiáng)不變模式

一個(gè)類的實(shí)例不會(huì)改變澎嚣,同時(shí)它的子類的實(shí)例也具有不可變化的狀態(tài)疏尿。這樣的類符合強(qiáng)不變模式。要實(shí)現(xiàn)強(qiáng)不變模式易桃,一個(gè)類必須首先滿足弱不變模式所要求的任何條件褥琐,并且還要滿足下面條件之一:

  • 第一、所考慮的類的所有方法都應(yīng)當(dāng)是final晤郑,這樣這個(gè)類的子類不能夠置換掉此類的方法敌呈。
  • 第二、這個(gè)類本身就是final的造寝,那么這個(gè)類就不可能會(huì)有子類磕洪,從而也就不可能有被子類修改的問題。

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

“不變”(Immutable)與“只讀”(ReadOnly)是不同的匹舞。當(dāng)一個(gè)變量是“只讀”時(shí)褐鸥,變量的值不能直接改變,但是可以在其他變量發(fā)生改變時(shí)發(fā)生改變赐稽。

比如叫榕,一個(gè)人的出生年月日是“不變”屬性,而一個(gè)人的年齡便是“只讀”屬性姊舵,而不是“不變”屬性晰绎。隨著時(shí)間的變化,一個(gè)人的年齡會(huì)隨之發(fā)生變化括丁,而人的出生年月日則不會(huì)變化荞下。這就是“不變”和“只讀”的區(qū)別

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

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

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

Java虛擬機(jī)中其實(shí)只會(huì)創(chuàng)建這樣一個(gè)字符串的實(shí)例尖昏,而這三個(gè)String對(duì)象都在共享這一個(gè)值仰税。

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

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

  1. 因?yàn)椴荒苄薷囊粋€(gè)不變對(duì)象的狀態(tài),所以可以避免由此引起的不必要的程序錯(cuò)誤抽诉;換而言之陨簇,一個(gè)不變的對(duì)象要比可變的對(duì)象更加容易維護(hù)。
  2. 因?yàn)闆]有任何一個(gè)線程能夠修改不變對(duì)象的內(nèi)部狀態(tài)迹淌,一個(gè)不變對(duì)象自動(dòng)就是線程安全的河绽,這樣就可以省掉處理同步化的開銷。一個(gè)不變對(duì)象可以自由的被不同的客戶端共享唉窃。

不變模式的唯一缺點(diǎn)是:

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

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

參考

《JAVA與模式》之不變模式

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市昨寞,隨后出現(xiàn)的幾起案子瞻惋,更是在濱河造成了極大的恐慌,老刑警劉巖援岩,帶你破解...
    沈念sama閱讀 221,888評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件歼狼,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡享怀,警方通過查閱死者的電腦和手機(jī)羽峰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來添瓷,“玉大人梅屉,你說我怎么就攤上這事×鄞” “怎么了坯汤?”我有些...
    開封第一講書人閱讀 168,386評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)搀愧。 經(jīng)常有香客問我惰聂,道長(zhǎng)疆偿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,726評(píng)論 1 297
  • 正文 為了忘掉前任搓幌,我火速辦了婚禮杆故,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘鼻种。我一直安慰自己反番,他們只是感情好沙热,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評(píng)論 6 397
  • 文/花漫 我一把揭開白布叉钥。 她就那樣靜靜地躺著,像睡著了一般篙贸。 火紅的嫁衣襯著肌膚如雪投队。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,337評(píng)論 1 310
  • 那天爵川,我揣著相機(jī)與錄音敷鸦,去河邊找鬼。 笑死寝贡,一個(gè)胖子當(dāng)著我的面吹牛扒披,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播圃泡,決...
    沈念sama閱讀 40,902評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼碟案,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了颇蜡?” 一聲冷哼從身側(cè)響起价说,我...
    開封第一講書人閱讀 39,807評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎风秤,沒想到半個(gè)月后鳖目,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,349評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡缤弦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評(píng)論 3 340
  • 正文 我和宋清朗相戀三年领迈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碍沐。...
    茶點(diǎn)故事閱讀 40,567評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡狸捅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出抢韭,到底是詐尸還是另有隱情薪贫,我是刑警寧澤,帶...
    沈念sama閱讀 36,242評(píng)論 5 350
  • 正文 年R本政府宣布刻恭,位于F島的核電站瞧省,受9級(jí)特大地震影響扯夭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鞍匾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評(píng)論 3 334
  • 文/蒙蒙 一交洗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧橡淑,春花似錦构拳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至符糊,卻和暖如春凫海,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背男娄。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工行贪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人模闲。 一個(gè)月前我還...
    沈念sama閱讀 48,995評(píng)論 3 377
  • 正文 我出身青樓建瘫,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親尸折。 傳聞我的和親對(duì)象是個(gè)殘疾皇子啰脚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評(píng)論 2 359

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

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