软件设计的哲学:前言

01 前言

80多年来,人们一直在为计算机编写程序,但令人惊讶的是,关于如何设计这些程序或什么是好程序的讨论却少之又少。关于软件开发过程(如敏捷开发)和开发工具(如调试器、版本控制系统和测试覆盖工具),已经有了相当多的讨论。还广泛分析了编程技术,如面向对象编程和函数式编程,以及设计模式和算法。所有这些讨论都是有价值的,但是软件设计的核心问题在很大程度上仍然没有触及。David Parnas的经典论文“关于将系统分解成模块的标准”发表于1971年,但是在随后的45年里,软件设计的技术水平并没有超过这篇论文。

计算机科学中最基本的问题是问题分解:如何把一个复杂的问题分解成可以独立解决的几个部分。问题分解是程序员每天都要面对的核心设计任务,然而,除了这里描述的工作,我还没有在任何一所大学里找到一个以问题分解为中心主题的类。我们教循环和面向对象编程,但不教软件设计。

此外,程序员之间在质量和生产力方面存在巨大差异,但是我们很少尝试去理解是什么让最好的程序员变得更好,或者在我们的课堂上教授这些技能。我曾与一些我认为是优秀的程序员的人交谈过,但是他们中的大多数人都很难清楚地表达出那些给他们带来优势的特定技术。许多人认为软件设计技能是一种天生的天赋,是不能被教授的。然而,有相当多的科学证据表明,在许多领域的杰出表现更多地与高质量的实践有关,而不是天生的能力(例如,杰夫•科尔文高估了才能)。

多年来,这些问题一直困扰和困扰着我。我想知道是否可以教授软件设计,我假设设计技能是区分优秀程序员和一般程序员的关键。我最终决定,回答这些问题的唯一方法是尝试教授一门软件设计的课程。结果是斯坦福大学的CS 190。在这门课上,我提出了一套软件设计的原则。然后学生通过一系列的项目来吸收和实践这些原则。这门课的教学方式与传统的英语写作课类似。在英语课上,学生们使用一种迭代的过程,他们先写一份草稿,得到反馈,然后重写以做出改进。在CS190中,学生们从零开始开发了大量的软件。然后,我们进行广泛的代码审查,以确定设计问题,学生修改他们的项目来解决问题。这让学生看到如何通过应用设计原则来改进他们的代码。

我现在已经教过三次软件设计课,这本书是基于这门课的设计原则。这些原则是相当高水平的,接近于哲学(“定义错误不存在”),所以学生很难理解抽象的思想。学生通过编写代码、犯错误,然后查看他们的错误和随后的修复如何与原则相关,从而获得最佳的学习效果。

此时您可能会想:是什么让我认为我知道关于软件设计的所有答案?老实说,我不知道。当我开始学习编程的时候,我没有上过软件设计的课程,也没有导师来教我设计原则。在我学习编程的时候,代码评审几乎是不存在的。我对软件设计的想法来自于编写和阅读代码的个人经验。在我的职业生涯中,我用各种语言写了大约250,000行代码。我的团队从零开始创建了三个操作系统、多个文件和存储系统、基础设施工具(如调试器、构建系统和GUI工具包)、脚本语言以及用于文本、绘图、演示和集成电路的交互式编辑器。在此过程中,我亲身体验了大型系统的问题,并尝试了各种设计技术。此外,我还阅读了大量其他人编写的代码,这使我接触到各种方法,有好的也有坏的。

在所有这些经验中,我尝试提取一些常见的线索,包括要避免的错误和要使用的技术。这本书反映了我的经验:这里描述的每一个问题都是我个人经历过的,每一个建议的技术都是我在自己的编码中成功使用过的。

我不希望这本书成为软件设计的最后定论;我确信我错过了一些有价值的技巧,从长远来看,我的一些建议可能会变成糟糕的主意。然而,我希望这本书能够开启一个关于软件设计的对话。将本书中的思想与您自己的经验进行比较,然后自行决定这里描述的方法是否真的降低了软件的复杂性。这本书是一篇观点文章,所以有些读者会不同意我的一些建议。如果你不同意,试着去理解为什么。我感兴趣的是那些对你有用的东西,那些没用的东西,以及你对软件设计的其他想法。我希望接下来的对话将提高我们对软件设计的整体理解。我将把我学到的东西写进这本书的未来版本里。

