如果使用字段名稱,則不會得到封裝。封裝不僅適用於類之間,而且適用於類。
如果在將來的某個點重新定義字段,但保留accessor/setter函數的簽名相同,不僅外部類使用您的類不會中斷,而且您自己的類中的內部例程也不會中斷。
就拿這段代碼中,鬆散的基礎上的代碼,在Apache Wicket框架顯示出來(雖然框架不會受到這個問題,我只是用它說明):
比方說,這是原班:
class RadioChoice {
private String prefix;
RadioChoice(String prefix) {
this.prefix = prefix ;
setPrefix(String prefix) {
this.prefix = prefix ;
}
}
在這裏,我們已經可以看到一個問題:同樣的操作this.prefix = prefix
在拖地發生。它意味着要做同樣的事情,但是因爲它發生在兩個地方,所以「同一個事物」可以分成兩個不同的事物。 (將此與數據庫規範化相比較,這是一種專門用於防止這種情況的實踐。)
現在,Apache Wicket具有記錄如何呈現網頁的更改的概念,以便可以撤消這些更改。它通過存儲一個「撤消」對象列表來完成。一個RadioChoice的前綴是可以撤銷的事情之一,所以「前綴」二傳手必須記錄的變化:
class RadioChoice {
private String prefix;
RadioChoice(String prefix) {
this.prefix = prefix ;
setPrefix(String prefix) {
// save the old prefix
this.getPage().addChange(new PrefixChange(this.prefix));
// set the new one
this.prefix = prefix ;
}
}
現在看看會發生什麼:因爲構造前綴直接設置,沒有變化被保存ctor。如果我們使用了setter,那麼ctor會在重構後自動「做正確的事情」。相反,我們必須重構設置器和 ctor。
當然,我們的代碼仍然不是最佳少,在現實中,它應該是這樣的:
setPrefix(String prefix) {
// save the old prefix
this.getPage().addChange(new PrefixChange(this.getPrefix()));
// set the new one
this.prefix = prefix ;
}
}
斯科特邁爾斯有一系列關於此文章,他主張(在C++中,其具有自由函數)一類暴露僅原始函數(原始功能:函數不可能除了由類iteslf),並且所有可能被由出的基本功能的功能得以自由功能。這使得界面更精簡,界面更穩定。
在這同樣,到可以處理的類作爲只取決於它的原始接口之前,有更多的靈活性功能的程度;特別是,這些職能可能會被移出課堂。更一般地說,使用setter和getter將你從變化中隔離出來。
是的,它是C#的一大好處。 – Randolpho 2009-04-09 15:41:37
對於我們這些不知道這些javabeaner事情的人來說,什麼是雅談話? – 2009-04-09 15:43:43