[译]软件工程不是写代码

原文:Software Engineering is different from Programming
作者:Samer Buna

胖达注:这篇文章发布于2017年10月11日,虽然一年多了,但是方法论的东西并不会过时。

任何对此文感兴趣的读者请花费50美元/年或5美元/月的价格参加Medium会员计划,否则每月只能查看三篇文章。
一个月一餐盒饭钱,我觉得并不贵,你说呢?

以下为本人对文章的翻译。不对内容负责,也不对任何翻译错误负责,同时不包含任何图片内容,如需查看图片请付费查看原文链接,谢谢。


由于容易跟工程师混淆,有些人不喜欢软件工程师这个术语。本文跟这个混淆无关。如果您不喜欢它,可以将其替换为软件作者,软件工匠或软件艺术家!

说到软件工程师,我是指一个视写高质量的软件作为他们的职业的人。他会将科学和统计学应用于该专业并且不仅仅将其视为赚钱的工作的人。

了解如何编程并不能使您成为软件工程师。

任何人都可以学习编程。这很简单。任何人都可以创建在他们的机器上他们工作的简单程序,但这并不能保证相同的程序可以为其他人工作。

我最喜欢的类比是,每个人都可以在淋浴时唱歌和娱乐自己,但是在派对上,你不会播放自己唱歌的录音。你会选择专业人士的歌声。

更多类比?当然:

  • 我们在学校学习数学和写作,但这并没有让我们成为数学家和作家。
  • 我们大多数人都可以轻松地学习烹饪,但是当需要给很多人做饭的时候,我们会雇用一名厨师。
  • 你不要打电话给附近的勤杂工让他从头开始建房子。

我想在本文中分享的主要信息是,简单程序工程程序有很大不同。

编程行为,在其最简单的定义中,是给计算机指令,使用某些输入来做某事以产生一些输出

工程软件的行为是关于设计,编写,测试和维护计算机程序,目的是为许多用户解决问题。它是关于创建强大而安全的解决方案,能够经受住时间的考验,并能解决围绕在最开始问题附近的的一些未知问题。

软件工程师了解一切有关他们解决的问题,他们提供的解决方案,这些解决方案的局限性,隐私影响以及安全隐患的事情。

如果有人不理解这个问题,就不应该让他们为它编写解决方案。

解决方案心态

软件工程师并不认为他们的职业只是编写程序。他们从满足需求和解决问题的角度思考问题。这很重要,因为不是每个问题都需要一个程序。有些问题可以通过现有程序或将多个程序组合在一起来解决。通过早期行动可以完全避免一些问题。设计良好的程序通常包括事先设计以防止未来的问题。

“知识分子解决问题,天才阻止问题的发生。”

  • 艾尔伯特爱因斯坦

复杂的问题通常需要编写多个程序。某些问题需要并行运行的程序,而其他问题需要程序按顺序运行。通过教育用户也可以解决一些问题。

在编写程序之前,软件工程师会询问以下问题:

  • 我想解决什么问题?
  • 除了编写代码还可以做些什么来解决它们?
  • 我可以做些什么来使代码更容易来解决这些问题?

代码质量

优秀的程序清晰可读,可以轻松扩展,与其他程序配合使用,维护它们不是一场噩梦。代码的质量不是一个可以谈判的东西,因为截止日期或感情而使用草率的捷径是永远不可接受的。

工程软件最重要的一个方面是从头开始设计任何可扩展性的东西。修改软件是生活中的事实。用户将需要更多功能和更简单的软件使用方法。

一块软件本身通常不是很有用。有用的软件功能在多个软件彼此通信,交换数据以及协作向用户呈现数据和接口的任务时开始。

程序必须考虑到这一点而设计。他们接受什么消息?监控哪些事件?发出什么消息?我们如何验证和授权通信?

优秀程序的另一个重要方面是代码的清晰度,而不是有多少测试或测试覆盖率报告中的数字。这个代码是否可以被其他人理解这个简单的问题,或者更好的是,作为今天的代码编写者,我会在几周后理解这段代码吗

“计算机科学只有两件事:缓存失效和命名事物。”

  • 菲尔卡尔顿

代码可读性比您想象的要重要得多。不幸的是,没有良好的代码清晰度指标。记住良好的软件模式和实践可能会有所帮助,但往往是不够的。优秀的软件工程师只需要通过经验和直觉来保证代码清晰度。这里的写作比喻是完美的:只知道一大堆单词无法帮助你写出简洁明了的内容。

