我的答案不會是最豐富的,但它會來自處理這種模式的直接經驗。在設計一個對象時,通常很容易直接訪問成員字段,而不是依賴訪問器。這種慾望源於想要簡化對象並避免在簡單返回值的方法中添加混亂。以你的例子更進了一步添加上下文&含義:
public class MyClassmate {
private Integer age;
public MyClassmate(Integer age) {
this.age = age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getAge() {
return age;
}
}
這裏的年齡是一個簡單的數字,它似乎不需要添加周圍getter/setter方法。如果再加上下面的方法,你會受到誘惑,直接訪問領域,因爲在任何變化:
public Integer calculateScore() {
if(age > 21) return 100 - getNumberOfIncorrectAnswers();
//Add 10% before for younger students
else return (100 - getNumberOfIncorrectAnswers()) + 10;
}
你的對象,然後可以一起成長依賴於年齡字段方法的新功能,你繼續使用直。稍後,您可能會改變年齡的起源方式,並從網絡中提取價值。您可能不希望將網絡邏輯結合到構造函數中,因爲這是一種昂貴的操作,應該只在需要時觸發。該calculateScore()
方法可以使網絡連接和發現的年齡,但隨後也將全部依賴於年齡的其他方法。但是,如果calculateScore長什麼樣如下?:
public Integer calculateScore() {
if(getAge() > 21) return 100 - getNumberOfIncorrectAnswers();
//Add 10% before for younger students
else return (100 - getNumberOfIncorrectAnswers()) + 10;
}
然後,您可以提升改變它派生年齡不接觸calculateScore()
方法方式的對象。這意味着你的方法遵循開放閉合原則(OCP)。它可以改進,但可以隨時更改,或者您不必更改方法來源即可更改其獲得年齡的位置。
根據您的應用程序和對象模型的複雜性,封裝式訪問可能仍然有些過度,但即使在這些場景中,理解直接字段訪問的權衡也是很好的,而這些更簡單的場景大都很少見。
一般來說,你應該明白,需要封裝是幾乎從來沒有直接。隨着對象的增長,它會隨着時間的推移而出現,如果對象不是從開始封裝開始設置的,那麼將其放入更昂貴。這就是使這種方法難以欣賞的原因。它需要經驗(即使得典型的過分簡單化並且在數年內多次遭受痛苦)至感覺爲什麼封裝是必要的。這不是你可以觀察和檢測的東西。
也就是說,這是一個比當今IDE更大的問題。今天,您可以使用內置的encapsulate fields
重構IntelliJ這樣的IDE來根據需要引入模式。即使使用現代IDE,從一開始實踐封裝仍然是有利的。
如果你經過Java封裝和抽象,那麼我認爲第一個更可取。因爲你不直接暴露字段。 – SachinSarawgi
就意義而言,沒有區別。這更多的是一個觀點問題。我會選擇**實現1 **,因爲您一定會獲得想要測試的值,例如,如果您有,例如,任何類型的轉碼編碼 – DamCx
您應該對此進行詳細閱讀:http:// stackoverflow .com/questions/1568091/why-use-getters-and-setters – rafid059