clean code-代碼整潔之道 閱讀筆記(第十六章)

第十六章 重構SerialDate

16.1 首先,讓它能工作
  1. 利用SerialDateTests來完整的理解和重構SerialDate
  2. 用Clover來檢查單元測試覆蓋了哪些代碼,效果不行
  3. 重新編寫自己的單元測試
  4. 經過簡單的修改,讓測試能夠通過
16.2 讓它做對

全過程:

  1. 開端注釋過時已久,縮短并改進了它
  2. 把全部枚舉移到它們自己的文件
  3. 把靜態變量(dateFormatSymbols)和3個靜態方法(getMontShNames、isLeap Year和lastDayOfMonth)移到名為DateUtil的新類中。
  4. 把那些抽象方法上移到它們該在的頂層類中。
  5. 把Month.make改為Month.fromInt,并如法炮制所有其他枚舉。為全部枚舉創建了toInt()訪問器,把index字段改為私有。
  6. 在plusYears和plusMonths中存在一些有趣的重復,通過抽離出名為
    correctLastDayOfMonth的新方法消解了重復,使這3個方法清晰多了。
  7. 消除了魔術數1,用Month.JANUARY.toInt()或Day.SUNDAY:toInt()做了恰當的替換。在SpreadsheetDate上花了點時間,清理了一下算法
    ?

細節操作:

  1. 刪除修改歷史
  2. 導入列表通過使用java.text.*和java.util.*來縮短
  3. 用<pre>標簽把整個注釋部分包圍起來
  4. 修改類名:SerialDate => DayDate
  5. 把MonthConstants改成枚舉
  6. 去掉serialVersionUID變量,自動控制序列號
  7. 去掉多余的、誤導的注釋
  8. EARLIEST_DATE_ORDINAL 和 LATEST_DATE_ORDINAL移到SpreadSheeDate中
  9. 基類不宜了解其派生類的情況,使用抽象工廠模式創建一個DayDateFactory。該工廠將創建我們所需要的DayDate的實體,并回答有關實現的問題,例如最大和最小日期之類。
  10. 刪除未使用代碼
  11. 數組應該移到靠近其使用位置的地方
  12. 將以整數形式傳遞改為符號傳遞
  13. 刪除默認構造器
  14. 刪除final
  15. 使用枚舉整理for循環,并使用||連接for中的if語句
  16. 重命名、簡化、重構函數
  17. 使用解釋臨時變量模式來簡化函數、將靜態方法轉變成實例方法、并刪除重復實例方法
  18. 算法本身也該有一小部分依賴于實現,將算法上移到抽象類中
最終代碼

DayDate.java

