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.mzph.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这几年以及目前的状态…