代码的坏味道

本文探讨了代码重构的重要性及其在项目中的实践方法。分析了重构难以推行的原因,并提出了“在不改变功能的前提下,优化其内部结构”的核心原则。介绍了如何通过发现代码的坏味道来确定重构的切入点,并提供了重构的步骤。
1.重构和核心思想

我们一直在强调,程序中我们要不断的进行代码的重构,但是重构作为一种高度的脑力活动确实不易。为什么重构在一般的团队中不易推进呢?究其原因我认为有两方面的原因,第一、项目执行计划中不包括,团队只想更快的看到结果,没有规定时间用来重构,程序员可能有这方面的意识但是做了又不加入绩效所以也没有主动去重构的行动了。第二、没有一个统一的标准,每一个具体的开发人员都会按照自己认为的标准去编写代码实现功能,导致了编写出来的程序代码水平不一致。我认为这两方面原因是阻碍重构的主要原因。

为什么要做重构呢?站在项目长远发展的角度来看重构可以保持项目不被频繁的修改腐化了架构,确保在下一次需求变更的时候能够更加灵活快速的实现功能而会不引起过多的改变。那么我们进行重构工作应该遵循的原则是,“在不改变功能的前提下,优化其内部结构。”。

2.代码的坏味道

任何一个傻瓜都能写出计算机可以理解的代码,唯有写出人类容易理解的代码,才是优秀的程序员。那么我们怎样进行代码重构呢?要进行代码重构前提是能够找到适应的切入点,敏锐的嗅觉闻到代码的坏味道。什么是敏锐的嗅觉呢?前提条件是我们对设计模式的6大原则比较清楚了并且熟悉业务需求。

我们可以从架构和代码两个方面来发现代码坏味道了,怎样发现架构的坏味道呢?一般来说架构设计是程序搭建的基本骨架,在架构层面,要对系统功能的划分,数据存储方案设计,物理部署设计,运行设计和开发使用的架构这五方面进行设计。如果程序在开发过程中发现现有系统的逻辑功能已经超出了原先界定的范围,那么我们就发现一处坏味道了。如果开发架构中原本规定使用三层架构,但是开发中却出现了两层或直接访问数据库的情况都是不符合规范的坏味道。另一方面就是从代码编写上面,我们要把代码写的尽可能轻易被阅读,代码的编写应该使用设计模式6大原则进行检验。项目的坏味道及早发现及早修改保持项目在预期设计范围之内。


3.重构的步骤

差劲的系统是很难修改的,因为很难找到修改点。如果很难找到修改点,程序员就很有可能犯错,从而引入Bug。重构这件事让那些已经能够运行的差劲的系统是没有人愿意去进行内部结构的优化。如果非得重构这样子的富有挑战性的系统,那么采用这几个步骤可以极大的降低重构中引入新的BUG。

每当我要进行重构的时候,第一个步骤永远相同,得为即将修改的代码建立一组可靠的测试环境。因为我们都是人,我们要把自己当人看,是人就不可避免会犯错,所以我需要可靠的测试(自我检验能力)。

当建立完一套完善的测试环境之后,我们以可以一步一步进行代码内部结构的优化了,不要追求一步能够把代码优化得非常成功,保持小步快走的不断对代码进行优化。


重构是一件非常繁琐的事情,程序员要不断的提升自己的语言能力,让编写的代码能够被别人读懂。有持续不断的重构意识,并且付诸实施让我们的代码保持清爽整洁易于阅读,不要做傻瓜一样的程序员,要做优秀的程序员。


### 代码味道概述 代码味道是指程序中存在的某些结构上的缺陷,这些问题虽然不会阻止程序运行,但却会降低其可读性、可维护性和扩展性。通过识别并消除这些味道,可以显著提升代码质量。 #### 味道类型及改进方式 1. **过长的方法** 过长的方法通常包含了过多的责任和复杂的逻辑,这会使方法难以理解和测试[^1]。 #### 改进方式 - 将大方法拆分为多个小方法,每个方法只负责单一职责。 - 使用提取函数(Extract Method)技术来分离出独立的功能模块。 ```python def process_data(data): cleaned_data = clean_data(data) # 提取清洁数据功能 analyzed_data = analyze_data(cleaned_data) # 提取分析数据功能 return format_results(analyzed_data) # 提取格式化结果功能 def clean_data(data): ... def analyze_data(data): ... def format_results(data): ... ``` 2. **霰弹式修改** 霰弹式修改发生在每次变更需求时都需要在多个类中进行大量小改动的情况[^3]。这种模式不仅增加了开发成本,还容易遗漏重要部分。 #### 改进方式 - 应用移动方法(Move Method)、内联临时变量(Inline Temp)等重构手段集中相关行为到单个位置处理。 - 考虑引入抽象基类或者接口统一管理共同的行为特性。 3. **发散式变化** 发散式变化指的是当面对特定类型的改变时,需要同时调整同一类中的多处地方[^2]。这种情况表明该类承担了太多不同方面的责任。 #### 改进方式 - 利用提炼类(Extract Class)把不相关的属性与操作移除出去形成新的子组件。 - 对于复杂的数据模型考虑采用DTO(Data Transfer Object),减少原始对象负担。 4. **重复代码** 如果发现相似片段反复出现,则意味着存在潜在共享机制未被充分利用的机会。 #### 解决方案 - 合并重复条件片段(Consolidate Conditional Expression) - 创建通用工具库供项目其他区域调用 5. **循环语句滥用** 循环往往带来性能瓶颈以及嵌套层次加深的问题。 #### 处理建议 - 替代迭代器或流表达式简化流程控制 ```java List<String> names = people.stream() .map(Person::getName) .collect(Collectors.toList()); ``` 6. **过度耦合** 类之间依赖关系过于紧密,任何一方变动都会影响另一方正常运作。 #### 缓解措施 - 实施依赖注入(Dependency Injection),使服务提供者和服务使用者相互隔离. - 推荐遵循开闭原则(Open/Closed Principle) 7. **缺乏清晰命名** 不恰当的名字会让读者困惑不解,无法快速把握意图. #### 补救办法 - 更改含糊不清的术语为更具描述性的词语 - 确保名称能够反映实际用途而非实现细节
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Scalzdp

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值