2008-12-06 49 views
64

你們是如何決定在本地跟蹤事件,然後將它傳遞給你調用它的每個方法,或者聲明一個實例變量並在方法?何時傳遞參數以及何時使用實例變量

我傾向於喜歡保存在類末尾的列表中的實例變量。但是隨着我的計劃變得越來越複雜,這份名單變得越來越長......我認爲,如果事情經常得到通過,所有需要它的男孩和女孩都應該可以看到,但是我開始想知道, 「爲什麼不把所有的東西都公之於衆呢?那麼就沒有必要再傳遞任何東西了!」

+1

如果你有一個具體的例子,你可能會得到更直接有用的答案 – Brabster 2008-12-06 10:46:09

回答

34

因爲要引用實例變量,我假設你在面向對象的語言工作。在某種程度上,何時使用實例變量,如何定義它們的範圍以及何時使用局部變量是主觀的,但是在創建類時可以遵循幾條規則。

  • 實例變量通常被認爲是類的屬性。將這些看作是將從您的課程創建的對象的形容詞。如果您的實例數據可以用來幫助描述對象,那麼將實例數據作爲一個很好的選擇可能是安全的。

  • 在方法範圍內使用局部變量來幫助他們完成工作。通常情況下,一個方法的目的應該是獲取一些數據,返回一些數據,和/或在某些數據上運行/運行算法。有時候,將局部變量看作幫助方法從頭到尾的方法有助於解決問題。

  • 實例變量作用域不僅僅是爲了安全性,而是爲了封裝。不要認爲「目標應該是保持所有變量不公開」。在繼承的情況下,將變量保護起來通常是一個很好的選擇。不要公開所有實例數據,而是爲那些需要訪問外部世界的人創建getters/setters。不要讓它們全部可用 - 只有你需要的那些。這將貫穿整個開發生命週期 - 從開始就很難猜測。

當涉及到圍繞一個類傳遞數據時,很難說你在做什麼是好的做法,而沒有看到一些代碼。有時,直接對實例數據進行操作沒問題;其他時候,事實並非如此。在我看來,這是有經驗的東西 - 隨着面向對象的思維能力的提高,你會發展出一些直覺。

+0

我的答案是將這個答案添加到H-Man2答案(終生)。它應該是成員屬性,當且僅當它是對象的持久狀態。也就是說,該值本身在當前方法堆棧的範圍之外是有意義的。 – 2008-12-06 10:59:09

+0

我的直覺反應是贊同David和H-MAn2。然而,我正在閱讀Robert c Martin的「乾淨的代碼」,並且在第3章中,他重構了代碼以將某些東西從方法參數移動到成員變量,因爲有很多參數是不好的。總的來說,我猜如果你的班級只有一項責任,那麼對象的生命週期與該計算的生命週期相同,所以也許實際的答案是,如果你必須問這個問題,那麼你的班級太大了? – Andy 2015-11-13 14:18:13

32

主要取決於您存儲在變量中的數據的生命週期。如果數據僅在計算過程中使用,請將其作爲參數傳遞。 如果數據綁定到對象的生命週期,則使用實例變量。

當您的變量列表變得太長時,或許考慮將類的某些部分重構爲新類是一個好的觀點。

3

當然,在課堂上保留一大堆公共變量是很容易的。但即使在直覺上,你也可以說這不是要走的路。

在打算使用它之前定義每個變量。如果一個變量支持特定方法的功能,那麼只能在該方法的範圍內使用它。

另外考慮安全性,公開類變量容易受到來自「外部」代碼的不必要更改的影響。你的主要目標應該是保持所有變量都是私有的,任何不是的變量都應該有一個非常好的理由。

關於將參數傳遞給堆棧,它可能會非常快速地變醜。經驗法則是讓您的方法簽名保持清潔和優雅。如果你看到許多使用相同數據的方法,那麼決定它是否足夠重要,如果不是,重構你的代碼使它更有意義。

歸結爲常識。想想究竟在何處以及爲何要聲明的每個新的變量,就是它的功能應該是,從那裏做出關於它應該生活在這範圍內的決定

+0

你經常想要的方法是公開的,所以你可以單元測試它們。 – obesechicken13 2015-12-16 18:59:39

4

恕我直言:

如果狀態的變量構成部分的實例,那麼它應該是一個實例變量 - classinstance HAS-A實例變量。

如果我發現自己反覆將某些東西傳遞給實例的方法,或者我發現有大量的實例變量,我可能會試着看看我的設計,以防萬一我錯過了某些東西或做出了糟糕的抽象某處。

希望它可以幫助

13

在我看來,實例變量只有在數據將用於多個調用時纔是必需的。

下面是一個例子:

myCircle = myDrawing.drawCircle(center, radius); 

現在讓成像myDrawing類使用15個助手函數來創建myCircle對象和每個這樣的功能將需要的圓心和半徑。它們仍然不應該被設置爲myDrawing類的實例變量。因爲他們永遠不會再需要。

另一方面,myCircle類將需要存儲中心和半徑作爲實例變量。

myCircle.move(newCenter); 
myCircle.resize(newRadius); 

爲了使myCircle對象知道它的半徑和中心,當這些新的呼叫做,他們需要被存儲爲實例變量,而不僅僅是傳遞給需要它們的功能。

所以基本上,實例變量是一種方法來保存對象的「狀態」。如果一個變量不需要知道一個對象的狀態,那麼它不應該是一個實例變量。

而且讓所有的東西都公開。這可能會讓你的生活更輕鬆。但它會回來困擾你。 Pease不要。

相關問題