2013-07-16 25 views
2

免責聲明:這個問題是針對那些誰會考慮斯科特邁耶斯在有效的C++項目23的建議是良好的面向對象設計 - 至少在C + +。更喜歡Java中的非成員非朋友函數?

在Java中,全局函數不存在的地方,起初看起來這個原理不適用,但在我看來它是這樣。以Scott Meyers自己的例子。

public class WebBrowser { 
    public void clearCache() {} 
    public void clearHistory() {} 
    public void removeCookies() {} 
} 

通過創建包含靜態便捷方法相關聯的「命名空間」級,我已經通過最小化可以訪問它的內部的代碼量增加的WebBrowser的封裝。畢竟,Java中的靜態方法本質上是全局函數(假定類中的所有內容都是公共和靜態的)。

public class WebBrowserStuff { 
    private WebBrowserStuff() {} // prevent instantiation 

    public static void clearBrowser(WebBrowser browser) { 
     browser.clearCache(); 
     browser.clearHistory(); 
     browser.clearRemoveCookies(); 
    } 
} 

我能看到的唯一的缺點是,有沒有在java參數相關的查找,所以調用該方法是稍微詳細。

WebBrowserStuff.clearBrowser(browser); 

我的問題是,因爲這種使用非成員函數希望在C++(見我的聲明),沒有任何理由,不是增加冗長,你爲什麼不想做這在Java中其他?這個問題具體是關於C++和Java之間關於這種技術的區別。

聽取您對這個是否是普遍良好的面向對象設計的個人意見,並不興趣,雖然我上午興趣,如果有是C之間的文化差異++和Java可能導致普遍的觀點聽力以一種方式或另一種方式傾斜。

[編輯]

不幸的是,我並沒有真正得到的回答我的問題,我的編輯,試圖使它少的意見爲基礎並沒有被關閉,阻止它,所以我不能選擇一個接受的答案。人們可以把它解釋爲,你真的不想這麼做(假設這是C++的良好實踐),沒有任何技術原因,任何對這種技術的反對都是純粹的個人或文化的Java事物。

+0

這些被稱爲助手類,是非常常見的,通常被認爲是不好的做法。見http://blogs.msdn.com/b/nickmalik/archive/2005/09/06/461404.aspx –

回答

1
WebBrowserStuff.clearBrowser(browser); 

是一種靜態方法,它是按類定義的,並且不能直接訪問超出傳遞實例的實例。這需要另一個類爲實用的原因。一般來說,在Java庫本身中,只有當我們使用無法處理所有這些靜態方法的專用類型(Array對象與Arrays類中的實用程序對比,或Collections,我們正在使用廣泛的,不應該採取靜態方法的接口。

這些輔助類一般不是好的做法,並在你的情況,你可以,而且應該,把clearBrowser作爲WebBrowser非靜態方法。

現在,這已經完成,儘管這不是一個好的做法,但它在技術上是有效的,而且沒有合同義務否認你這個權利。在那個筆記上,爲了滿足Java庫的命名,我會調用幫助類WebBrowsers,因爲庫通常將相關的類/接口引用並將其複數化以實現此命名目的。

+0

你有沒有理由說這些課程在實踐中不好?爲什麼我應該把'clearBrowser'作爲'WebBrowser'的非靜態成員? 而且我意識到靜態方法不與一個實例鏈接;這就是重點 - 它們表現得像全球功能。我不完全確定你的意思是要求另一個班級出於公用事業的原因。也許你只是總結了什麼'WebBrowserStuff'呢? 感謝您指出數組和集合類;這些都是很好的示例集合,適合在單獨的「靜態」類中使用。 –

+0

@JosephThomson 1.它創建更多的類。 1和2)通常,對實例狀態進行操作的方法應該在類中,而不是在另一個類中,因爲它在「瀏覽器的clearBrowser,不帶參數的clearBrowser」中具有語義含義。 – hexafraction

0

可以接受,是的。首選,不。原因如下:靜態方法本質上被排除在實例化開銷之外 - 因此,爲WebBrowser類的一些支持方法創建一個新類非常愚蠢。如果有的話,將靜態方法添加到WebBrowser類。這避免了你所說的冗長,並且保持一樣。不過,我也同意科林的觀點,即如果你把它建設成一種類型的圖書館或者以後要擴展的東西 - 那麼在開始時不要過分隱瞞事情。

+0

你是什麼意思「靜態方法本質上排除在實例開銷之外」?這是一個性能問題? 「把事情保持在一起」是使C++中的所有成員函數都成爲函數的主要論據,但我並沒有真正購買它(Meyers在一篇在線文章中提出了一個很好的論點)。 –

+0

我的意思是靜態方法不會爲創建的每個實例花費額外的開銷。因此,如果您有3000個網頁瀏覽器同時運行,那麼對於每個3000的呼叫,您都不會像在調用成員函數時那樣花費相同的開銷。 – RutledgePaulV

0

不,這在Java中並不常見,它不是這樣做的方式。 您創建的WebBrowserStuff在Java中看起來就像是Singleton Pattern的糟糕實現。 您的實現的一個問題是您可以創建WebBrowserStuff的多個實例。看起來你只需要一個,所以你應該使用Singleton

想想如果你想在瀏覽器中使用這些方法。這似乎是正確的方式來處理你的情況。他們應該是瀏覽器的一部分。但是,如果你想做一個輔助類,請確保使它成爲一個單例:添加一個私有構造函數,這樣除了類以外,其他人都不能創建實例並添加getInstance()方法來獲取實例。

+0

你說得對,我應該讓構造函數是私有的,但不是這樣,只有'WebBrowserStuff'可以創建它自己的一個實例,而不是任何東西都可以創建它的一個實例。 'WebBrowserStuff'不是一個單身人士;它只是一堆靜態方法的容器,並且沒有狀態,所以創建一個WebBrowserStuff實例是沒有意義的。 –

+0

約瑟夫,當然你可以使用靜態類。在這種情況下,我認爲辛格爾頓更好。用所有靜態方法檢查關於Singleton與Class的討論http://stackoverflow.com/questions/7329788/static-methods-or-singleton-which-one-to-choose。我發現它非常有用。檢查實現Singleton的Enum方法(從Java 5開始)。如果資源真的很短(一個微小的移動設備?),我會使用全靜態方法類。甚至沒有像Collections這樣的類的輔助方法。單身人士有更多的靈活性。乾杯。 – chipay