与我沟通这本书的最好方式是发邮件到以下地址:

[email protected]

我对听到关于这本书的具体反馈很感兴趣,比如bug或改进建议,以及与软件设计相关的一般想法和经验。我特别感兴趣的是可以在本书未来版本中使用的引人注目的例子。最好的例子说明了一个重要的设计原则,并且简单到可以用一两段话来解释。如果你想知道其他人在电子邮件地址上说了什么,并参与讨论,你可以加入谷歌组软件设计书籍。

如果因为某种原因,软件设计书籍谷歌组将来应该消失,在网上搜索我的主页;它将包含如何沟通这本书的更新说明。请不要将与书籍相关的邮件发送到我的个人邮箱。

我建议你对这本书中的建议有所保留。总的目标是减少复杂性;这比你在这里读到的任何特定的原则或思想都要重要。如果你从这本书中尝试了一个想法,发现它并没有减少复杂性,那么不要觉得有义务继续使用它(但是,一定要让我知道你的经验;我想要得到关于什么可行什么不可行的反馈)。

许多人提出了批评或建议,以提高这本书的质量。以下这些人对这本书的不同版本提供了有益的意见:杰夫·迪恩、桑杰·格玛沃特、约翰·哈特曼、布莱恩·克尼汉、詹姆斯·科佩尔、艾米·奥斯特豪特、凯·奥斯特豪特、罗伯·派克、帕莎·兰加纳坦、基思·施瓦茨和亚历克斯·斯纳普斯。Christos Kozyrakis建议用“深”和“浅”来表示类和接口,而不是以前的“厚”和“薄”,这两个词有些模棱两可。我很感激CS 190的学生们;阅读他们的代码并与他们讨论代码的过程有助于明确我对设计的想法。

原文地址:https://www.cnblogs.com/peida/p/12049010.html

时间: 2024-10-10 18:03:00

软件设计的哲学:前言的相关文章

2020荐书:软件设计的哲学

2020年必读书籍推荐:软件设计的哲学(A Philosophy of Software Design),本书190多页,豆瓣的点评分在9分以上,目前只有英文版本,中文版还未上市,英文好的同学建议去直接阅读原版. 内容简介 书中讨论了软件设计的主题:如何将复杂的软件系统分解成可以相对独立实现的模块(如类和方法).这本书首先介绍了软件设计的基本问题,即管理复杂性.然后讨论了如何处理软件设计过程的哲学问题,并提出了在软件设计过程中应用的一系列设计原则.该书还介绍了一系列标识设计问题的危险提示.你可以

软件设计的哲学 第五章 隐藏信息

目录 5.1 信息隐藏 5.2 信息泄漏 5.3 时间分解 5.4示例:HTTP服务器 5.5 示例:类太多 5.6 示例:HTTP参数处理 5.7 示例:HTTP响应中的默认值 5.8 隐藏在类中的信息 5.9 不要过度隐藏 5.10 结论 第四章论述了模块的深度.本章以及随后的几章将讨论创建深度模块的技术. 5.1 信息隐藏 实现深度模块最重要的技术是信息隐藏.这种技术首先由David Parnas描述.基本思想是每个模块应该封装一些知识,这些知识表示设计决策.该知识嵌入到模块的实现中,但不

软件设计的哲学:第四章 深度封装模块

目录 4.1 模块化设计 4.2什么是接口? 4.3 抽象 4.4 深度模块 4.5浅模块 4.6 类拆分 4.7示例:Java和Unix I/O 4.8 结论 管理软件复杂性最重要的技术之一是系统设计,这样开发人员在任何时候都只需要面对总体复杂性的一小部分.这种方法称为模块化设计,本章介绍其基本原理. 4.1 模块化设计 在模块化设计中,软件系统被分解成一系列相对独立的模块.模块可以采用多种形式,例如类.子系统或服务.在理想的情况下,每个模块都完全独立于其他模块:开发人员可以在任何模块中工作,

