我们是否一直在用错误的方式做软件开发?面对一个混乱的代码库,我们脑中闪过的解决方案,通常是那些通用而偏技术的:把前端换成 React、把后端拆成微服务、甚至用 Rust 全盘重写。
在正确的场景下,这些技术选型确实能带来收益,但它们真能解决“烂代码”的核心问题吗?
约翰・欧斯特霍特在《软件设计的哲学》中写道:
编写软件最大的局限,在于我们理解所构建系统的能力。
烂代码的根源,往往是系统变得过于复杂,以至于难以理解。无论是 Rust 还是 React,都无法直接解决这个核心矛盾。那么,什么才能解决?
让事情变简单
答案是:抽象。
抽象是一种思想,它能隐藏无关细节,突出核心逻辑。请注意,抽象是思想本身,而不是实现它的那几行代码。这些思想,是我们对真实世界复杂度的简化模型,能让你更轻松地理解正在构建的系统。你得以站在更高的层面思考问题,只在必要时才深入底层细节。
那么,我们该如何设计出好的抽象呢?
很多时候,优秀的抽象就在眼前,几乎是“呼之欲出”。它们通常是业务中早已存在的概念,你只需要梳理清楚,然后用代码准确地表达出来。比如:订单、商品、客户、订阅。
但要注意,业务口中的“客户”,并非字典里的通用定义,而是你们业务中有着特定规则和交互方式的“客户”。这本身就是一种抽象!你的任务,就是像业务人员用语言描述它一样,用代码把它完整、准确地表达出来。
还有一些抽象更难以被发现,需要你发挥创造力。你需要主动识别系统中的复杂度,然后反复尝试用不同的思想模型去管理它。很多时候,这个过程甚至不需要写代码——仅仅是把思路写在纸上或白板上,就足以评估这个抽象是否合理。一开始可能会觉得困难,但随着练习,你会越来越得心应手。
上述提到的抽象有一个共同点:它们都是数据类型。如果你正在为寻找抽象而苦恼,不妨多关注数据。数据从来都不只是数据,它几乎总是伴随着一系列的修改规则。如果这些规则还没有被妥善封装,那就是你创建一个新抽象思想的绝佳机会。
如何重构已有的抽象
有时候,找到好的抽象会很难,因为代码里已经充斥着大量抽象,只不过它们已经过时或不再适用。桑迪・梅茨在《错误的抽象》一文中,提到了一个非常实用的技巧:直接删除你认为已经失效的抽象,先把重复的代码恢复回来。在看得见重复代码的地方,远比在混乱抽象的迷宫里,更容易找到真正优秀的新抽象。
不要因为害怕犯错而不敢设计抽象。你一定会犯错!设计抽象是一项创造性的工作,而创造性工作本身就伴随着反复试错。与其畏首畏尾,不如大胆设计,并随时准备在它弊大于利时,果断地重构它。
正如修改是写作的核心环节,重构也是软件开发的核心。而随着时间推移,最需要被重构的,往往就是你正在使用的那些抽象思想。
总结
归根结底,你的工作不是编程。你的工作,是通过设计、打磨和重构抽象来管理系统复杂度。只要你能做好这一点,编写代码本身就会变成一件相对简单直接的事情。
反之,如果无法有效管理复杂度,代码库只会变得越来越难以维护,新人难以接手,简单的功能变更会异常复杂,而复杂的功能几乎将无法实现。想要深入探讨更多关于系统逻辑与架构设计的思想,可以到云栈社区与其他开发者交流心得。
|