2009-08-05 93 views
3

難道這讓這裏的其他人難堪嗎?我寧願看到:將getter和setter命名爲「get ...」和「set ...」有什麼好處?

block.key(newKey); // set the key for this block 

testKey = block.key(); // look up the key for this block 

block.setKey(newKey); // set the key for this block 
testKey = block.getKey(); // look up the key for this block 

首先, 「設置」 和 「得到」 是多餘的(因此增加噪聲降低可讀性) 。動作(set/get)由每個語句的語法定義。我瞭解超載。實際上,使用相同的確切標識符強化了這些與對象相同的屬性。當我讀「getKey()」和「setKey()」時,我可能不太確定。其次,如果「get」和「set」被嚴格解釋爲setter和getter,那麼如果其他語義與設置/獲取值相關聯,例如副作用將會令人驚訝。

我想這個偏差來自我的Smalltalk背景,但是在一個多態性正常運行的世界裏,如果沒有「get」和「set」散落在哪裏,我們會不會更好?想想如果我們不必一遍又一遍地輸入這三個字母,我們可以輸入多少代碼? (舌頭有點臉頰)

有人在那裏有同樣的感覺嗎?

+1

我真的不認爲語言不可知標籤適用。 Java是使用該慣例的主要語言。其他人喜歡C#,Delphi等傾向於擁有真實的屬性。 – NotMe 2009-08-05 02:00:59

回答

2

使用「get」和帶有「set」的增詞符前綴固定存取符是一種隨語言而異的實踐,並且似乎在Java中最爲普遍。例如:

  • 在Python中,你有屬性的概念,所以一個訪問可能看起來像obj.foo和賦值函數可能看起來像obj.foo = bar(即使方法被稱爲幕後)。類似的概念存在於Ruby等語言中。因此,在很多語言中,對訪問器和增變器的調用看起來像對實例變量的直接「調用」,並且您從不會看到類似「setFoo」或「getFoo」的任何內容。
  • Objective-C等語言不鼓勵使用「get」前綴訪問器的做法,因此在Objective-C中,您會看到諸如[obj foo][obj setFoo:bar]之類的調用。

我從來不喜歡在Java中用「get」加前綴訪問器的做法,但我確實看到了帶有「set」的前綴mutators的優點。也就是說,由於現行的做法是在Java中以「get」/「set」作爲前綴,所以我繼續使用我自己的代碼中的趨勢。

3

對我來說,getset前綴讓我的大腦在閱讀代碼時少花功夫。當一致地使用時,get/set方法可以更容易地標記頭部,可能使得該類更容易學習&的使用。我花費了大量的時間閱讀代碼與編寫代碼,因此getset的額外字符對我來說沒問題。

+0

正如你反思get/set如何幫助你閱讀代碼,當你遇到 block.setKey(newKey); 您是否創建了帶訪問器的簡單私有變量的心智模型,而如果您讀取的是 block.key(newKey); 你是否更有可能構建更復雜或細緻的心理模型? set/get約定是否違反信息隱藏原則? – 2009-08-06 14:15:11

+0

@Mark,我不認爲它存儲一個私有變量,也不認爲它違反了信息隱藏。 setKey/getKey可以在內存中存儲整數,在數據庫中存儲行,在文件中存儲文本等,但這並不重要。 set/get方法可以存儲或從某處取回某些內容。 – Pete 2009-08-06 15:19:29

4

C#的設計者顯然同意,'C#'標記在StackOverflow上超過了2:1的下一個最流行的語言。所以我懷疑你是在向合唱團傳道。

+1

+1用於正確性的數學證明。 – 2009-08-05 02:44:12

4

幾種語言有不同的處理getter和setter的方法。在Java中你有getName和setName,在Qt中你有名字和setName。由於以下原因,我更喜歡Java方式:

  1. 如果您有一個稱爲驅動器的功能,該怎麼辦?它會導致你的班級駕駛,還是它設置/驅動器?
  2. 打開建議後,您可以鍵入get,然後獲取所有獲得者。如果您不記得您需要的吸氣劑名稱,這非常有用。
  3. 基於原因之一,它將功能分爲不同的組。你有這樣的功能,它們不是以get或set開頭的(儘管也許他們應該從do開始?)。然後你得到一個財產的功能,他們都以get開頭。然後你有設置屬性的函數,並且它們都以set開頭。
+3

您的要點#2和#3來危險地接近贊同匈牙利批註 - 謹防! ;) – 2009-08-05 01:58:59

+0

Drive和Driver在您的使用中無關。一個更好的例子就是Drive是否意味着設置一個屬性或引發一個動作。 – NotMe 2009-08-05 01:59:05

+0

謝謝克里斯,只是寫得有點太快:) 帕維爾,我討厭匈牙利符號,但我喜歡getName和setName。不同之處在於描述每種方法的作用,而另一種描述它們是什麼,這是已知的。此外,匈牙利符號會影響我班內發生的事情,只要從外面看起來很乾淨,我就可以隨心所欲地做事。 – Marius 2009-08-05 02:17:20

1

是的在Java中的get/set本質上是一種解決方法,在該語言中的問題。

比較它與C#的性質在

http://www.csharp-station.com/Tutorials/Lesson10.aspx

或Python http://blog.fedecarg.com/2008/08/17/no-need-for-setget-methods-in-python/

我覺得這是Java最大的失敗之一。

+0

Python鏈接的URL很有趣,因爲博文實際上建議在Python中實現get/set方法,但是通過`property`將它們掩飾到成員名稱。 – Pete 2009-08-05 01:53:09

0

C#獲取器和設置器是「第一類」實體,並不類似語法上的函數調用(儘管任何代碼都可以在訪問器的上下文中運行)。

我只使用get/set來強制我使用Objective-C語言。

2

在C++中的話就用重載

int parameter() const { return m_param } 
void parameter(int param) { m_param = param; } 
2

在常規屬性名應該是名詞,而方法名是一個動詞,因此,在上述示例中的屬性將被稱爲「驅動器」,並且該方法將是'駕駛'。當然會存在重疊的情況,但通常情況下這會起作用並使代碼更具可讀性。

0

您可以輕鬆搜索您的代碼庫以獲取對getDrive()setDrive()的引用。如果你的方法被命名爲'drive',那麼在搜索時你會得到更多的誤報。

3

Java語言目前沒有屬性,所以getter/setter語法已成爲事實上的標準。如果您編寫Java代碼,那麼您將很好地使用Java約定。這不僅僅是其他程序員可以讀取你的代碼,更重要的是其他數百個Java框架可以處理支持Java Bean風格getter/setter的對象。

例如,在Velocity templating engine,你可以寫這樣的:

The answer is $block.key 

以上將嘗試調用:

block.getkey(); 
block.getKey(); 

如果你定義block.getKey(),然後一切都會正常工作。通常最好遵循該語言的約定。

0

聽到,聽到。

我真的很喜歡吸氣劑和吸氣劑的特殊符號。 CLU這樣做是最好的:

  • 在表達式中使用p.x相當於通話get_x(p)

  • 使用p.x := e(轉讓)相當於撥打電話set_x(p, e)

如果對象p接口沒有出口get_xset_x,你是從做相應的操作阻止。簡單。

讓我們來聽聽它的語法糖!