对于事物的不同观点,不要专注于预先编写干净的代码。
先写出解决问题的代码,然后再回去清理。唯一需要注意的是不要走太久而不回去清理它。通过清理它,我的意思是返回并仅为定义系统意图的抽象实现 SOLID 原则。
我读过的大多数代码,无论是否来自专业人士,你几乎可以知道他们何时尝试在第一遍编写完美的代码,因为他们总是没有这样做,而且他们永远不会回去清理它。实际干净的代码是迭代代码块草稿的结果,只有原始作者才能理解,直到熟悉所用模式的任何人都可以轻松理解。
尝试预先编写完美的代码是过早的优化。
首先,您最终会得到大量的抽象,而这些抽象实际上并不只是为了满足一些关于可维护代码的教条。很多时候,您会在解决方案的结构上花费大量时间,以至于您尝试解决的实际问题在翻译中丢失了。实际上,抽象的数量越少,就越容易弄清楚一段代码的核心职责。最好先仅在最高级别构建抽象,并且仅在绝对必要时构建更多抽象。
其次,您经常根据当前需求的参数设计错误的抽象,而不是如果您确切地知道需求在未来将如何变化。
职业候选人搜索项目中有一个很好的例子。最初我们的要求是为结果集加载搜索结果和糖果数据(统计图表等)。我们使用 sql 实现了这一切,并将加载 candy 和获取搜索结果的过程分离到不同的服务中。几年后,我们决定尝试使用弹性搜索来实现这一切。事实证明,我们没有必要使用弹性搜索将糖果生成与搜索结果分开,因为它可以同时进行。
发生在我们身上的是,我们过于热衷于让班级对一件事负责。事实上,我们有不同的服务来为搜索生成 sql 并将搜索参数保存到数据库中。当我们使用弹性搜索实现这一点时,参数保存服务就派上了用场,但它仍然是前面做的不必要的工作。事实上,我们为可维护性付出的大部分额外时间几乎都是浪费,因为我们最终不得不重新处理一个核心抽象错误来处理新的需求。
如果我们可以再做一遍,我们会在一个巨大的搜索服务中编写所有代码。在起草过程中,我们会将我们实现的每一个其他服务分解为该服务上的简单私有函数。2 年后,当我们创建第二个搜索实现时,为了打破共享服务,我们所要做的就是将私有功能复制到新服务并在新服务上公开共享功能。与尝试编写“完美”代码相比,这是一种更实用的方法。
不要误解我的意思,干净的代码会让你的代码更加优雅和可维护;你只是不能在第一遍就写出来。仅仅通过阅读一本书或查看人们认为是干净的源代码,你无法真正理解是什么让代码变得干净。除了这些东西之外,为了实现构成干净代码的原则的全部意图,还需要花费大量时间来遇到我上面描述的错误。 不要害怕犯这些错误,它们会让你成为更好的程序员。 害怕错误是一种不宽容的观点,它会让你成为一个更糟糕的程序员。