大多数软件工程师的教育都集中于STEM学科:科学(S)、技术(T)、工程(E)和数学(M)。其他科目,尤其是文科类的科目,通常被认为不那么重要,或者仅仅是一个烦人的毕业要求。然而,帮助你成为一名伟大的软件工程师,并创造出人们想要使用的优秀软件的大部分东西,都来自STEM的外部世界。

 

计算机科学是对算法、数据结构和操作系统的研究。编程是计算机科学的实际应用。软件工程是利用软件来工程化地解决问题。有效分析问题、评估不同选项和设计解决方案的能力需要人文科学的相关技能。

 

人文教育意味着什么?

首先要澄清什么是人文科学这一术语。一个简洁的定义:任何不是STEM的东西。虽然在技术上是正确的,但并没有真正告诉我们学习人文和社会科学的好处。很明显,如果你获得生物学学位,你就有资格成为一名生物学家。但是文科的目的并不是直接为某一特定的职业培训。

 

有时自由主义者被错误地认为只是保守派的对立面,就像在政治上一样。相反,它有一个词根,意思是自由,不被囚禁或征服。人文教育提供了在社会中作为自由公民所必需的技能。杰拉尔德·格林伯格说:“它教会学生如何批判性地思考、清晰地沟通、分析和解决复杂的问题、欣赏他人、理解现实世界,并做好不断学习的准备,这样他们就能与他人合作,依靠自己解决未来不断出现的挑战与问题”。

 

软件工程师需要批判性地思考,分析和解决复杂的问题。格林伯格的经验教训(清晰的沟通、欣赏他人和持续的学习)对软件开发来说似乎不那么重要,但正是这些技能决定了一个优秀的开发人员和一个优秀的软件工程师之间的差别。

 

语言的重要性

当音乐剧《汉密尔顿》上演时,我的同事分为两组阵营:一组拼命地买票,另一组对看演出没有兴趣。后者中的一个说他不喜欢音乐剧,因为它们是不现实的——在现实生活中,人们不会自发地开始唱歌和跳舞,但一部音乐剧或戏剧的目的并不是100%真实的;它是在有限的时间里讲述一个故事,传达情感,让观众思考。歌曲结合了音乐和节奏,比单纯的歌词更能吸引观众。剧场的环境大小是有限的,而音乐可以看作是数据压缩的一种技术。

对于软件代码也可以做出类似的评论。在为计算机创建指令时,语法上有严格的限制。这使得代码更接近诗歌而非散文。我不期望软件工程师开始把自己描述成代码诗人,但他们显然是作家。每个作家都必须了解他们的读者。

 

了解你的读者

当教授学生如何成为更好的作家时,第一步是承认并理解你为谁写作。儿童读物的风格与大学论文大相径庭,罗马帝国的历史和生物学实验室的报告也不尽相同。在关于可读代码的演讲中,Laura Savino指出,程序员是为两种受众编写代码的:编译器和其他开发人员。其中一个非常固执己见,当它不理解的时候会大声告诉我们。这使得很多代码倾向于编译器作为主要受众。然而,由于人类必须维护代码,因此让代码保持可读性至关重要。

 

泛语言的概念(ubiquitous language),在领域驱动的设计中很常用。通过明确定义某些适用于特定的上下文的术语,可以有效帮助沟通。通过关注一小部分听众,就能更好地表达你的意图。在泛语言中,单词和短语在不同语境可能有不同的含义,但因为你的受众并不是所有人,因此无须担心。

 

在代码级别,DDD(领域驱动设计)建议使用值类型而不是本机数据类型。传递AccountNumber比传递简单的字符串或整数更有意义。可以清楚地定义检查AccountNumber是否为有效的规则,并且可以防止构造无效的值。一旦我们就一种普遍存在的语言达成一致,它就可以用来防止由于交流中的歧义而产生的错误。

 

所有问题都是沟通问题

无论是向工程师提供来自客户的需求(“我是一个与人打交道的人!”),还是向API发送请求,沟通贯穿于应用程序生命周期和软件系统的每一层。当事情没有按计划进行时,解决方案通常从改善沟通开始。

 

瀑布式项目基于离散的、重要的通信点。需求通常收集并文档化,然后交给开发人员。开发人员编写代码并将其交给QA进行测试。如果软件没有达到预期,每个人都开始相互指责。敏捷方法希望通过创建更频繁、更小的沟通点来解决这个问题。这使每个人都更容易理解正在讨论的内容,确定问题,并在它们成为主要障碍之前解决它们。

 

在N层的单体代码中,通信点的数量是有限的。(前端与后端通信。后端与数据库通信。)在任何单层中,都不会过多考虑通信路径。然而,当整体变得过于笨重而无法频繁部署时,就开始将其分解为单独的服务。此时会有更多的沟通途径需要进行考虑。

 