软件设计的哲学: 第十章 定义不存在错误

目录 10.1 异常增加复杂性的原因 10.2 例外情况太多 10.3 定义不存在的错误 10.4 示例:在Windows中删除文件 10.5 示例:Java子字符串方法 10.6 屏蔽异常 10.7 异常聚合 10.8 事故? 10.9 设计不存在的特殊情况 10.10 做过了头 10.11 结论 异常处理是软件系统中最糟糕的复杂性来源之一.处理特殊情况的代码天生就比处理正常情况的代码更难编写,而且开发人员经常在定义异常时没有考虑如何处理它们.本章讨论了异常对复杂性的不成比例的贡献,然后展示了

软件设计的哲学:第十一章 两次设计

目录 设计软件是困难的,所以你对如何构建一个模块或系统的最初想法不太可能产生最好的设计.如果您为每个主要的设计决策考虑多个选项,您将得到一个更好的结果:设计两次. 假设您正在为GUI文本编辑器设计管理文件文本的类.第一步是定义类将呈现给编辑器其余部分的接口:与其选择第一个出现在脑海中的想法,不如考虑几种可能性.一种选择是面向行的接口,它具有插入.修改和删除整行文本的操作.另一个选项是基于单个字符插入和删除的接口.第三种选择是面向字符串的接口,它可以跨行操作任意范围的字符.你不需要确定每种选择的每

软件设计的哲学:增加复杂度的12中危险信号

软件系统的设计和开发过程中,增加系统复杂性的12中危险信号: 危险信号1:浅层模块 浅层模块的接口相对于它提供的功能来说是复杂的.浅层模块在与复杂性的斗争中帮助不大,因为它们提供的好处(不需要了解它们内部如何工作)被学习和使用它们的接口的成本所抵消.小模块往往是浅层的. 危险信号2:信息泄漏 当在多个地方使用相同的知识时,例如两个不同的类都理解特定类型文件的格式,就会发生信息泄漏. 危险信号3:时间分解 在时间分解中,执行顺序反映在代码结构中:在不同时间发生的操作位于不同的方法或类中.如果在不同

软件设计的思想与哲学

以下是从比较经典的书籍中摘录了的几条跟软件设计相关的原则和思想,这些思想不仅可以帮助你在设计软件.编写代码时有用,而且正如Mike Gancarz的<Linux/Unix设计思想>的译者序的作者漆犇所说"如果用"武侠"来作一个类比,这本书就好像是一部教你修炼内功的秘笈,无论新手老手,修炼基本内功都是一件必须持之以恒甚至可以毕生研习的事情,而同时我们也要知道,有时候优秀程序员和普通程序员水平差距的关键也正在于此". 摘自Robbins和Beebe的<

Tcl 和 Raft 发明人的软件设计哲学

John Ousterhout(斯坦福大学教授,Tcl 语言.Raft 协议的发明人...真的是超级牛人,Title 好多好多,这里就列几个大家熟悉的),在 Google 做了一次演讲,题目就叫 「A Philosophy of Software Design」.首先,John 问了大家一个问题,什么是计算机科学里最重要的事情?下面有回答 Abstration 的,有回答 Complexities 的,有回答 Testing 的.他还问了 Donald Knuth(高德纳,程序员应该都认识吧),

由学习《软件设计重构》所想到的代码review(一)

前言 对于一个程序员来讲如何来最直接的来衡量他的技术能力和产出呢?我想最直观的作法是看他的代码编写能力,就拿我经常接触的一些程序员来看,他们买了很多技术重构类书籍,但是看完后代码编写能力并没有显著提高.有人说可以用代码review工具啊,但是像市面上的这些代码review工具,只能帮助我们解决表面的bug和规范点,还无法帮助我们发现更深层次的设计问题. 下面我将结合<软件设计重构>这本书谈谈在进行代码review的时候,需要关注的哪些点. 一.技术债务 何为技术债务? 技术债务是有意或无意的做