/* ====================================================================
* JCommon : a free general purpose class library forthe Java(tm) platform
* =====================================================================
*
* (C) Copyright 2000-2005, by Object Refinery Limited aand Contributors
...
* /
package org.jfree.date;import java.io.Serializable;
import java.util.*;/*** An abstract class that represents immutable dates with a precision of* one day. The implementation will map each date to an integer that* represents an ordinal number of days from some fixed origin.** Why not just use java.util.Date? We will, when it makes sense. At times,* java.util.Date can be *too* precise - it represents an instant in time,* accurate to 1/1000th of a second (with the date itself depending on the* time-zone). Sometimes we just want to represent a particular day (e.g. 21* January 2015) without concerning ourselves about the time of day, or the* time-zone, or anything else. That's what we've defined DayDate for.** Use DayDateFactory.makeDate to create an instance.** @author David Gilbert* @author Robert C. Martin did a lot of refactoring.*/
public abstract class DayDate implements Comparable, Serializable {public abstract int getOrdinalDay();public abstract int getYear();public abstract Month getMonth();public abstract int getDayOfMonth();protected abstract Day getDayOfWeekForOrdinalZero();public DayDate plusDays(int days) {return DayDateFactory.makeDate(getOrdinalDay() + days);}public DayDate plusMonths(int months) {int thisMonthAsOrdinal = getMonth().toInt() - Month.JANUARY.toInt();int thisMonthAndYearAsOrdinal = 12 * getYear() + thisMonthAsOrdinal;int resultMonthAndYearAsOrdinal = thisMonthAndYearAsOrdinal + months;int resultYear = resultMonthAndYearAsOrdinal / 12;int resultMonthAsOrdinal = resultMonthAndYearAsOrdinal % 12 + Month.JANUARY.toInt();Month resultMonth = Month.fromInt(resultMonthAsOrdinal);int resultDay = correctLastDayOfMonth(getDayOfMonth(), resultMonth, resultYear);return DayDateFactory.makeDate(resultDay, resultMonth, resultYear);}public DayDate plusYears(int years) {int resultYear = getYear() + years;int resultDay = correctLastDayOfMonth(getDayOfMonth(), getMonth(), resultYear);return DayDateFactory.makeDate(resultDay, getMonth(), resultYear);}private int correctLastDayOfMonth(int day, Month month, int year) {int lastDayOfMonth = DateUtil.lastDayOfMonth(month, year);if (day > lastDayOfMonth)day = lastDayOfMonth;return day;}public DayDate getPreviousDayofWeek (Day targetDayofweeek){int offsetToTarget = targetDayOfWeek.toInt() - getDayfWeek().toInt();if(offsetToTarget>=0)offsetToTarget = 7;return plusDays (offsetToTarget);}public DayDate get FollowingDayofWeek (Day targetDayofWeek){int offsetToTarget = targetDayOfWeek.toInt() - getDayofweek().toInt();if(offsetToTarget<= 0)offsetToTarget += 7;return plusDays (offsetToTarget);}public DayDate getNearestDayofWeek (Day targetDayofWeek) {int offsetToThisWeeksTarget = targetDayOfWeek.toInt()- getDayOfWeek().toInt();int offsetToFutureTarget = (offsetToThisWeeksTarget +7)&7;int offsetToPreviousTarget = offsetToFutureTarget - 7if(offsetToFutureTarget>3)return plusDays(offsetToPreviousTarget);elsereturn plusDays (offsetToFutureTarget);}public DayDate getEndOfMonth(){Month month=getMonth();intyear=getYear();int lastDay = DateUtil.lastDayOfMonth (month,year);return DayDateFactory.makeDate(lastDay,month,year);}public Date toDate(){final Calendar calendar = Calendar.getInstance(); int ordinalMonth = getMonth().toInt() - Month.JANUARY.toInt ();calendar.set (getYear(), ordinalMonth, getDayOfMonth(),0,0,0);return calendar.getTime();}public String toString(){return String.format("802d-is-8d", getDayofMonth(),getMonth(),getYear());}publicDaygetDayOfWeek(){Day startingDay = getDayOfWeekForordinalzero();int startingoffset = startingDay.toint() - Day.SUNDAY.toInt();int ordinalofDayOfWeek = (getordinalDay() + startingoffset)7;return Day.fromint(ordinalofDayOfWeek + Day.SUNDAY.toint());}public int daysSince(DayDate date){returngetordinalDay() - date.getordinalDay();}public boolean ison(DayDate other){return getordinalDay() = other.getordinalDay();}public boolean isBefore(DayDate other){return getordinalDay()<other.getordinalDay();}public boolean isonorBefore(DayDate other){return getordinalDay()<= other.getordinalDay();}public boolean isAfter(DayDate other){return getordinalDay() > other.getordinalDay();}public boolean isonorAfter(DayDate other){return getordinalDay() >= other.getordinalDay();}public boolean isInRange(DayDate d1,DayDated2){return isInRange(dl,d2,DateInterval.CLOSED);}public boolean isInRange (DayDate dl, DayDate d2, DateInterval interval){int left = Math.min(dl.getordinalDay(),d2.getordina1Day())int right = Math.max(dl.getOrdinalDay(), d2.getordinalDay());return interval.isIn(getOrdinalDay(),left,right);}
}

Month.java

