??有時(shí),你可能會(huì)嘗試編寫(xiě)簡(jiǎn)單類,除了組實(shí)例字段之外沒(méi)有任何目的:
??因?yàn)檫@些類的數(shù)據(jù)字段是可以直接訪問(wèn)的施敢,所以這些類沒(méi)有提供封裝的好處(item15) 。你不能在不更改API的情況下更改表示狭莱,你不能強(qiáng)制不變量僵娃,你不能在訪問(wèn)字段的時(shí)候執(zhí)行輔助操作。強(qiáng)硬的面向?qū)ο蟪绦騿T認(rèn)為這些類是詛咒腋妙,應(yīng)該總是具有private字段和public訪問(wèn)方法(getters)和可變類的方法(setter):
??當(dāng)然默怨,強(qiáng)硬派是正確的,當(dāng)類是public的時(shí)候:如果一個(gè)類在包歪是可訪問(wèn)的骤素,提供訪問(wèn)方法保持改變類內(nèi)在表示的靈活性先壕。如果一個(gè)public類暴露它的數(shù)據(jù)字段瘩扼,所有改變其表示的希望都會(huì)丟失,因?yàn)榭蛻舳舜a可以被遠(yuǎn)程分發(fā)垃僚。
??然而集绰,如果一個(gè)類是package-private或者是private嵌套類,那么暴露它的數(shù)據(jù)字段沒(méi)有任何內(nèi)部錯(cuò)誤-假設(shè)它們足以描述類提供的抽象谆棺。在類定義和在使用它的客戶端中栽燕,這種方法比訪問(wèn)方法產(chǎn)生更少視覺(jué)混亂。雖然客戶端代碼與類內(nèi)部表示相關(guān)聯(lián)改淑,但該代碼僅限于包含該類的包碍岔。如果需要改變表示,你可以在不改變包外的任何代碼來(lái)更改它朵夏。在私有嵌套類的情況下蔼啦,更改范圍更一舉限制為封閉類。
??在Java平臺(tái)庫(kù)中的一些類違反了public類應(yīng)該不直接暴露字段的建議仰猖。突出的例子包括java.awt包下的Point和Dimension類捏肢。這些類應(yīng)該被視為警示故事,而不是模仿的例子饥侵。正如item67所述鸵赫,暴露Dimension類的內(nèi)部覺(jué)得導(dǎo)致了嚴(yán)重的性能問(wèn)題,至今仍然存在躏升。
??雖然public類直接暴露字段永遠(yuǎn)不是一個(gè)好主意辩棒,但是如果字段是不可變的,它的危害更小膨疏。你無(wú)法在不改變API的前提下改變類的表示一睁,你不能當(dāng)類正在被讀時(shí)做輔助性操作,但是你可以強(qiáng)制執(zhí)行不變量佃却。例如卖局,這個(gè)類保證每個(gè)實(shí)例表示有效時(shí)間:
??總結(jié),public類應(yīng)該永不暴露可變字段双霍。public類暴露不可變字段的危害較小砚偶,雖然這仍然有問(wèn)題。然而洒闸,有時(shí)候package-private或private嵌套類需要暴露字段染坯,無(wú)論可變還是不可變。
本文寫(xiě)于2019.3.21丘逸,歷時(shí)1天