实践中的代码复杂性第一部分:软件复杂性介绍
扫描二维码
随时随地手机看文章
想象一下,你走进一个熙熙攘攘的工作室——这里不是机器嗡嗡作响的地方,而是人们齐心协力的思想。这才是软件编程的真正本质:集体努力,代码不仅是机器的指令,也是开发人员的共同语言。然而,与口头语言不同,代码往往会成为一种晦涩难懂的方言,笼罩在复杂性之中,新手难以理解。这就是为人类编写代码的艺术发挥作用的地方,将神秘的脚本转化为其他人可以轻松理解的叙述。
毕竟,我们代码的主要用户群是软件工程师;那些目前正在与我们合作或将来会为我们的代码工作的人。这改变了我们的软件开发思维。仅仅为机器理解和执行编写代码是不够的。这是必要的,但还不够。如果我们的代码易于人类阅读和理解,那么我们就朝着可管理的代码复杂性迈出了足够的一步。
本文重点介绍以人为本的代码如何帮助实现可控的代码复杂性。有许多最佳实践,但应仔细思考并考虑我们的环境来处理它们。最后,使用丛林隐喻来解释代码复杂性的一些基本动态。
复杂的迷宫
所有人类可读代码的天敌是什么?复杂性。随着项目的发展、功能的增加以及屏幕上代码行的蜿蜒,理解代码成为一项艰巨的任务。为了解决这个问题,开发人员采用了一套经过时间考验的原则,作为对抗混乱的武器。重要的是要记住复杂性是不可避免的。它可能是最小的复杂性或高的复杂性,但这里的一个关键要点是复杂性会悄悄出现,但它不必征服我们的代码。 我们必须保持警惕并尽早采取行动,这样我们才能编写不断增长而不是呻吟的代码。
慢下来
通过应用模块化设计、清晰的命名约定、适当的文档和下一段中提到的原则等最佳实践,我们可以显著降低复杂性增加的速度。这使得代码更容易理解、维护和修改,即使它增长。
打破复杂性
我们可以使用重构和代码审查等技术来识别和消除现有代码库中不必要的复杂性。这并不能消除所有复杂性,但可以显著减少。
选择更好的工具和方法
较新的编程语言和范例通常注重通过设计来降低复杂性。例如,函数式编程提倡不变性和模块化,这可以减少代码结构的复杂程度。
彻底消除复杂性
降低代码复杂性是一回事,减少它是另一回事,而完全消除它是另一回事,在实践中很少能实现。
经过时间考验的原则
下面,我们可以找到一些可能有助于我们对抗复杂性的原则示例。这绝不是一个详尽的清单,但它有助于说明我们的观点:环境是王道。虽然这些原则提供了宝贵的指导,但严格遵守有时会适得其反。始终考虑项目的具体环境。过度应用单一职责或接口隔离等原则可能会导致代码库臃肿,从而掩盖核心功能。
别让我思考
努力让代码读起来自然,并且只需付出最少的脑力劳动就能理解。使用清晰的逻辑和不言自明的结构,而不是过于复杂的设计。尽可能让自己和他人都能轻松理解代码。
封装
将相关数据和功能分组到类或模块内,以促进数据隐藏和更好的组织。
松耦合
最大限度地减少代码库不同部分之间的依赖性,使得修改和测试单个组件变得更加容易。
关注点分离
将代码分为不同的层(例如,表示、业务逻辑、数据访问),以提高可维护性和可重用性。
可读性
使用有意义的名称、一致的格式和注释来解释代码背后的“为什么”。
设计模式(明智)
理解并应用这些常见的解决方案,但不要强迫使用它们。例如,SOLID 原则可以总结如下:
单一职责原则(SRP)
想象一下一把拥有百万种工具的瑞士军刀。虽然很酷,但不切实际。同样,代码应该专注于每个类的一个明确定义的任务。这使得修改代码时更容易理解、维护和避免意外后果。
开放/封闭原则(OCP)
想想乐高积木。你可以构建无数东西而不用改变单个积木本身。在软件方面,OCP 鼓励通过扩展添加新功能,而不改变核心代码。这可以保持代码的稳定性和适应性。
fbusin 替代原则 (LSP)
想象一下派你的朋友代替你工作。他们可能会做些略有不同的事情,但他们应该无缝地履行相同的职责。LSP 确保子类型(继承)可以无缝替换其基类型,而不会导致错误或意外行为。
接口隔离原则 (ISP)
想象一下遥控器上所有按钮都挤在一起。很混乱,对吧?ISP 提倡创建更小、更专业的界面,而不是一个巨大的界面。这使得代码更清晰、更易于使用,因为不同的部分只与它们需要的功能交互。
依赖倒置原则 (DIP)
想象一下每个任务都依赖特定工具。不切实际!DIP 建议依赖抽象(接口)而不是具体实现。这允许您轻松交换实现而不影响其余代码,从而提高灵活性和可测试性。
重构
定期重新审视和改进代码库以提高清晰度和效率。
简单 (KISS)
优先考虑清晰的设计,避免不必要的功能和过度设计。
DRY(不要重复自己)
通过使用函数、类和模块消除代码重复。
文档
为代码和软件使用写出清晰的解释,以帮助用户和未来的开发人员。
滥用如何导致适得其反
虽然上述原则旨在清晰和简单,但误用这些原则可能会导致相反的效果。以下是一些例子。
1. 过度使用 SOLID
严格的 SRP
想象一下,将一个具有多项明确职责的类拆分成多个较小的类,每个类处理一项微小的任务。这会因众多的类和依赖关系而产生不必要的复杂性,妨碍理解。
强迫症
为每个潜在的未来扩展实现接口,即使对于不太可能出现的情况,也可能会因未使用的抽象而导致代码库膨胀,并使理解实际功能变得复杂。
2. 误用设计模式
强制工厂模式
在直接创建对象时应用工厂模式是有意义的,但会引入不必要的复杂性和抽象,尤其是在较简单的项目中。
过度杀戮单身人士
为每个服务或实用程序类使用单例模式,即使在没有必要的情况下也会产生全局状态管理问题和紧密耦合的代码。
3.过度重构
重构狂热
在没有明确目标或理由的情况下不断重构可能会引起混乱,使代码库变得不稳定,其他开发人员更难跟进。
过早优化
过早地针对未来潜在的性能瓶颈优化代码可能会产生可能永远不需要的复杂解决方案,从而增加不必要的开销并降低可读性。
4. 对封装的误解
数据堡垒
过度严格的封装,将所有内部数据和方法隐藏在复杂的访问器后面,会妨碍理解并使代码更难测试和修改。
5. 忽视背景
盲目应用原则
严格遵守原则而不考虑项目的具体需求可能会导致解决方案对于特定情况来说过于复杂和繁琐。
记住
· 目标是将这些原则用作指导方针,而不是严格的规则。
· 简单和清晰至关重要,即使这意味着在特定情况下偏离原则。
· 背景为王:根据项目的独特需求和复杂性调整您的方法。
通过了解这些潜在的陷阱并明智地运用这些原则,您可以使用它们编写清晰高效的代码,避免过度设计的陷阱。
20240701_66825af63f45f__实践中的代码复杂性第一部分:软件复杂性介绍