如何降低软件的复杂性?

标签: Developer | 发表时间:2018-09-10 20:16 | 作者:
出处:http://www.ruanyifeng.com/blog/

John Ousterhout 是斯坦福大学计算机系教授,也是 Tcl 语言的创造者。

今年四月,他出版了一本新书《软件设计的哲学》( A Philosophy of Software Design)。这是课程讲稿,160多页,亚马逊全部是五星好评。

我还没读这本书,但是我看了作者在谷歌的一次演讲( Youtube),介绍了这本书的主要内容。我觉得非常值得看,大部分书教你怎么写正确的代码,这本书教你如何正确设计软件。

下面我就根据演讲视频和网上的 书评,做一下笔记。

一、什么是复杂性

Ousterhout 教授认为, 软件设计的最大目标,就是降低复杂性(complexity)。 所谓复杂性,就是任何使得软件难于理解和修改的因素。

Complexity is anything that makes software hard to understand or to modify.

复杂性的来源主要有两个:代码的含义模糊和互相依赖。

Complexity is caused by obscurity and dependencies.

模糊指的是,代码里面的重要信息,看不出来。依赖指的是,某个模块的代码,不结合其他模块,就会无法理解。

Obscurity is when important information is not obvious.

Dependency is when code can't be understood in isolation.

复杂性的危害在于,它会递增。你做错了一个决定,导致后面的代码都基于前面的错误实现,整个软件变得越来越复杂。"我们先把产品做出来,后面再改进",这根本做不到。

Complexity is incremental, the result of thousands of choices. Which makes it hard to prevent and even harder to fix.

二、复杂性的隔离

降低复杂性的基本方法,就是把复杂性隔离。 "如果能把复杂性隔离在一个模块,不与其他模块互动,就达到了消除复杂性的目的。"

Isolating complexity in places that are rarely interacted with is roughly equivalent to eliminating complexity.

改变软件设计的时候,修改的代码越少,软件的复杂性越低。

Reduce the amount of code that is affected by each design decision, so design changes don't require very many code modifications.

复杂性尽量封装在模块里面,不要暴露出来。如果多个模块耦合,那就把这些模块合并成一个。

When a design decision is used across multiple modules, coupling them together.

三、接口和实现

模块分成接口和实现。接口要简单,实现可以复杂。

Modules are interface and implementation. The best modules are where interface is much simpler than implementation.

It's more important for a module to have a simple interface than a simple implementation.

好的 class 应该是"小接口,大功能",糟糕的 class 是"大接口,小功能"。好的设计是,大量的功能隐藏在简单接口之下,对用户不可见,用户感觉不到这是一个复杂的 class。

最好的例子就是 Unix 的文件读写接口,只暴露了5个方法,就囊括了所有的读写行为。

四、减少抛错

有些软件设计者喜欢抛错,一遇到问题,就抛出一个 Exception。这也导致了复杂性,用户必须面对所有的 Exception。"反正我告诉你出错了,怎么解决是你的事。"

正确的做法是,除了那些必须告诉用户的错误,其他错误尽量在软件内部处理掉,不要抛出。

Tcl 语言的最初设计是,unset() 方法用来删除已经存在的变量,如果变量不存在,该方法抛错。Ousterhout 教授说,这个设计是一个错误,完全不应该抛错,只要把 unset() 定义成让一个变量不存在,就解决问题了。

另一个例子是,Windows 系统不能删除已经打开的文件,会有错误提醒。这也是一个设计错误,有些用户实在删不掉这些文件,不得不重启系统。Unix 的做法是,总是允许用户删除文件,但是不清理内存,已经打开的文件在内存里面继续存在,因此不会干扰其他程序的运行,那些程序退出保存文件的时候,发现文件不存在才会报错。这个设计比较好。

(完)

文档信息

相关 [软件 复杂性] 推荐:

如何降低软件的复杂性?

- - 阮一峰的网络日志
John Ousterhout 是斯坦福大学计算机系教授,也是 Tcl 语言的创造者. 今年四月,他出版了一本新书《软件设计的哲学》( A Philosophy of Software Design). 这是课程讲稿,160多页,亚马逊全部是五星好评. 我还没读这本书,但是我看了作者在谷歌的一次演讲( Youtube),介绍了这本书的主要内容.

降低软件复杂性的一般原则和方法

