JAVA的訪問控制3-封裝和可訪問范圍

JAVA的訪問控制3-封裝和可訪問范圍

在前文JAVA的訪問控制1-訪問控制的必要性,包JAVA的訪問控制2-public,protected,private和package-private中我們介紹了訪問控制的由來,基本概念以及具體內容,這一篇會繼續(xù)深入一些,講解一下這幾篇文章最開始提到的封裝可訪問范圍的一些內容。

封裝

JAVA語言通過訪問控制符,給我們提供了一種能力,我們可以控制客戶程序員的訪問范圍,或者說,客戶程序員可以只知道這個類可以完成什么,而不需要去關注其實現(xiàn)細節(jié)。這樣的話,類的創(chuàng)建者就可以將內部的機制隱藏起來,并且,在需要修改的時候,可以放心的修改內部機制,不用擔心破壞客戶程序員的使用。
封裝就是這種能力,有時候這個能力也叫信息隱藏.
封裝不只是JAVA語言中可用的一種概念,它是軟件設計的一個基本原則之一。封裝在軟件設計的很多層次都有體現(xiàn)。
在最小的類層次,封裝體現(xiàn)為類對外提供一些方法,內部存在自己的實現(xiàn)。
在更大的模塊層次,封裝體現(xiàn)為整個模塊對外提供了哪些能力,外部只能使用這些能力,而不必深入了解模塊內部的機制,比如用戶模塊可能通過一些方法對外提供給了人員的管理能力,其他模塊只需要使用這些方法即可,而不必自行去操作用戶模塊的數(shù)據(jù)庫等內部內容。
在服務層次,體現(xiàn)為整個服務對外提供了哪些能力,一般是通過接口的方式提供,而內部實現(xiàn)(比如數(shù)據(jù)庫)等內容,則不會對外提供。
可以看到,每一層的內容不一樣,但是思想是完全一致的,就是把內部很小心的隱藏起來,只對外提供必要的方法,而不是把整個系統(tǒng)全部敞開。
舉個反例,如果如果我們要使用某個類,需要提前設置這個類的某個內部變量,然后再用某些方法,那這個就是沒有封裝的,如果其作者想要修改前面的那個內部變量,勢必會影響客戶端,導致更大范圍的修改,這樣的系統(tǒng)就會盤根錯節(jié),牽一發(fā)而動全身,最終難以維護。
這種就是緊密耦合,會導致軟件很難以維護,通過封裝可以有效緩解這個問題,做到解耦。
除此以外,封裝還可以提高復用性,如果這個類很易于使用,并且提供的功能又很明確,那么其它遇到這一需求的就可以直接使用。如果類封裝的不好,使用起來困難重重,很可能會導致其他人不愿意使用,還不如自己寫一個新的,復用性也就很差了。

封裝與可訪問范圍

上面介紹了封裝和封裝可以帶來的好處,為了更好的封裝,我們需要控制可訪問范圍。關于控制可訪問范圍,只有一個原則,那就是,保持可訪問范圍最小。我們要盡可能的做到,每個內部的變量和方法,都不能被外部訪問,對外開放的,也就是設置為public的,僅應是那些必須對外提供的能力。
如果一個方法被設置成public了,那就意味著我們對外做出了一個承諾,public方法的名稱,入參,返回值等,一旦發(fā)布就難以修改了,后續(xù)還需要持續(xù)維護它的兼容性,務必謹慎。
類的實例變量,不應該設置為public的,如果需要對外提供,那么可以提供getXXXgetter方法。
另外,如果類的實例變量是可變對象,比如數(shù)組,列表,或者是Date這種可變的類,在提供getter方法的時候,要注意保護自己。
內部的變量提供給外部,很可能會被外部篡改,最好是變量本身設置為不可變,或者是克隆一個克隆體給外部,這樣外部的類就無法修改類的內部變涼了。出門在外,要當心。
下面舉一個例子說明這種情況:

public class XxxService {
    private static final String[] FIELDS = {"field1", "field2"};
    public String[] getFields() {
        return FIELDS;
    }
}

這里是一個類,它的內部有一個FIELDS常量,按照定義private static final String[],原意應該是一個不可變的數(shù)組,但是使用方沒有注意到,而是對它進行了修改:

// 非法使用者:
XxxService xxxService = new XxxService();
String[] fields = xxxService.getFields();
fields[0] = "myField";
// ...

這之后XxxService所有依賴FIELDS的方法都會被破壞,問題還隱藏的很深,并不在XxxService中,難以排查。
很多安全問題也是這樣子來的,請務必小心。
要規(guī)避也比較簡單,返回這個數(shù)組的副本就可以了:return Arrays.copyOf(FIELDS, FIELDS.length),這樣子使用方即使修改了返回的數(shù)組,也就不會對XxxService的功能有影響了。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容