无效方法为行为黑洞
如果“認為有害”的文章本身不被認為是有害的,則本帖標題為“認為有害的作廢方法”。 哦,好了
無效方法在大多數面向對象的代碼庫中無處不在。 在運行時中某個地方發生可變狀態或I / O的直接后果是,您可以包裝功能編程狂熱者稱為impure的任何行為,該行為原則上沒有有意義的返回值。 一個常見的示例是在應用程序引導期間,例如在Java中:
@Resource MyClass implements Runnable {// ...@PostConstruct public void init() {if(this.enabled) {this.executorService.scheduleAtFixedRate(this,0,500,TimeOut.MILLISECONDS);} }// ... }上面的代碼據說不錯,但是公共無效方法,尤其是它們在給定代碼庫中的擴散,顯然是代碼的味道。 即使以面向對象樣式進行編碼。
您的
公共方法供您的類合作者使用,它們是類功能的門戶。 因此,它們應盡可能簡潔,并提供實現類行為所需的最小表面積。 任何函數定義的一個主要的自記錄部分自然就是其返回類型。
讓我們從前面的示例開始:
@Resource MyClass implements Runnable {// ...@PostConstruct public void init() {if(this.enabled) {this.executorService.scheduleAtFixedRate(this,0,500,TimeOut.MILLISECONDS);} }// ... }我們的類可能在構造時收到某種executorService實例,該實例可能是從某些依賴項注入粘合代碼獲得的,然后啟動了工作計劃。 客戶代碼需要顯式調用init()的可能性通常很小。 這表明我們的@PostConstruct方法應該具有更嚴格的可見性,可能是private或protected ,而這將是結束。
但是,真的嗎?
可測性
假設我們要實際測試工作線程的關閉行為,這通常是一件棘手的事情。 您想做的事情大致如下:
// changed code from the original MyClass file: @PostConstruct public ScheduledFuture<T> init() {if(this.enabled) {return this.executorService.scheduleAtFixedRate(this,0,500,TimeOut.MILLISECONDS);} }public testExecutorShutdown(){ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();MyClass c = new MyClass(service, true); // executorService, enabledScheduledFuture<T> scheduled = c.init();executorService.shutdown();scheduled.get(1, TimeUnit.SECONDS); // throws exception }上面的測試代碼測試了計劃的操作在執行程序關閉后的1秒(或兩次計劃的迭代)內終止。 這樣的測試依賴于訪問由init方法返回的將來的對象。
自我記錄
人類的知覺被他們當前的意識視野所遮蓋
– 埃利亞·懷斯
我們對init()方法所做的更改啟用了行為測試,但帶來了一個重要的副作用: ScheduledFuture對象現在是MyClass公共接口的一部分,這意味著現在任何客戶端代碼都可以與其進行交互。 這是否是一個理想的屬性,實際上取決于MyClass旨在支持的用例,并且可能您希望將ScheduledFuture封裝在一個更友好的類中,例如,僅公開bool isDone()類的東西。
無論如何,保持上述init方法為空將始終導致您的客戶端代碼(或開發人員使用他/她的IDE瀏覽init簽名)而無視MyClass.init()的實際作用。 只需看看不同的簽名,然后想想自己針對每個簽名進行編碼:
public void init() public ScheduledFuture<T> init()后者將在您每次需要使用它時為您節省大腦周期,因為它清楚地說明了其產生的效果,而無需查看代碼或更深層次的文檔。
一件事做好
當函數一次執行多個操作時,堅持函數返回一個值以明確聲明其行為的想法顯然是不可能的。 幸運的是,它本身就是一種代碼味道 ,并且通過將返回類型視為函數的存在目的,可以使違反該原則變得更加奇怪。
結論
對您自己的未來以及對使用您的代碼的所有開發人員都是好事,永遠不要再在公共API中隱藏諸如返回值之類的寶貴信息。
擁抱與親吻c。
翻譯自: https://www.javacodegeeks.com/2018/05/void-methods-as-behavior-black-holes.html
總結
- 上一篇: 一个吉一个页是什么字 一个吉一个页是啥字
- 下一篇: 菠萝英语怎么读 菠萝英语如何读