5分钟经典英文技术演讲2:软件设计真正的精髓-Scott Meyer

一个人的能力上限很大程度上取决于他获取信息的能力。

而能力增长的速度与获取信息的_质量_正相关。

不可否认,大量优质的技术内容都基于英文。“5分钟经典英文技术演讲”专门撷取国外最有价值的纯英文技术演讲,以最精炼的形式将信息传达给国内的技术同侪,绕过网络政策和语言的障碍,实现中西方技术世界无壁垒的信息同步。

最新内容将发布于DecodeZ: https://decodezp.github.io

往期回顾:如何快速掌握新技术

DConf2017:软件设计真正的精髓

原视频

PPT/Slides下载

演讲者:Scott Meyer

上一张演讲者的照片,硬撸过C++的应该都很熟悉他:

Scott Meyer

摘要:成功的软件产品都有其共性。在Scott Meyer看来,这些共性由几个要素组成。在你的作品中考虑这些要素,将帮助你掌握软件设计真正的精髓。

效率/速度(Efficiency/Speed)

效率高(所需要执行的指令数少)的软件在大多数情况下等于速度快性能高的软件。

在硬件性能普遍过剩的2C和移动市场,对软件效率的追求也可以带来更广泛的平台配适性和更好的功耗表现。

而在每增加100毫秒延时,年收入就掉几个百分点的电商、在线广告和高频交易领域,对服务器软件效率的追求没有止境。

追求软件的高性能肯定没错,但大家一定都熟悉一句话:

“过早优化是万恶之源”(Pre-mature optimization is the root of all evil)。

很多人将这句话作为“先不忙优化,最后再说”的理由。但有多少人知道这句话的出处和上下文?

这句话出自Donald Knuth的一篇叫做”Structured Programming with go to Statements”的论文。而这句话的前面一句话和它连起来是:

如果你不能确定在哪里可以优化,就先不要优化。过早优化是万恶之源。

而在这篇总长度41页的论文的同一页,Donald写道:

可以简单获得(easily obtained)的性能提升,并非无足轻重。

当软件已届完成时再考虑性能优化,将是艰难甚至不可能的任务,例如单线程程序改为多线程,有锁替换为无锁结构等等。

所谓”过早优化“(我还是更喜欢将其直译为”不成熟的优化“),并不是指“从软件的设计阶段就考虑性能”,而是指你还并不知道哪里能优化就一通乱搞的时候。

而能看出系统性能的瓶颈,可以给出“成熟的优化”方案,是需要长期的学习和实践积累的。

Side Note: 对软件性能优化,特别是结合CPU内存等硬件特性感兴趣的读者可以自行搜索一下笔者在青涩时期挖了还没填上的大坑: x86高性能编程笺注

可移植性(Portability)

可移植性的出发点,是市场和客户。

Scott举出了一个他供职过的公司的例子:有自己的硬件平台、编译器、和操作系统。他们的产品跑在自己高度定制化的平台上,各方面的优化已臻完美,一切都很美好。

相形之下,那些跑在“拼凑”出来的平台上的竞品,就像一个拙劣的玩笑。

这一切都随着“通用硬件”性价比突飞猛进而结束,竞品提出的策略是:提供该公司80%的产品性能,但只需要20%的价格。

而这样的故事,在Scott二十余年的从业经历中重复发生着。

当你真的认真在考虑一个严肃的软件产品时,请通过可移植性给予它更多的市场适应能力,而不至于因为产品之外的因素影响产品本身的生命周期。

同时可移植性也可以帮助你在推出了一款成功的产品并在当前平台下达到市场饱和之后,开拓出更多的市场增长空间。有增长才有后续的融资嘛 :)

而做好产品的可移植性设计,其难度不亚于上一节提到的性能优化。有太多硬件的和软件的细节需要考虑,不但要做好不同平台之间的抽象,还要考虑如何充分利用不同平台的独有特性。

而这一切都将是你不断学习的内容。

修补性(Toolability)

字典中出给的翻译是“修补性”,但我觉得这是一个不贴切的翻译。Toolability在这里的意思是,当你创造出某种产品的时候,需要考虑能够简单地让别人围绕它开发出工具(Tool-able)。

我个人的理解就是,预留出构建生态的能力。

如果把编程语言看作是一种产品,那么某种语言的重构工具就是它整个生态中重要的一环。

重构工具的一项基本功能,就是在一个项目工程中替换某一个函数的名字。在Java中我们有Intellij,有Eclipse,在对C++来说,我们还没有一个特别好使的重构工具。

因为在C++中,一个简单的f(x)可能是:

  • 一个函数
  • 一个函数指针
  • 一个重载操作符
  • 一个模板
  • 一个宏
  • 等等等等

这样的复杂度,让实现C++的重构工具变得几乎不可能。Comments: 现在确实出现了一些C++的重构工具,但相比于其他语言,晚了十余年。

但我们想强调的并不是C++如何重构,而是当没有这些工具,没有产品生态的时候,你的产品能发挥出多大作用,完全受限于使用者本身的能力。而如果他人能够迅速构建出一套工具,将会帮助你提升产品能力的下限。

简单来说就是,只靠产品一个人打天下不行,需要有组件团队的能力。同时当别人想加入你的团队时,最好不要有太多障碍。

一致性(Consistency)

一致性是用户体验提升的核心,这里的用户既包括产品最终的消费者,同时也包括开发者。

所谓用户体验,是能够轻易的与以往的经验做类比。保持一致并不是处女座强迫症作祟,而是在软件设计领域有重要意义——带来有效的抽象和类比。一致性本质上是在为我们的大脑创造一种”模式“,既然是模式,就需要有保持一致的东西。

看一个iOS10上的例子:

删除按钮的图标都是一致的,但位置和颜色并没有保持一致。

试想,如果一系列相关的函数调用,它的相同类型的参数位置都不一样,如下面这个C语言的例子:

即便是编写了数十年C程序的程序员,每次也都需要查表才能确定自己把参数放对了位置。

又如Java中求得某个数据类型的长度的方法:

1
2
3
array.length
string.length()
List.size()

这种体验需要开发者针对每种不同的数据类型分别记忆不同的方法,而不能构建一个一致性的抽象。

现在当然有智能化的IDE可以帮助我们摆放好参数或者使用正确的方法,但我们想探究的正是,为什么IDE会加入这个功能——因为不一致的参数位置和方法名实在太恼人了。

而用户体验的核心,并非是扁平化设计,而是追求一致:产品本身性能一致,稳定性一致;用起来的时候,能把我以前的经验带到这里来,并且我一看就知道,这个产品如何操作。

接口(Interfaces)

设计接口,既要考虑如何容易用对,同时也考虑如何很难用得不对。

而上一节提到的一致性,就是一个很好的指导原则。

毕竟会调用你接口的人,都是聪明人,都是有软件经验的人,同时他们也希望你实现的接口能够帮助他们自己,所以也愿意去读一点文档。

如果即便如此他们还是不能正确使用你的接口,那一定是你自己的问题。

而真正优秀的接口,是调用者凭借你提供的一致性,凭直觉就能使用的接口——“我也不知道为什么,但这个接口就是工作了”。

而一个设计不靠谱接口的开发人员的典型口头禅就是:他们会搞明白的。

这可能正是你的产品变得混乱不堪的开始。

以上就是Scott Meyer想要在本次演讲中传达给我们的内容。

© 2020 DecodeZ All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero