Fork me on GitHub

什么是良好的开发思维

一. 引言

“修复了一个Bug,又创造了N个Bug,Bug似乎无穷无尽。”

“这套代码太冗余和复杂,我无法在上面继续添加新功能了。”

“删除不必要的代码,重写这套系统吧!”

上面这些都是开发人员经常讨论的问题。每个开发团队都经历过这些事情。

​ 什么原因造成了这些问题呢?有许多小的因素,比如说开发人员某个习惯,某些约束不一致性等等,短期看这些因素无大影响,但是随着时间推移,可能就对项目有个长期危害。就像你有一个不当的生活习惯,让你患上某种慢性疾病一样。

​ 为了避免这些危害,我们应该应用一些软件法则,培养良好的思维习惯。

二. 关键点

  1. 构思软件的目的

    ​ 明确开发软件的目的都是帮助人们。切记不要以开发软件炫耀你的聪明才智为目的。

    无法想象开发出一个复杂的系统,但是对人们帮助并不大,所以当你Coding前,牢记这点,“我们软件能带来什么帮助”。

  2. 软件设计的目标

    ​ 每个软件随着持续迭代,都可能会遇到难以继续开发和修改。这取决于软件的设计。正如《Code Simplicity》中说到:“设计可以让开发人员尽可能的轻松创建和维护系统,并且持续为用户提供更多的帮助。

    ​ 明确软件设计两个主要目标:1 您的设计对您而言应该非常简单。2 您的设计应该为用户带来更多帮助。

    不管您是前端后端开发人员,使用java还是 JavaScript…..,在您的学习工作生涯中都会接触到很多设计模式,不难理解,这些设计模式也正是为了让开发人员构建更简单,更好的软件而出现。

  3. 误解和理解

    ​ 如果您不能完全的理解您将要开发软件,会导致复杂性增加。所以确保您完全理解您正在使用的系统和工具,比如您的项目引入的某个框架(工具),如果您对该工具不完全理解,它的设计理念和应用不理解,就很可能导致误用,使系统增加复杂性。

  4. 简单

    Simplicity is the ultimate form of sophistication” - 达芬奇

    ​ 我们应该明白,编程是将复杂性降低为简单行的行为。如果一个开发者不能降低其复杂性,甚至让系统增加了复杂性,那么他一定是个劣质开发人员。与之对应,优秀的开发人员都在竭尽全力为其他程序员提供更简单易于理解的代码。

    ​ 有些开发人员可能会有这种心态:“我编写一些难以理解的代码,以便让其他开发人员觉得我聪明。”但是如果您换个角度想,假如接手人员看到您的代码感到困惑,并伴随产生一些不友好的情绪,请问这是你需要的吗?事实上,如果其他人能轻松理解读懂您的代码,这才是最好的。

  5. 复杂性

    控制复杂性是计算机编程的本质” - Brian Kernighan

    许多软件故障的来源是复杂性。Jdon

  6. 维护

    ​ 我们应该意识到维护是开发当中最重要的一件事。开发人员通常会忽略它的重要性。快速编码看起来比代码维护更重要。这就是我们犯错的地方 - 对未来代码维护的无知。简单性和复杂性是影响代码维护的两个主要因素。任何软件的易维护性与其各个部件的简单性成正比。维护工作与软件的复杂性成正比。

    对于维护,我们应该遵循:

    减少维护工作比减少实施工作更重要。

  7. 一致性

    ​ 一致性是简单性的重要组成部分。比如某一类变量的命名,代码缩进等。这也不难理解为什么每个公司都会制订一些技术规范,以便让团队保持一致性。

    ​ 一致性也带来了效率,减少新成员学习不一致代码的成本。当然一致性,不限于编码,比如术语统一,开发流程,工作流程统一等。

    *In any team sport, the best teams have consistency and chemistry. — Roger Staubach*

  8. 优先考虑

    ​ 当面临多种可能性选择时,应该依据什么来考虑?《Code-Simplicity》书中给出了一个公式:

    • 更改可取性(D):你想要做多少改变?

    • 更改的价值(V):此改变给用户带来多大帮助?

    • 更改所需要的工作(E):更改需要多少工作时间

      D = V / E

      更改可取性和更改带来的价值成正比,与所花费的工作,时间成反比。所以,以最少的工作时间带来最大

      改变价值的更改是最应该优先考虑。

  9. 解决问题

    ​ 如果解决一个问题?

    • 充分理解问题,例如:写下您的问题并尝试向别人解释,当您能用简单的术语向别人解释清楚问题时,说明您对这个问题已经充分理解。

    If you can’t explain something in simple terms, you don’t understand it“. — Richard Feynman

    • 计划,沉静,让您的大脑有充分时间来处理信息,分析问题,不要急于胡乱采取行动去尝试解决。
    • 分解问题,不要尝试一并解决一个庞大的问题,将其分解为多个子问题,并逐步解决每个子问题。
  10. 不要追求’’完美’’

    ​ 无论是创建新项目还是向现有系统添加功能,开发人员都倾向于从头开始详细规划所有内容。我们可能希望第一个版本是完美。我们会忽视我们将解决的问题以及我们的软件如何帮助人们。我们会考虑能想到的每一个小细节,然后作出假设和预测。

    但是,我们并不知道等待我们的是什么,追逐完美会花多少钱。

    让我告诉你会发生什么:

    • 您将编写不需要的代码。
    • 通过添加不必要的代码会增加复杂性。
    • 您太通用了。
    • 您将错过开发最后期限。
    • 您将处理由复杂性引起的许多错误。

    你想要这件事发生吗?我觉得不是。

    你该怎么做?

    从小处开始,改进它,然后扩展。

    增量设计应该是您的指南。以下是如何使用它来设计计算器:

    1. 计划一个只添加其他内容的系统。
    2. 实施它。
    3. 改进现有系统的设计,以便您也可以添加其他操作。
    4. 计划减法并重复步骤2和3。
    5. 计划乘法并重复步骤2和3。
    6. 计划划分并重复步骤2和3。
  11. 预测

    ​ 对于代码将来会发生变化这类问题,我们都会试图去设计一个通用的方案,以应对未来所有可能的变化。

    但,问题是过于通用会涉及到大量不需要的代码。您也无法预测未来,因此无论您的解决方案多么通用,它都不够通用,无法满足您将来的实际需求。最有可能的是,这一次永远不会到来,你为解决未来问题而编写的代码会增加复杂性,难以改变代码片段,最终会成为可能破坏软件的负担。

  12. 假设

    An assumption is something that you accept as true or suppose to be true, although you have no conclusive proof.

    ​ 我们知道必须开发一个系统来做X.然后我们认为系统将来要求我们做Y,并且我们也实现Y. 我们编写了数千行代码来设计Y。

    ​ 在将来,我们意识到当前的要求与我们的想法完全不同。但现在,该软件有不必要的代码,因为一切都交织在一起,很难丢弃。重构代码需要几个月的时间,现在我们认为从头开始重写整个软件会导致我们失去数月。

    所以为了避免这种问题,我们应该遵循:代码的设计应基于您现在所知的内容,而不是我认为将来会发生什么。不要去假设。

  13. 停止重塑

    尽量不要重新发明轮子。

    但有些特殊情况:

    • 你需要一些尚不存在的东西。
    • 所有现有的“轮子”都是糟糕的技术,或者无法满足您的需求。
    • 现有的“车轮”未得到妥善维护。
  14. 自动化

    不要把时间浪费在重复性的工作上面,比如:部署运行等。

    *能进行自动化的尽量实行自动化完成。

  15. 代码量

    *Measuring programming progress by lines of code is like measuring aircraft building progress by weight.— Bill Gates*

    ​ 有种现象,”我某个功能写了几千行代码…….” 某开发人员说到。似乎意识里面大家会根据代码行数(代码量)来评估软件的质量,并认为代码行越多越好。

    ​ 但是这里隐含着一些问题,我们自问,我们的软件真有那么大?会不会是哪里设计有问题才导致代码庞大。因为简单的设计,代码应该是简洁,少量。当然不是说代码越少越好。就像我们上面提到的:最佳代码是一小

    段代码,易于理解,易于阅读。

  16. 测试

    ​ 我们应该在一开始就加入必要的日志记录和错误处理,以便我们容易排查问题。

    对于测试(这是指的是开发人员进行的测试,像单元测试这些)应该全面,比如你有 If/else 代码块,那么您应该每个分支都运行测试。总而言之,在你将代码提交到远程仓库后,应该是经过测试稳定可靠,当其他同事更新完你代码后,不会影响其开发。

  17. 评估

    ​ 评估某个系统或功能的开发工作时间精力,这对于开发人员可能是个难题,很多时候我们往往会无从下手,或者随便出个糟糕的估算,并且我们往往会低估了它们,而非高估了。这里讲个笑话,在国内,如果有个功能,您评估需要3天,那么产品经理或者老板会将它压缩到1天,而国外如果您评估了3天,您同事会告诉您这个应该5天或者更长时间。

    ​ 当你无从下手时:将大事件分解为更小的东西。它越小,评估就越容易。您可能仍然会弄错,但是如果您估计一个大项目,这种方式会是您的错误减少。

    记住:一切都比你想象的都长

  18. 远离重写

    重写代码通常是开发人员的妄想,而不是大多数情况下的解决方案。

    ​ 因为阅读代码比编写代码更难。这就是重用代码如此困难的原因。这就是为什么当我们阅读另一个开发人员的代码时,我们的潜意识会低声对我们说“ 扔掉它并重新开始 ”。

    关于重写可以看下这篇文章

  19. 关于注释

    ​    我们经常会听到"这代码注释都没有啊“这样的抱怨。注释很重要,但我们仔细想一想,写注释的目的是什么?看注释的对象是谁?我们很容易用注释去描述我们这段代码正在做什么,这是个误区,首先看代码的对象也是开发人员,如果您的代码简洁,易理解,那么我们写这些注释干嘛!大量无用的注释反而扰乱了我们代码的简洁性。
    

    ​ 那么,我们什么时候写注释呢?写注释的目的应该是解释我为什么这样做,或某些提醒点或作为记录。

  20. 自我发展

    ​ 保持学习。尝试不同的编程语言和工具,阅读有关软件开发的书籍。他们会给你另一个视角。每天小的改进都会对您的知识和技能产生真正的影响。

    要心胸开阔。不要对一项技术着迷。使用所需技术解决特定问题。不要像Microsoft vs Linux那样进行不必要的讨论:)

    知道每个特定问题都有自己特定的解决方案。

原文