“我没有时间写一封短信,所以我写了一篇很长的信。”

  • 马克吐温

程序会出问题。能够在问题发生的时候轻松修复它们是良好软件的关键属性。程序中发生的错误应该有明确的消息,并集中记录到某个地方进行监控。报告新错误时,需要修复它的人应该能够调试该错误。他们应该能够在任何时间点挂入系统并读取有关执行上下文的信息。他们应该能够轻松验证对系统任何部分的期望。

环境和测试

当软件工程师编写程序时,他们会确保他们的程序可以在许多不同的环境中,在资源不同的机器上以及在不同的时区工作。该软件需要在许多不同的屏幕尺寸和方向上工作。它还需要具备在被迫使用有限的内存或处理能力时正确处理的能力。

例如,在为Web浏览器创建软件时,它需要在所有不同的主要浏览器中工作。在创建桌面软件时,在大多数情况下,它需要适用于Mac和Windows用户。在创建依赖于数据的应用程序时,软件需要处理当检索该数据的连接缓慢或完全离线一段时间的情况。

要编写一个软件,软件工程师会尝试考虑他们可以想象的每个可能的场景,并计划测试这些场景。这开始于他们称之为没有意外发生的快乐路径,但更重要的是,他们记录了可能发生的每个问题并为此计划测试。一些软件工程师首先编写代码,他们称之为测试用例,模拟这些场景。然后,他们编写能通过所有这些测试用例的所需代码。

软件工程师了解通常含糊不清的软件需求。一个才华横溢的软件工程师的绝招是不是如何写解决方案,而是如何识别哪些内容应该被包含在解决方案中。

成本和效率

软件工程师可以在大多数情况下快速解决问题 如果您认为招聘有经验的程序员意味着更高的成本,请再想一想。您聘用的程序员越有经验,他们就能越快地提供强大,准确,可靠和可维护的解决方案。这意味着从长远来看整体成本会降低。

您还需要考虑运行程序的成本。每个程序都将使用计算机资源,而这些资源并不是免费的。软件工程师将编写高效程序而不是不必要地使用计算机资源。例如,缓存常用数据是一个例子,但它只是数千种可以使程序更快,更高效的工具和变体中的一种。

初学者程序员可能会给你一个廉价的解决方案,但运行该解决方案可能最终会让你和你的客户比有经验的程序员创建一个有效的解决方案花费更多。

可用性

优秀程序的设计考虑了用户体验(UX)。人机交互是无数研究和发现的重要课题。这些发现被应用的越多,软件就越好。

让我举几个例子,让您体会一下范围有多广:

  • 在设计用户需要输入数据的输入表单时,例如,他们的电子邮件地址,一个好的接收程序会忽略电子邮件地址的字母大小写。它还会删除周围的任何额外空格。不要给用户带来困难,即使他们的CAPSLOCK键已打开,电子邮件的小写格式是唯一的。如果程序正在接受新的电子邮件地址,请尽早验证,以便向用户提供明确的消息,表明他们可能使用了错误的地址。这包括明显的验证问题,例如没有@符号,但它还应该包括不那么明显的验证问题,例如使用拼写错误的“gmail.ocm”。
  • 当重定向用户做某事时,一个好的程序会记住它们的原始位置,并在完成后将它们重定向回该位置。一个好的程序还会记住任何已经定义的数据和交互,这些数据和交互需要与用户被要求做的未来步骤相关联。例如,假设您一直在Expedia上搜索作为访客的航班。然后,您决定创建一个帐户。您之前的所有搜索都将保存到新帐户中,您可以从完全不同的计算机访问它们。
  • 一个好的程序在设计时考虑了用户场景。站在用户的立场考虑问题。不要只是添加功能!有一天,我预订了美联航航班但忘记包含我的常旅客号码了。在我得到出票确认之后,我去了美联航网站,想将我的常旅客号码添加到航班上,我花了很长时间才弄明白。没有明显的路径,所以我必须探索可能导致该功能的所有链接。我访问了具有该功能的页面,我一开始根本看不到,因为它被深埋在一个大的表格中。事实证明,我必须编辑旅行者信息,滚动浏览该表格上的大约20个输入元素,选择我想要使用的常旅客号码的类型,并输入所需的电话号码才能使整个表单提交。这就是程序设计时没有站在用户角度考虑的一个例子。

