魔术二传手反模式
設(shè)置者和獲取者是邪惡的。 創(chuàng)建JavaBean定義時,這似乎是個好主意。 但是它們對Java社區(qū)造成了很大的傷害。 通常不如null指針那么多,但足夠了。
首先,許多初級人員認(rèn)為實現(xiàn)setter和getter(嘿,在Eclispe中只需單擊幾下)確實可以正確地封裝。 我應(yīng)該詳細(xì)說明為什么不這樣做嗎?
另一件事是使用setter和getter反對YAGNI。 YAGNI代表你不需要它 。 這意味著您不應(yīng)該開發(fā)該項目現(xiàn)在不需要的代碼。 要強(qiáng)調(diào)的是這個詞吧 。 許多程序員傾向于開發(fā)可擴(kuò)展實際功能并執(zhí)行比實際需要更通用的功能的代碼。 即使從原則上講它可能是有價值的:在大多數(shù)實際情況下卻沒有。 代碼變得更加復(fù)雜,另一方面,項目從未發(fā)展到需要程序員創(chuàng)建泛化的階段。
Setter和getter是YAGNI的一個干凈,簡單且使用非常廣泛的示例。 如果setter除了設(shè)置字段的值外什么也不做,而getter除了返回字段的值外什么都不做,那為什么我們根本不需要它們呢? 為什么不將字段的訪問修飾符更改為setter和getter的值(可能是public )?
答案通常是,您可能需要在getter或setter中實現(xiàn)一些更復(fù)雜的功能,然后無需更改bean提供的“接口”。 “ 您可能需要實施 ”一詞表明這是YAGNI。 而且,這很危險。 實施setter和getter隱式公開了類的實現(xiàn)。 塞特犬做什么? 設(shè)置字段的值。 例如, setBirthDate()通過定義來設(shè)置字段birthDate 。 這就是編寫調(diào)用setter的代碼的用戶思考的方式。 您可以在JavaDoc中記錄setBirthDate()實際上“指定”了出生日期,但是為時已晚。 您將方法命名為設(shè)置方法,僅此而已。 沒有人閱讀JavaDoc。 API規(guī)則。
以后,當(dāng)您更改代碼時, setBirthDate()不僅設(shè)置生日,甚至不設(shè)置生日,也不會通知用戶。 更改是無聲的,您只是更改了隱式提供給用戶的界面。 會有bug,調(diào)試會話,新版本,這很好,因為這會創(chuàng)建工作場所(請諷刺,請)。 如果為用戶提供對字段的直接訪問,則將字段從public移到private訪問修飾符的后面將導(dǎo)致編譯時錯誤。 也許這只是一種怪異的個人喜好,但我更喜歡編譯時錯誤而不是錯誤。 它們更易于修復(fù)(閱讀:更便宜)。
不用擔(dān)心:您仍然可以修改您的API。 您仍然可以從方法集中刪除您的setter和getter,并迫使其他程序員修復(fù)其代碼,這些代碼隱含地假定setter實際上已經(jīng)設(shè)置并且getter得到了。 拜托
我寫這篇文章的真實故事是什么?
從前,有一個物體可以做某事。 要執(zhí)行其任務(wù),您可以設(shè)置字段aaa或字段bbb ,但不能兩者都設(shè)置。 該應(yīng)用程序是通過這種方式開發(fā)的,并且已經(jīng)超過六年了。 有一天,一位年輕的程序員公主騎著白馬,希望使世界變得更美好。 他想使前面提到的類更安全,并修改了setter setAaa()以使字段bbb null , setAaa() 。 單元測試大放異彩。 覆蓋率為100%。 (我應(yīng)該學(xué)會不撒謊。)他提交了圖書館的新書,幾周后他完成了實習(xí),回到學(xué)校。 那時應(yīng)用程序開始使用該庫的新版本。 由于這一微小的變化,他們慘遭失敗,并退回到了舊版本。 我們所有人都辛苦了,總而言之,由于簡單的更改,公司花了大約一年的時間來工作,更不用說程序員從頭頂拔下來的頭發(fā)了。
為什么程序失敗了? 有一些代碼以這種方式克隆了一個包含aaa和bbb字段的對象:
BadBean newBadBean = new BadBean();newBadBean.setAaa(oldBadBean.getAaa());newBadBean.setBbb(oldBadBean.getBbb());你明白了。 在新bean中,字段aaa始終為null 。
現(xiàn)在您已經(jīng)閱讀了本文,您將永遠(yuǎn)不會嘗試創(chuàng)建一個聰明的二傳手。 我知道你不會! 您知道的一句話是: 始終編??碼,就像最終維護(hù)您的代碼的人是知道您住的地方的暴力精神病患者。 看哪!
翻譯自: https://www.javacodegeeks.com/2015/03/the-magic-setter-antipattern.html
總結(jié)
- 上一篇: 华为Mate 60 Pro/Pro+独占
- 下一篇: 为AWT的机器人创建DSL