2012-01-05 76 views
4

我係統中的一些資源使用基於Java集合的對象集合的概念。面向對象的方法橋樑

此集合類(抽象)爲另一個具體類(稱爲列表)提供基本功能,該類允許通過集合的索引查找對象。

我將使用我的HTTP頭文件類來解釋。

我在它的構造函數中有一個這個Lists類的實例。每個HTTP頭字段都通過Headers :: addHeader()方法添加到Collection中。

很顯然,我有一個名爲getHeaders(),它返回集合的存儲,不是集合的對象一個的getter方法。所以,如果我需要列出這個類以外的標題,我只需要調用$ obj - > getHeaders(),並且我有一個添加了所有對象的ArrayObject。

好吧!

但是,最近想出了使用List方法之一的必要性,Lists :: find(),它在Collection的存儲中找到一個Object,但它甚至不知道Object的名字或它的具體位置。

由於Lists對象位於私有屬性中,Headers :: getHeaders()返回Collection Storage,我不想違反封裝,通過將該屬性設爲公共屬性,我無法訪問此方法。

一切我的代碼,除了功能,必須在視覺上優雅,並創建另一個getter方法,讓我們說getHeadersLists()將產生調用,如:

$obj -> getHeadersLists() -> find('foo'); 

這是醜陋的!

於是,我趕緊加了__call()在頭類,它工作得很好:

$obj -> find('foo'); 

但我認識的人(而他在面向對象的主題非常精通)告訴我,這是不對的。

我的論點純粹是關注於可讀性,他反駁說:「在面向對象,魔術方法和可讀性不能共存」。

那麼是什麼?我應該怎麼做才能在這兩個類之間創建這個「橋樑」,而不使用_call()並保留面向對象的原則?

我知道,我可以在頭返回集合對象:: getHeaders(),並使用類似:

$obj -> getHeaders() -> find(); 

但是很多事情我瞭解面向對象的責任。正如其聲明所說,這種方法的責任是返回所有添加的頭,而不是外部對象。

回答

1

我打算用Bob叔叔的單一責任原則a.k.a(S.O.L.I.D的大S)打你。您可以在Principles Of OOD文章中閱讀更多內容。也可以直接回答你的問題Tom Dalling's very nice article and example

Single Responsibility Principle. Acknowledgement I have no rights or claims on this image.

當你隱藏getHeaders()函數調用,它返回和類型的對象列出了問題那麼它看起來像您所呼叫的對象,它有一個叫發現「它不應該有功能「因爲找到正確的標題不是他的責任。

我可以理解你的責任方式。

你說:當我調用getHeaders()我不應該被迫操縱結果進一步得到我想要的。

您的建議是完全正確。但爲了達到隱藏getHeaders()函數調用Syntatic糖的結果是完全錯誤。因爲它會誤導我。

考慮我作爲第三方閱讀你的代碼,我會立即假設這個類的find()函數非常具有誤導性。此外,我會拒絕這個find()函數,因爲從頭文件列表中查找不是來自對象的責任,這只是一個不必要的附加組件或錯誤。所以你的同事也是正確的:D。

我相信情況下,迫使你打電話find()方法能夠使用類型的對象都歸咎於此。

我對你的困境的建議就是這樣的。

  1. 該對象最應該定義一個名爲getHeaders()的函數。不要改變這一點。它應該返回所有標題。
  2. 做一個名爲getRelatedHeaders(「foo」)或getFooHeaders()的第二個函數,它以封裝的方式調用getHeaders()而不是使用find(「foo」),並返回您的「foo」頭。

現在我的朋友只剩下一個小小的窒息。我相信你的討論激起了你和你的隊友應該問的更有趣的問題。

幾乎總是,如果您需要獲取對象的某些屬性並對它們執行操作。那麼你也應該能夠將該功能封裝到該對象/類中。當你得到一個對象屬性並用它來做一些事情然後把它放回去時,它幾乎總是一種代碼味道。

爲什麼這個物體沒有履行他的責任,但你是 操縱他的財產給他?

謝謝你的時間,我希望我在某種程度上幫助你:D。

0

這就是爲什麼在PHP中有一個「受保護的」範圍,就像其他O.O.編程語言。

如果您知道,「受保護」成員可以通過後代類訪問,但不能作爲公共訪問。

作爲一個建議,我通常不使用「私人」,而是,「保護」,而不是出於同樣的原因,作爲您的文章。

+0

+1在這裏相同。 – 2012-01-05 15:51:22

+1

好吧,但受保護的可見性在這種情況下不起作用,因爲我沒有在繼承上下文中調用方法。以這種方式思考:標題**使用**列表而不是標題**是一個**列表。通過擴展Lists,我的Headers類將變得相關。 – 2012-01-05 19:49:21