可靠性,安全性和安全

这可能是软件专业人士与业余爱好者不同的最重要的一点。他们知道自己得为编写安全可靠的解决方案负责。

一个软件必须能够抵御糟糕的输入,糟糕的状态和糟糕的交互。这非常难以实现,这也是我们听到因软件错误导致人们死亡的故事的主要原因。

用户将使用输入错误或错误的软件。有些人会故意这样做,试图打破软件并侵入该软件所代表的资源。据称对最近的Equifax惨败负有责任的人被指控没有做好自己的工作,即在公开曝光的所有软件中应设计出对错误和恶意输入的包容性。

安全故事不仅涉及错误和恶意输入,有时也是正常输入。如果用户忘记密码,他们可以尝试多少次?你把他们锁了吗?如果其他人试图让他们被锁定怎么办?您是否允许用户通过未加密的连接提交密码?如果尝试登录帐户来自不寻常的地方怎么办?如果登录似乎是自动化的,您会怎么做?

您如何保护您的用户免受跨站点脚本和请求伪造,中间人攻击以及简单的社交网络钓鱼?如果您的服务器遭受DDoS攻击,您是否有备份策略?这些问题只是列举了需要考虑的一部分。

安全程序不会将敏感信息存储为明文,而是使用非常难以破解的算法将数据单向加密存储。这是一种备份策略,以防程序和数据受到损害。黑客会发现对他们来说几乎没用的加密数据。

软件将进入不良状态,需要做出更正。即使是最好的程序也会出现意外的问题。如果您没有意识到这一点并且您没有计划,那么您不是软件专业人员,您只是不安全程序的作者。

软件缺陷是不可见的。我们预测和预防已知缺陷的知识能力有限。这就是软件工程师理解可以帮助他们编写正确和安全软件的好工具的价值的原因。

拥抱工具

毫无疑问,我们需要更多更好的工具。工具产生很大的作用,而且往往不被重视。

想象一下,如果我们仍然需要部署FTP文件!想象一下,在没有Chrome DevTools的情况下调试网络和性能问题!想象一下,如果没有ESLint和Prettier,编写JavaScript会有多么低效!

如果您是JavaScript开发人员,并且出于某种原因,您不得不只能为代码编辑器选择一个插件,那么您应该选择ESLint。

在编写代码时缩短反馈循环的任何工具都应该是一个受欢迎的补充。Bret Victor关于发明我们创造的直接视觉表现的论点让我大开眼界。拥抱和改进工具是让我们走向光明未来的一种方式。如果您以前没有见过,请立即观看Bret的演讲

当我找到一个很棒的新工具时,我唯一的遗憾是之前没有使用过该工具。更好的工具将帮助您成为更好的程序员。找到它们,使用它们,欣赏它们,如果可以的话,改进它们。

语言的选择至关重要。类型安全很重要。JavaScript上发生的最好的事情是TypeScript(和Flow)。代码静态分析比你想象的要重要。如果你没有这样做,你基本上会让自己容易受到未来未知的影响。没有静态类型系统就不要编码。如果您选择的语言没有静态类型,请更改语言或查找Transpilers。今天的Transpilers足够聪明,可以通过阅读代码中的注释来工作,我认为这是对本身不支持它的语言进行类型检查的语言的未来。

软件工程的演变

没有人可以在两个月,六年甚至一年内学习软件工程。您不会在训练营中学习成为软件工程师。我已经学习了20多年,今天我还在学习。只有在经过大约十年的学习以及设计,构建和维护成千上万用户使用的应用程序之后,我才有足够的信心称自己为经验丰富的程序员。

软件工程并不适合每个人,但每个人都应该学会用计算机来解决自己的问题。如果你可以学习编写简单的程序,你应该去做。如果您可以学习如何使用通用软件服务,去做。如果您学习使用开源软件,那么您将拥有很多能力。

问题在发展,软件工程也应如此。该专业的未来是使普通计算机用户能够使用他们的计算机而无需学习五年。通过易于使用的工具,用户可以自行解决容易出现的问题。然后,软件工程师将继续创建更好的工具,解决更大的已知问题,并尽最大努力防止未知问题。

谢谢阅读。