Java静态方法可能会产生代码异味
“程序源代碼中任何可能表明存在更深層問題的癥狀。”
在Java中, 靜態(tài)方法允許您在“類范圍”內(nèi)執(zhí)行代碼,而不是像成員方法這樣的實(shí)例范圍。 這意味著,它們依賴于類級(jí)別的變量(如果有),傳遞給靜態(tài)方法的參數(shù)或任何其他全局可訪問的數(shù)據(jù)。 它們不是面向?qū)ο蟮摹?對象具有與之關(guān)聯(lián)的狀態(tài),并且只能通過實(shí)現(xiàn)該對象“行為”的方法進(jìn)行操作。 靜態(tài)方法不在狀態(tài)上操作,它們不是面向?qū)ο蟮?#xff0c;實(shí)際上它們是過程式的。
這不好嗎?
不會(huì)。盡管Java是面向?qū)ο蟮?#xff0c;但有時(shí)還是需要和/或首選Java中的類似于過程的編程。 任何面向?qū)ο蟮恼Z言的真正威力在于能夠在代碼中緊密實(shí)現(xiàn)現(xiàn)實(shí)生活中的系統(tǒng)模型的能力(請參閱我有關(guān)面向?qū)ο蠼5奈恼?)。 但是,即使在最核心的對象模型中,也很可能會(huì)有一些粘合代碼或?qū)⒁赃^程樣式實(shí)現(xiàn)的基礎(chǔ)結(jié)構(gòu)代碼。
因此,如果Java中的類似于過程的編程不是“那么糟糕”并且靜態(tài)方法是過程編程的一種形式,那么靜態(tài)方法是否不好?
嗯……答案并不像是“是”或“否”那么簡單,無論您在其他博客上會(huì)讀到什么,但我可能會(huì)不斷爭論著為什么這實(shí)際上是必須在上下文中做出的決定,因此,讓我們重點(diǎn)關(guān)注一下我在Michael Minella博客的“如何模擬靜態(tài)方法”中遇到的一組語句:
“已經(jīng)成為該語言基礎(chǔ)知識(shí)的部分(您要做的只是看一下Apache Commons項(xiàng)目以了解這一點(diǎn))非常糟糕,以測試為名必須不惜一切代價(jià)避免。 Gosling(或其團(tuán)隊(duì)中的某人)出于某種原因?qū)⑵浞湃胝Z言中,并且僅由于您的工具集不支持對它的測試是無稽之談而避免使用這些語言。 是時(shí)候獲得新的工具集了。”
首先,我想指出的是,僅僅因?yàn)槟撤N東西已經(jīng)成為一種語言的基本組成部分,并不意味著它就是“好”或應(yīng)該做的事情。 查看已檢查的異常以供參考。 我記得EJB 1.x和2.x在過去成為Java EE的“基礎(chǔ)”部分,因此也請參考一下。
其次,盡管我在理論上確實(shí)同意Michael的觀點(diǎn),即由于您的工具不支持某種特定的語言功能而使其愚蠢,但他的前提是靜態(tài)方法。 避免使用靜態(tài)方法是因?yàn)槟墓ぞ卟恢С朱o態(tài)方法,這根本不是胡說。 實(shí)際上,由一些好的測試和/或模擬框架( Mockito是我最喜歡的框架)引起的阻抗類型 )和靜態(tài)方法可以確定地識(shí)別為代碼異味。 這并不意味著我們不應(yīng)該這樣做,而是應(yīng)該付出更多的努力來理解我們?yōu)槭裁催@樣做,并在存在“更深層次的問題”時(shí)探索替代方法。
我想指出,至少有兩種類型的靜態(tài)方法通常不會(huì)在測試/模擬框架中表現(xiàn)出太大的阻力。 第一種類型是用作實(shí)用程序方法的靜態(tài)方法,就像在許多apache commons庫或您自己的內(nèi)部commons庫中找到的方法一樣。 這些通常是支持特定方法目標(biāo)的例程,并且將它們模擬/存根到單元測試之外是沒有意義的。 它們是實(shí)現(xiàn)的一部分,因此應(yīng)進(jìn)行測試。 第二種類型是靜態(tài)方法,用于代替構(gòu)造函數(shù),如Joshua Bloch在他的書《 Effective Java》中所展示的。 靜態(tài)方法的這種使用使您可以使用名稱具有非常描述性的方法來構(gòu)造新對象,以及其他一些優(yōu)點(diǎn)。 第二種靜態(tài)方法的分支可能包括工廠方法,但這取決于上下文。
當(dāng)單元依靠靜態(tài)方法執(zhí)行超出該單元職責(zé)范圍的邏輯時(shí),由于靜態(tài)方法和測試框架阻抗而產(chǎn)生的最明顯的代碼異味。 在這些情況下,您的測試框架將對您不利,因?yàn)槟鸁o法對范圍外的邏輯進(jìn)行存根/模擬,因?yàn)樗峭ㄟ^靜態(tài)方法“硬編碼”的。 這可以被視為“更深層的問題”,并且是大多數(shù)博客的焦點(diǎn),這些博客告訴您不要使用靜態(tài)方法,因?yàn)闇y試變得異常困難或不可能。 更改設(shè)計(jì)方法以遵循依賴性反轉(zhuǎn)原則是另一種選擇。 對如何測試單元的更好的理解是另一個(gè)。
我強(qiáng)烈斷言,在使用靜態(tài)方法的情況下,您可能會(huì)從測試框架中得到的回退表示代碼有氣味,而不是您需要嘗試找到一個(gè)使用復(fù)雜的欺騙手段并將類加載器重新映射作為解決方案的框架。 應(yīng)該準(zhǔn)備評(píng)估一種特殊方法在其設(shè)計(jì)中的用途和基本缺陷。 Michael的博客文章使讀者太容易采用新的工具/框架,僅因?yàn)镴ava支持靜態(tài)方法并且您當(dāng)前的測試框架闡明了一個(gè)阻抗-在這種情況下,阻抗反映了代碼的味道,需要一些更深入,更批判性的思考。
參考: Java靜態(tài)方法可能是 JCG合作伙伴 Christian Posta在Christian Posta Software博客上的代碼味道 。
翻譯自: https://www.javacodegeeks.com/2012/05/java-static-methods-can-be-code-smell.html
總結(jié)
以上是生活随笔為你收集整理的Java静态方法可能会产生代码异味的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 腔怎么读音 腔如何读
- 下一篇: 安全密码存储–请勿做的事和Java示例