- - SegmentFault 最新的文章
斯坦福教授、Tcl语言发明者John Ousterhout 的著作《A Philosophy of Software Design》[1],自出版以来,好评如潮. 按照IT图书出版的惯例,如果冠名为“实践”,书中内容关注的是某项技术的细节和技巧;冠名为“艺术”,内容可能是记录一件优秀作品的设计过程和经验;而冠名为“哲学",则是一些通用的原则和方法论,这些原则方法论串起来,能够形成一个体系.

复杂性正在杀死软件开发者

- - DockOne.io
现代软件系统日益增长的复杂性正在慢慢杀死软件开发人员. 你怎样才能重新获得控制权,而又能充分利用这些技术所能提供的优势. "复杂性是致命的,"Lotus Notes的创建者和微软的老员工Ray Ozzie 在2005年的一份非常有名的内部备忘录中写道. "它在吞噬开发者的生命;它使产品难以规划、构建和测试;它带来了安全挑战;它使用户和管理员感到沮丧.

【外刊IT评论】从Google Wave和XML看软件复杂性之争

- Lamengao - 外刊IT评论
© 外刊IT评论, 2010. | 永久链接:从Google Wave和XML看软件复杂性之争 | One comment | Add to del.icio.us. 软件公司热衷于雇佣喜欢挑战技术难题的人. 表面上看这种做法没什么问题,不幸的是,这会导致公司处于一种情形,你让他们开发一款产品,他们开发的产品更多的是来满足他们对各种技术挑战的好奇心,而不是用来解决客户的问题.

复杂性和用户体验[译]

- - UX 一淘体验中心
       【译者按】每一个交互设计师应该都怀有一颗追求简单的心——轻盈的操作,简易的流程,干净的界面. 每每提及复杂性,必然会想到其对立面——简单. 所谓简单,就是要去除不必要的干扰,让用户直达目标.        UX的使命之一就是:将复杂的流程简单化. 其间,纠结一个Button的摆放、大小、颜色,又或者研究各类用户群体的“脾气”.

复杂性和用户体验设计

- - ITeye资讯频道
每一个交互设计师应该都怀有一颗追求简单的心——轻盈的操作、简易的流程、干净的界面. 每每提及复杂性,必然会想到其对立面——简单. 所谓简单,就是要去除不必要的干扰,让用户直达目标. UX的使命之一就是:将复杂的流程简单化. 其间,纠结一个Button的摆放、大小、颜色,又或者研究各类用户群体的“脾气”.

用户体验设计中最蛋疼的部分:复杂性(COMPLEXITY)

- Version - 互联网的那点事
说到用户体验设计,就一定会提到简单和复杂(simplicity and complexity)的对立,然后大家就会先入为主的觉得简单就是好,简单就是美. 你甚至都不必当一个体验设计师都知道没有一个UX设计者会说:“我们的目标是要把作品做到非常非常复杂. ”通常来说简单就是指做到排除不必要的干扰,让用户能直接达到他们的目的的设计——但是这并不意味着复杂性也要一并被剔除,听上去挺矛盾的不是么.

审视微服务架构:影响因素、运维复杂性和替代方案 |InfoQ 圆桌

- - InfoQ推荐
本文要点:尽管业界已有一些迁移到微服务的成功案例,但依然有大量企业尚未接触到微服务战略. 当前的微服务方式比以往都要复杂. 我们正构建越来越复杂的系统,使用越来越复杂的架构,进而导致我们举步维艰,学习曲线陡峭.  除了复杂性之外,如何监控和追踪也是微服务面对的极大挑战.  事件驱动架构是构建微服务的很好方法,尤其是针对各服务间的通信.

软件架构

- - 研发管理 - ITeye博客
    对于外包业务类型的项目,软件架构设计的目的与产品类型的项目有所不同,在这里主要讨论外包类型项目的软件架构设计目的.     1、为大规模开发提供基础和规范,并提供可重用的资产,软件系统的大规模开发,必须要有一定的基础和遵循一定的规范,这既是软件工程本身的要求,也是客户的要求. 架构设计的过程中可以将一些公共部分抽象提取出来,形成公共类和工具类,以达到重用的目的.

软件吞噬软件开发

- - PingWest中文网
软件蚕食世界,自互联网特别是移动互联网连接线上线下服务后,已成为不可逆的趋势. 每一项实用的服务可以由小团队来完成. 以WhatsApp为例,这款被高调收购的IM应用,拥有4.5亿月活跃用户,70%的日活跃率,至今还保持每天新增用户1000万的速度. 但这些服务居然由32名工程师支撑下来了,所以有了业界八卦“每位员工价值20亿”的说法.