`

如何降低软件的复杂性?

阅读更多

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

 

 
图0:阮一峰:如何降低软件的复杂性?

 

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

 

 
图1:阮一峰:如何降低软件的复杂性?

 

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

 

 
图2:阮一峰:如何降低软件的复杂性?

 

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

一、什么是复杂性

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.

 

 
图3:阮一峰:如何降低软件的复杂性?

 

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

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

 

 
图4:阮一峰:如何降低软件的复杂性?

 

四、减少抛错

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

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

 

 
图5:阮一峰:如何降低软件的复杂性?

 

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

 

 
图6:阮一峰:如何降低软件的复杂性?

 

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

 

 

http://www.techug.com/post/a-philosophy-of-software-design.html

分享到:
评论

相关推荐

    软件复杂性管理与应对策略.pptx

    ### 软件复杂性管理与应对策略 #### 第一章:软件复杂性管理概述 - **软件复杂性定义**:软件复杂性是指由于软件系统内部各组件间存在大量交互和依赖关系,使得其整体行为难以预测的现象。这种复杂性来源于多方面...

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

    4.1 拒绝战术编程 4.2 设计两次 5.1 层次和抽象 5.2 复杂性下沉 5.3 异常处理 6.1 深模块和浅模块 6.2 通和专

    领域驱动设计 软件核心复杂性应对之道

    《领域驱动设计:软件核心复杂性应对之道》是由美国软件设计专家Eric Evans撰写的经典著作,这本书详尽地探讨了如何在复杂的业务环境中利用领域驱动设计(Domain-Driven Design,简称DDD)方法来构建高质量的软件...

    软件工程与软件系统可复杂性评估.pptx

    - **降低软件复杂性:** - 简化系统架构:采用更简单的设计方案。 - 规范编程规范:统一编程风格,减少混乱。 - 减少模块耦合度:降低各部分之间的相互依赖。 **软件复杂性对项目的影响** - 增加开发和维护难度...

    计算机算法复杂性分析

    对于编程者来说,能够预测并优化算法的复杂性至关重要,因为它直接影响到软件的性能和资源消耗。本文将深入探讨时间复杂性和空间复杂性,并通过实例解析常见问题算法的复杂性。 时间复杂性是衡量算法运行速度的一个...

    软件外包项目复杂性的概念及维度研究

    软件外包项目复杂性是一个影响软件外包项目成功与否的重要因素。它通常被定义为项目管理和交付过程中所面对的挑战与困难的总体量级。研究者通过分析相关文献,发现目前对于软件外包项目复杂性的研究较少,且现有的...

    领域驱动设计:软件核心复杂性应对之道.zip

    领域驱动设计(Domain-Driven Design,简称DDD)是一种软件开发方法论,由Eric Evans在其同名著作《领域驱动设计:软件核心复杂性应对之道》中提出。这种方法论着重于理解和利用业务领域的专业知识来构建高质量、可...

    领域驱动设计--软件核心复杂性应对之道源码

    每个层次都有其特定的责任,保持职责清晰有助于降低复杂性。 2. **CQRS(命令查询责任分离)** - CQRS将读取和写入操作分离,使得系统可以独立优化读取(查询)和写入(命令)性能。查询模型关注于提供高效的数据...

    通过业务领域模型驱动设计, 关于降低设计复杂性的好书。

    通过业务领域模型驱动设计, 关于降低设计复杂性的好书。

    C++网络编程+卷1+运用ACE和模式消除复杂性

    在网络编程中,模式可以帮助我们更好地组织代码,降低复杂性,提高可维护性和可扩展性。例如,工厂模式用于创建网络连接,观察者模式用于事件通知,代理模式可以用于远程对象访问等。作者将这些模式与ACE库结合,...

    软件工程导论(第六版)课后习题答案1

    此外,软件工程倡导面向对象范型,通过封装、继承和多态性降低软件复杂性,提高可理解性和可维护性,促进代码重用。 结构化范型,又称生命周期方法学,将软件生命周期划分为多个阶段,便于分工合作。然而,对于大型...

    领域驱动设计:软件核心复杂性应对之道.pdf

    《领域驱动设计:软件核心复杂性应对之道》是软件开发领域的一本经典著作,作者通过深入探讨领域驱动设计(Domain-Driven Design,简称DDD)这一方法论,为开发者提供了应对软件核心复杂性的策略和实践。DDD是一种以...

    软件可靠性工程手册(中文版)

    总之,《软件可靠性工程手册》是软件开发者、项目经理和技术领导者不可或缺的参考资料,它提供了一套系统的方法论,帮助我们在复杂和变化的软件环境中构建出更可靠的产品。通过学习和实践其中的理论与技术,我们可以...

    程序复杂性与API设计.pdf

    程序复杂性与API设计的知识点涉及软件工程的核心问题——...通过逻辑与控制的分离(正交设计)、高内聚与低耦合原则以及灵活的接口抽象,可以有效地管理和降低程序的复杂性,使软件设计更加优雅且具有长期的生命力。

    快速设置与降低分辨率小软件

    "快速设置与降低分辨率小软件"是一个专为此目的设计的实用工具,它提供了简单快捷的方式来改变屏幕的显示分辨率。下面将详细阐述相关知识点。 首先,我们来了解屏幕分辨率的基本概念。分辨率是指屏幕上像素的数量,...

    软件开发安全性设计培训

    软件安全问题加剧的三个趋势是互联性、可扩展性和复杂性。互联性是指软件系统之间的连接和依赖关系,增加了软件的脆弱性。可扩展性是指软件可以通过更新或扩展使系统升级,但也增加了软件的复杂性和脆弱性。复杂性是...

    软件可靠性工程Software Reliability Engineering

    同时,采用自顶向下设计、模块化等软件工程方法,控制模块的复杂性和规模,有助于提高软件的可靠性。 总的来说,软件可靠性工程是确保软件质量、降低风险和提高用户信任度的关键。通过系统化的方法,结合管理和技术...

    一种优化的面向对象软件复杂性度量方法

    面向对象软件复杂性度量是评估软件质量和可维护性的重要工具。本文主要探讨了一种优化的面向对象软件复杂性度量方法,旨在弥补现有度量方法的不足,提高度量的有效性和实用性。 CK度量,由Chidamber和Kemerer提出,...

Global site tag (gtag.js) - Google Analytics