【读书活动案例分享】——愚公——《重构:改善既有代码的设计》从576次到24次:一次代码重构的启示与深远意义_文章

【读书活动案例分享】——愚公——《重构:改善既有代码的设计》从576次到24次:一次代码重构的启示与深远意义

钱广恩
发表于 2025-11-11 20:32:06

       下面这张图片是我在实际的代码开发中遇到的前人写的一段代码,使用了双层的For循环来实现相关的功能,在数据量较小的时候这块代码并没有什么问题,但是随着数据量越来越大,循环次数越来越多,其性能也越来越差,所以当时看到这样的代码我就毅然决然的决定重构这部分代码。

一、算法优化:从暴力搜索到智能映射
       右侧前人的原始代码采用了最直接的暴力搜索方法——三重循环嵌套。对于24小时的数据,它需要执行24×24=576次比较操作。这种算法的时间复杂度是O(n²),随着数据量的增加,性能损耗将呈指数级增长。
       而左侧的我所采用的重构代码展现了一个优雅的解决方案:通过引入映射(Map)数据结构,先将数据按小时建立索引,然后通过键值直接访问。这种"空间换时间"的策略将时间复杂度从O(n²)降到了O(n),循环次数从576次锐减到24次,性能提升了整整24倍。
       这种优化不仅仅是技术层面的提升,更是编程思维的转变。它体现了从"怎么做"到"怎么高效地做"的思维跃迁,是程序员从代码实现者向问题解决者转变的重要标志。
二、可读性革命:从复杂逻辑到清晰表达
       原始代码中,核心逻辑被深埋在多层嵌套的循环和条件判断中。阅读这样的代码,就像在迷宫中寻找出口,需要不断地在脑中进行堆栈操作,跟踪每一个循环变量和状态变化。
// 重构前:逻辑复杂,意图模糊
if (hoursArray[j] == Funcs.Hour(res.data[y].TimeReal)) {
// 业务逻辑被嵌套在多层控制结构中
}
       重构后的代码通过引入有意义的中间变量和数据结构,使代码的意图变得清晰明了:
// 重构后:意图明确,逻辑清晰
if (hourlyDataMap[hoursArray[j]]) {
BillAvgRealPower = hourlyDataMap[hoursArray[j]].BillAvgRealPower;
}
       这种清晰性不仅降低了新开发者的理解成本,也大大减少了未来维护时引入错误的风险。正如《重构》作者Martin Fowler所言:"任何傻瓜都能写出计算机能理解的代码,唯有能写出人类容易理解的代码的,才是优秀的程序员。"
三、可维护性的质的飞跃
       重构后的代码在可维护性方面实现了多重提升:首先,它遵循了单一职责原则。原始代码的一个函数同时负责数据查找、数据处理和结果组装,违反了单一职责原则。而重构后的代码将不同的关注点分离,使每个部分都专注于自己的核心职责。其次,它为扩展留出了空间。如果需要添加新的数据字段,原始代码需要在多个地方修改,而重构后的代码只需在映射构建和访问两个明确的位置进行调整,大大降低了修改的复杂度和风险。最重要的是,它建立了防御性编程的机制。通过显式地处理数据不存在的情况(使用默认值),代码的健壮性得到了显著提升。

        这个重构案例的价值远远超出了当前的具体问题,它为我们提供了可复用的优化模式:当发现代码在循环中反复查询相同的数据集时,就应该考虑引入缓存或索引机制。代码的优化需要选择合适的数据结构,在本案例中可以考虑更加适合的存储结构如映射(Map)和集合(Set)。并且要培养预处理思维:将运行时计算转移到初始化阶段,用空间换取时间。这些都是重构的重要方法
代码重构不仅仅是技术活动,更是一种文化体现。它反映了开发团队对质量的追求、对技术的尊重以及对协作的重视。
       在快速迭代的互联网时代,我们常常面临"先上线,后优化"的压力。但这个案例告诉我们,适当的投资于代码质量,往往会带来意想不到的回报。24倍的性能提升意味着更好的用户体验、更低的服务器成本,以及更快的业务响应能力。这个从576次循环到24次循环的优化故事,生动地展示了重构的威力。但它绝不是终点,而是一个新的起点。随着业务的发展和技术的变化,今天的优化方案可能成为明天的优化对象。

111 0

评论


意见反馈