如果这些服务由不同的团队管理,那么需要确保每个团队都理解其相关服务的行为。康威定律指出:“设计系统的组织……被限制只能设计出这些组织的通讯结构的复制品。”因此,为了能够改善服务之间的沟通,我们不能忽视人与团队之间的沟通。

 

软件通信模型

人文学院研究人类交际和跨文化交际,研究人们如何交流,无论是分享知识、讲故事,还是简单地相互了解,都可以帮助我们了解关于交流会出现哪些挑战、克服这些挑战的方法,以及对那些与之交流的人产生更多的同理心。这些经验教训可以应用到软件工程的许多方面。

 

随着分布式系统变得越来越普遍,必须开始从不同的角度来考虑整个系统中的通信。与其寻找伟大的架构模式,不如从人们如何交流开始,你会发现各种成功技术,其中一些可以作为系统的模型。人类能够进行实时对话,无论是面对面的、通过电话或视频聊天,还是一对一的或大规模的群体。它们还使用异步和分布式通信模式,如发送电子邮件或文本消息,或留下语音邮件。在所有这些过程中,翻译都发生在不同的阶段。

 

下次你在星巴克点咖啡时,可以注意观察,你的订单会被翻译成简明的信息,并写在纸杯上(传输层)。当饮料准备好,他们会叫你的名字(引发一个事件),你会从柜台上取回它(对事件做出响应)。

 

诸如命令查询责任隔离(CQRS)、事件驱动体系结构(Event-DrivenArchitecture)和响应式编程(reactiveprogramming)等软件模式都强调消息传递。在CQRS中,可以发送一个命令或一个查询,其中意图被清楚地理解,并且通过消息传递所有必要的信息。EDA事件驱动和reactive都以人性化的方式来处理问题——当事情发生时,我做出相应的反应。

 

人类的交流比电脑早了几千年,我们进化出了对特定行为模式的期望。在创建软件时,如果系统包含这些模式,而不是试图呈现一些新的和破坏性的东西,那么它将会非常成功。了解用户的期望,并将其设计到系统中,需要一定程度的同理心。

 

同理心的重要性

人文学科告诉我们,世界远比我们所能感知到的更为复杂。虽然同样的视角也可以来自天体物理学,但人文学科探索的是,位置、环境或历史背景的微小变化——一种不同的视角——会带来截然不同的结果。虽然你不可能站在别人的角度去理解他们的处境,但是花时间去理解他们的处境可以让你对他们产生更多的同理心。

 

敏捷宣言只有68个字,但是它可以被大大简化为“实践同理心”。比起过程和工具,它更倾向于个人和互动;比起合同谈判,更倾向于客户合作,这是为了创造共同的理解和同理心。当遇到具有直观冲击性用户体验的软件时,这并不是因为开发人员知道使用哪种排序算法最好——而是因为该软件的设计考虑到了用户的感受。

 

在调试和故障排除时,有时会发现某些功能未达到预期,要对计算机产生同理心,试图理解为什么软件不能像预期的那样工作。毕竟,它没有做任何你或其他开发人员没有要求它做的事情。(如果电脑真的开始独立思考,肯定会引发很多哲学讨论——另一个文科教育有益的时代)。

 

批判性思维及解决问题

我所接触过的每一位优秀的开发人员都具有出色的解决问题的能力。我参加过很多技术面试,面试的目的都不是确定编程能力,而是发掘一个人如何处理新问题。在STEM学科中,科学方法通常被用作一组逻辑分析步骤。

 

科学方法的核心是建立假设,用实验检验假设,然后分析数据得出结论。提出一个问题,确定这个问题是否正确,做背景调查,这些都需要批判性思维能力,而这正是人文科学的重点。

 

有效地反馈结论,最终还是要了解你的受众。如果编写了一个原型应用程序来测试性能改进,如何将结果对非技术产品负责人进行沟通?显示原始代码可能不比编写一份50页的报告更有用。更好的方法是使用原型演示新功能,或者创建一个简单的图表来总结改进的性能指标。良好的沟通取决于你想和谁沟通,以及你想和他们沟通什么。

 

终生学习

人文科学告诉我们,可获得的信息量太大,任何人都不可能知道所有的事情,而且总是有足够的机会去学习更多。学习胜过了解的重要性得到了敏捷教练的赞同,他们强调要有一个增长的心态,而不是固步自封。由于技术发展如此之快,优秀的开发人员已经知道他们必须不断学习新的编程语言、框架和平台。然而,优秀的工程师意识到,继续学习软件开发的非技术方面可以提高他们与团队合作的能力,并提供更好的解决方案。

 

人文科学教授如何运用广泛的知识基础来分析新的和不熟悉的问题。看起来与软件开发完全无关的主题可以提供新的见解和视角,从而为技术带来新思路和新点子。研究人际沟通可以带来更好的微服务体系结构。阅读小说和学习社会科学都能让人产生更强的同理心。同理心帮助你了解你的受众,并创造出让客户满意的伟大软件作品!

 

原文作者:Thomas Betts  译者:江玮