package org.jfree.date;import java.text.DateFormatSymbols;public enum Month{JANUARY(1), FEBRUARY(2), MARCH(3),APRIL(4), MAY(5), JUNE (6),JULY(7), AUGUST(8), SEPTEMBER(9),OCTOBER(10), NOVEMBER(11), DECEMBER(12);private static DateFormatSymbols dateFormatSymbols = netDateFormatSymbols();private static final int[] LAST_DAY_OF_MONTH = {0,31,28,31,30,31,30,31,31,31,30,31,30,31,30,31};private int index;Month(int index){this.index=index;}public static Month fromInt(int monthIndex) {for(Monthm:Month.values())(if(m.index==monthIndex)return m;}throw new IllegalArgumentException("Invalid month :index " + monthIndex)}public int lastDay(){return LAST_DAY_OF_MONTH[index];}public int quarter(){return1+(index-1)/3;}public String toString()(return dateFormatSymbols.getMonths()[index - 1];}public String toshortString(){return date FormatSymbols.getShortMonths()[index -1];}public static Month parse(String s) {s = s.trim();for(Monthm:Month.values())if(m.matches(s))return m;try{return fromInt(Integer.parseInt(s));}catch (NumberFormatException e){}throw new IllegalArgumentException("Invalid month"+s);}private boolean matches (String s){return s.equalsIgnoreCase(toString()) || s.equalsIgnoreCase(toShortString());}public int toInt(){return index;}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/41934.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/41934.shtml
英文地址,請注明出處:http://en.pswp.cn/web/41934.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

若依微服務初始化搭建教程

文章目錄 &#x1f95d;從Gitee拉取代碼&#x1f344;初始化項目配置配置項目maven配置項目JDKmaven - clean - install &#x1f352;數據源配置創建config / seata數據庫創建ry-cloud數據源導入ry-cloud數據 &#x1f370;啟動Nacos下載Nacos修改Nacos配置雙擊startup.cmd啟動…

梧桐數據庫:查詢優化器是提升數據庫性能的關鍵技術

查詢優化器是數據庫管理系統中的核心組件之一&#xff0c;它的主要作用是在執行查詢語句之前&#xff0c;選擇最優的執行計劃&#xff0c;以提高查詢性能。 查詢優化器的基本原理 查詢優化器的主要目標是找到一個執行代價最小的查詢執行計劃。它通過對查詢語句進行語法分析、…

GraphRAG:AI的全局文本理解革新

前言 在人工智能領域&#xff0c;處理和理解大量文本數據始終是一個挑戰。隨著大型語言模型&#xff08;LLMs&#xff09;的出現&#xff0c;自動化地進行復雜的語義理解和文本摘要變得可能。檢索增強生成&#xff08;RAG&#xff09;方法因其能有效結合檢索與生成技術&#x…

C++基礎語法之重載引用和命名空間等

1.C關鍵字 c的關鍵字比我們的c語言的關鍵字多&#xff0c;c包容C語言并對C語言進行了補充&#xff0c;但是我們對關鍵字的學習是在我們后面逐漸學習的。這里我們的只是提供一個表格對齊了解一下。 2.命名空間 我們c出現了命名空間的概念&#xff0c;用關鍵字namespace來定義。…

LeetCode 二分查找

1.題目要求: 給定一個 n 個元素有序的&#xff08;升序&#xff09;整型數組 nums 和一個目標值 target &#xff0c;寫一個函數搜索 nums 中的 target&#xff0c;如果目標值存在返回下標&#xff0c;否則返回 -1。示例 1:輸入: nums [-1,0,3,5,9,12], target 9 輸出: 4 解…

論文閱讀 - Intriguing properties of neural networks

Intriguing properties of neural networks 經典論文、對抗樣本領域的開山之作 發布時間&#xff1a;2014 論文鏈接: https://arxiv.org/pdf/1312.6199.pdf 作者&#xff1a;Christian Szegedy, Wojciech Zaremba, Ilya Sutskever, Joan Bruna, Dumitru Erhan, Ian Goodfellow,…

信息技術課堂上如何有效防止學生玩游戲?

防止學生在信息技術課堂上玩游戲需要綜合運用教育策略和技術手段。以下是一些有效的措施&#xff0c;可以用來阻止或減少學生在課堂上玩游戲的行為&#xff1a; 1. 明確課堂規則 在課程開始之初&#xff0c;向學生清楚地說明課堂紀律&#xff0c;強調不得在上課時間玩游戲。 制…

電阻負載柜的工作原理是什么?

電阻負載柜是用于模擬電網中各種負載特性的設備&#xff0c;廣泛應用于電力系統、新能源發電、電動汽車充電站等領域。其工作原理主要包括以下幾個方面&#xff1a; 1. 結構組成&#xff1a;電阻負載柜主要由變壓器、調壓器、電阻器、控制器、保護裝置等部分組成。其中&#xf…

理解神經網絡的通道數

理解神經網絡的通道數 1. 神經網絡的通道數2. 輸出的寬度和長度3. 理解神經網絡的通道數3.1 都是錯誤的圖片惹的禍3.1.1 沒錯但是看不懂的圖3.1.2 開玩笑的錯圖3.1.3 給人誤解的圖 3.2 我或許理解對的通道數3.2.1 動圖演示 1. 神經網絡的通道數 半路出嫁到算法崗&#xff0c;額…

數據防泄密軟件精選|6款好用的數據防泄漏軟件強推

某科技公司會議室&#xff0c;CEO張總、CIO李總、信息安全主管王經理正圍繞最近發生的一起數據泄露事件展開討論。 張總&#xff08;憂慮&#xff09;: 大家&#xff0c;這次的數據泄露事件對我們來說是個沉重的打擊。客戶信息的外泄不僅損害了我們的信譽&#xff0c;還可能面…

DAY2:插件學習

文章目錄 插件學習ClangGoogle TestCMakeDoxygen 收獲 插件學習 Clang 是什么&#xff1a;Clang 是指 LLVM 項目的編譯器的前端部分&#xff0c;支持對 C 家族語言(C、C、Objective-C)的編譯。Clang 的功能包括&#xff1a;詞法分析、語法分析、語義分析、生成中間中間代碼 L…

【源碼+文檔+調試講解】智能倉儲系統 JSP

摘 要 隨著科學技術的飛速發展&#xff0c;社會的方方面面、各行各業都在努力與現代的先進技術接軌&#xff0c;通過科技手段來提高自身的優勢&#xff0c;智能倉儲系統當然也不能排除在外。智能倉儲系統是以實際運用為開發背景&#xff0c;運用軟件工程開發方法&#xff0c;采…

Dubbo源碼解析-過濾器Filter

上篇我們介紹了消費端負載均衡的原理 Dubbo源碼解析-負載均衡-CSDN博客 因為篇幅問題&#xff0c;本文主單獨Dubbo消費端負載均原理&#xff0c;從dubbo源碼角度進行解析。 大家可以好好仔細讀一下本文。有疑問歡迎留言。 接著說明&#xff0c;讀Dubbo源碼最好是先對Spring源碼…

小車解決連接 Wi-Fi 后還不能上網問題

小車解決連接 Wi-Fi 后還不能上網問題 跟大家講講&#xff1a;為什么小車連接我們自己的熱點以后還是不能聯網呢&#xff1f; 小車連接我們的熱點以后需要訪問外面的網絡&#xff0c;我們訪問網絡使用域名來進行的&#xff0c;所以要對域名進行解析&#xff0c;但是小車原來的域…

【HarmonyOS NEXT】鴻蒙線程安全容器集collections.Map

collections.Map 一種非線性數據結構。 文檔中存在泛型的使用&#xff0c;涉及以下泛型標記符&#xff1a; K&#xff1a;Key&#xff0c;鍵V&#xff1a;Value&#xff0c;值 K和V類型都需為Sendable類型。 屬性 元服務API&#xff1a;從API version 12 開始&#xff0c…

Android 系統網絡、時間服務器配置修改

1.修改wifi 是否可用的檢測地址&#xff1a; 由于編譯的源碼用的是谷歌的檢測url,國內訪問不了&#xff0c;系統會認為wifi網絡受限&#xff0c;所以改成國內的地址 adb shell settings delete global captive_portal_https_urladb shell settings delete global captive_por…

貓咪浮毛太多怎么處理?6年鏟屎官最值得買的貓毛空氣凈化器分享

作為一位擁有6年鏟屎經驗的鏟屎官&#xff0c;家中既有寶寶又有毛孩子的鏟屎官家庭來說&#xff0c;空氣中的寵物異味和貓毛不僅影響生活質量&#xff0c;更關乎家人的健康。普通空氣凈化器雖然能夠提供基本的空氣凈化&#xff0c;但對于養貓家庭的特定需求&#xff0c;如去除寵…

捕獲 IPython 的輸出:深入探索 %%capture 命令的妙用

捕獲 IPython 的輸出&#xff1a;深入探索 %%capture 命令的妙用 在 IPython 的強大功能中&#xff0c;%%capture 魔術命令是一顆隱藏的寶石&#xff0c;它允許用戶捕獲執行單元格的輸出&#xff0c;無論是打印的文本、錯誤信息還是生成的圖像。這對于創建干凈的報告、自動化文…

使用 YOLOv8 實現人體姿態檢測

引言 在計算機視覺的各種應用中&#xff0c;人體姿態檢測是一項極具挑戰性的任務&#xff0c;它能夠幫助我們理解人體各部位的空間位置。本文將詳細介紹如何使用 YOLOv8 和 Python 實現一個人體姿態檢測系統&#xff0c;涵蓋模型加載、圖像預處理、姿態預測到結果可視化的全流…

回頭看,已過去6載

前言&#xff1a; 目前狀態比較不好&#xff0c;家里催著結婚&#xff0c;自己年紀慢慢變大&#xff0c;感覺很焦慮&#xff0c;時常不經意間感覺嘴角都是向下的&#xff08;os&#xff1a;希望看到這段沒有影響到你的心情&#xff0c;我只是想記錄一下it這幾年以及目前的狀態…