2013-02-12 48 views
0

我一直在閱讀爲什麼我應該和爲什麼我不應該使用獲取者和安裝者的原因。我讀this article(設計策略)關於如何/爲什麼不使用getters和setters,但我只是沒有「看到」什麼情況下我不會使用它們,或者更好的是,替代方案。 是的,我需要看到一個替代getters和setter的方法。如何不使用獲得者和​​安裝者

+0

重複:http://stackoverflow.com/questions/1568091/why-use-getters-and-setters – Arpit 2013-02-12 17:32:42

+0

默認應該是沒有getter或setter,除非(i)你必須因爲外部期望找到它們的框架,或者(ii)揭示你們班的一些內部事物是有意義的。 – assylias 2013-02-12 17:34:17

+0

@Aprit這不是重複的。我多次閱讀。這是如何不使用它們。請投票,如果你投票,請說明原因。 – tazboy 2013-02-12 18:27:10

回答

3

這是我在少於三天的時間裏從JW讀到的第二篇文章,他們都分享了爲什麼XXXXX是邪惡的座右銘......留下這些背後我想我會引用文章的最後單詞和給我關於它的意見。

除非絕對必要,否則不應該使用存取方法(getter和setter),因爲這些方法會公開有關類如何實現的信息,從而導致難以維護代碼。有時候get/set方法是不可避免的,但是一個經驗豐富的OO設計人員可能會很容易地消除當前代碼中99%的訪問者。

我相信作者引用具體對象,像POJO(爲什麼不是實體),不與任何人交互。你的網站有一個登錄功能,所以你有一個用戶...爲什麼要打擾getNamesetName,如果它只是一個String

雖然這可能是真的,但如果名稱是null會發生什麼?你是否將自己暴露於NullPointerException的所有代碼中?除非您每次使用該變量時都進行檢查,否則您不能確定任何用戶的名字都不可信。吸氣劑可以使它變得容易,但恕我直言,這一切都是關於味道。你只是將支票從一個地方轉移到另一個地方。

getter/setter方法經常在代碼中出現,因爲編碼器在程序上思考。擺脫這種程序性思維的最好方式是根據具有明確責任的對象之間的對話來思考。坎寧安的CRC卡方式是一個很好的入門途徑。

在這裏,作者似乎進一步在CRC的原則(在文章中解釋)進行挖掘,這是對大多數訪問者的有效論據。

再一次,這是所有關於瞭解你的應用程序,你會讓別人知道它。我現在想不到替代方案,但我寧願選擇成本VS收益的概念,避免吸氣劑有什麼好處,以及避免它花費多少成本(時間瞭解變量,做檢查的時間,找到該領域的時間,確定和處理變更的影響的時間,其中沒有訪問者限制變更)。

另一個有趣的觀點(現在我認爲它是最重要的一點)是什麼時候避免吸氣和吸氣。他們顯然是邪惡如果你暴露你不應該的東西,就像一些重要的變量持有一個計數器,並可能讓你的應用程序處於不一致的狀態(換句話說......「瘋了」)。在這些情況下,吸氣劑就足夠了。

最後,很多框架和工具都依賴這些訪問器來設置和獲取值。避免它們意味着失去與這些工具的「兼容性」,例如,除非您創建間接訪問器或包裝器。

+0

在閱讀本文和文章後,我開始明白什麼是知道你的程序/類是否需要以及是否需要getter和setter。沒有更具體的例子,我很難完全理解,但我必須編寫更多的代碼,並瞭解我的決定不會使用它們。 Simon Verhoeven提供了一個鏈接,幫助至少一個例子,這樣很好,並減輕了負擔。 – tazboy 2013-02-12 19:44:11

+0

@tazboy不錯的鏈接,哦封裝......爲什麼我們不能讓你快樂? :) – Gamb 2013-02-13 12:57:07

4

爲什麼你不想在聲明的類中使用另一個(除非涉及其他業務邏輯)。我無法真正想到一個真正的選擇。把它稱爲你想要的,但你所做的只是聲明一個方法來獲取你的值。 這只是鍋爐板代碼。

也有人使用你的API將期望getters \ setter,並可能會有困惑時,沒有。

一個不錯的讀退房:Are getters and setters poor design? Contradictory advice seen

+1

好的鏈接...... – assylias 2013-02-12 17:33:05

+0

謝謝。 Zarkonnen有一個偉大而簡單的例子,說明爲什麼/如何不使用它們。那裏的其他評論者也有非常好的見解。 – tazboy 2013-02-12 18:29:17

1

這裏有一個:

public class Point { 
    public int x; 
    public int y; 
} 

沒有必要對getter和setter,因爲一個點的定義是x,y值。

像這樣的構造函數將使該類更易於使用。

public Point (int x, int y) 

以及空構造

public Point() 
1

無論你是否使用「干將」或「二傳手」真的可以歸結爲需求的問題。例如,有一些持久性框架需要託管對象來聲明getter和setter。一些模板框架需要它。

如果要限制某個對象成員的可見性(從代碼角度來看),可以在getter上使用修飾符來實現此目的。如果你想限制可變性,你可以在這個setter上使用修飾符。

這在使用getter/setter方面並不是真正的「偏好」問題。這是您嘗試實現的目標以及您正在使用的技術的要求的問題。

1

從我的經驗:

在真正大多數情況下的getter setter方法是最好的。

但是,當在類內使用字段時,通常最好直接訪問變量。

getter/setter的一個缺點是在複雜的數學公式中使用時,它們的可讀性較差,並且更容易出現錯誤,因爲代碼看起來不像 類似於文獻中的公式。

實施例:

​​

return (p2.getX()- p1.getY())/len; 

而這就是隻有一個簡單的例子更具有可讀性。

在極少數情況下,您需要非常高的性能計算。 一個例子是java.awt.Rectangle 爲了性能的原因,需要公開x和y。 但這是一個例外。

其他編程語言通過引入屬性(C#和Objective C)解決了這個問題。它們與點語法一起使用,但內部調用getter或setter。