diff options
author | Hui Lan <lanhui@zjnu.edu.cn> | 2019-04-06 21:34:05 +0800 |
---|---|---|
committer | Hui Lan <lanhui@zjnu.edu.cn> | 2019-04-06 21:34:05 +0800 |
commit | 70badf413e3ce6fbac036b4167c15b2a1af73d1a (patch) | |
tree | 53c35560579f0c9c67e9982da1aa87e3d0b588cf |
第一次commit,把所有学生的翻译合并在一起
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | parnas-a-rational-design-process.rst | 437 |
2 files changed, 440 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6781b2d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.html +*.bak +*~ diff --git a/parnas-a-rational-design-process.rst b/parnas-a-rational-design-process.rst new file mode 100644 index 0000000..671d997 --- /dev/null +++ b/parnas-a-rational-design-process.rst @@ -0,0 +1,437 @@ +理性设计过程 +============================================================ + +`Parnas and Clements. 1986. A rational design process: How and why to fake it. IEEE Trans. Softw. Eng. 12, 2 (February 1986), 251-257. <https://link.springer.com/content/pdf/10.1007%2F3-540-15199-0_6.pdf>`_ + +.. |date| date:: +.. |time| date:: %H:%M + +文件更新时间 |date|. + +.. contents:: 内容目录 + + +通篇总结 +------------------------------------------------------------------------- + +伍泰炜 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +读完全文之后,我感觉作者能把前面十几页的内容写出那么多字,真是十分了不起,可能这就是科研工作者的特长吧,把一个东西反复讲述,使得论文的篇幅变得很长,让人看起来好像内容很多。以下是我没有做第二遍阅读,单凭印象做出的理解。(而且我也相信第二遍和第一遍不会又很多改变) + +作者核心观点是,一个合理的设计过程需要写一大堆东西,比如“设计文档/需求分析/母子模型/接口说明”,这点写东西就在设计之初就开始写,在设计过程中每一次改变都要做清晰的更新。然而这是很难的,甚至一般都是不可能也做不到的,作者大人就说了,那就假装有一个。 + +有一个合理的设计过程有什么用呢?如果有的话,可以帮助开发过程中,有助于估算一个过程的时间金钱花费,减少重复做决策,减少大改的次数,方便后来人维护,防止人员变动地时候对接困难,等等。这些前提都是一个合理的设计过程的时候,没有的时候,或者说实施得不那么周全得时候,也不会有那么理想的辅助效果。 + +那么怎么假装呢?这篇文章写了很多,方法论式的表述,缺少举例——可能也很难举例,毕竟是理想状况——总之就是文档多花时间写。具体而言,在最开始的时候就照着自己理想的目标去写,不要去考虑实际实现的过程,防止后期忘掉了最开始的想法。开发的过程中,要秉持“write everything down”的原则,无论做什么决策改变或者修改,都要如实的写下原因。 + +在我看来能做到自然是一件很理想的事情,或许在一个长期的软件开发过程中,这是重要的。根据我的个人所见,比较多的开发者会写”change log/update log“之类的东西,这也算文档的一种,但是可能更面向用户一些。像这篇论文中的文档可能对于短期的私人的项目开发太繁琐了,也是有局限性的。 + +作者在最后几页分析一些他不认同的行为,比如各种文档软件做完了再写,写的文档要么意识流要么面向实现;或者是干脆文档很少,都靠代码注释。这样的文档会很难看懂,过多的注释也会导致后续的修改很麻烦(改了一个注释,还有多少注释要牵连呢?) + + + + + +Page 1 +------------------------------------------ + +徐梦旗 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +一个理性的设计过程:如何以及为何要仿制它 +摘要 +软件工程师们一直在探寻最为理性的软件开发过程:从技术规格中派生编程过程,无异于从已被发表的证明公理中导出前提与定理。 +本文在解释为何我们永远无法企及这一高度后,还将描述这样的一个过程。这个过程是,在软件设计的路上,如何根据一系列的文档来描述过程。 +我们也将展示诸如此类的文档产生的多方面的益处。它们不仅为初步设计提供了参考依据,还为编码过程充当了评审资料,也为维护程序员们的工作提供了技术指导。 +我们还将进一步探讨利用统一标准指导软件设计的文档是如何架构的。结果文档远远比通常产生的“事后考虑”文档更有价值。 +如果我们可以苦心孤诣地更新所有文档,那么我们就可以缔造一个相当理性的设计过程。 + + + +Page 2 +---------------------------------------------------------- + +田遍地 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +一个理性的设计过程:如何和为什么伪造它? + +DavidL.Parnas 加拿大维多利亚湾,维多利亚大学计算机科学系和美国华盛顿计算机科学和系统分支海军研究实验室,Paul C. Clements美国华盛顿特区计算机科学与系统科海军研究实验室。 +1.寻找哲人之石:为什么我们要一个理性的设计过程? + + + 一个理性的人总是有一个很好的理由来做他所做的事情。所采取的每一步都可以被证明是达到一个明确目标的最好方法。我们大多数人都认为自己是专业人士。然而,对许多观察家来说,通常的软件设计过程似乎是相当不合理的。程序员似乎经常在没有任何理由的情况下做出决定。他们一开始就没有明确说明他们要建设什么。他们做出了一系列的设计决策,但并没有清楚地说明为什么他们会以自己的方式做事。他们的目标从来没有明确过;他们的理由很少被解释。 + + 我们中的许多人对这样的设计过程并不满意。这就是为什么对软件设计、编程方法、结构化编程和相关主题进行研究的原因。理想情况下,我们希望从一个要求的陈述中导出我们的程序,在同样的意义上,定理是从公开的证明中的公理导出的。所有可以被分类为“自顶向下”的方法都是我们希望有一个理性的、系统的软件设计方法的结果。 + + + +Page 3 +----------------------------------------------- + +徐闰钞 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +所有可以被归类为“自顶向下”的方法都是我们希望有一种合理又系统的软件设计方法的结果。这篇文章既带来坏消息,也带来好消息。坏消息是,在我们看来,我们永远找不到哲学家stone。我们永远找不到一个能让我们以完全合理的方式设计软件的过程。好消息是我们可以伪造它。我们可以像是理性的设计师一样向别人展示我们的系统。还有一个好消息:这样做是值得的。 +二。为什么软件设计“过程”总是理想化? + + 我们永远不会看到一个软件项目按照上面的建议进行。部分原因如下: + 1。在大多数情况下,委托构建软件系统的人并不确切地知道他们想要什么,也无法告诉我们他们知道什么。 + 2。我们即使知道了需求,也还需要知道很多其他的事实来设计软件。许多细节只有在我们实施的过程中才会被我们了解,我们从中学到的一些东西会使我们的设计失效,于是我们必须回溯。 + 3.即使我们在开始之前就已经了解了所有相关的事实,经验表明,人类无法完全理解那些为了设计和建立一个正确的系统而必须考虑的过多的细节。设计软件是一个我们试图分离关注点的过程,因此我们将会处理大量可管理的信息。然而,在我们达到目的之前,我们必然会犯错误。 + 4. 即使我们能够掌握所有需要的细节,除了那些最微不足道的项目外的所有项目都会受制于外部原因而发生变化,其中一些变化可能会使以前的设计决策失效。 + + + +Page 4 +------------------------------------------------------------------- + +吴贞娴 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +5. 只有人类避免使用才能避免人类的错误。无论我们的决策过程多么理性,无论我们如何收集和组织相关的事实,我们都将会犯错误。 + +6. 我们经常被这些在相关项目中发现的或者是在课堂上听到的先入为主的设计思想所干扰。有时候我们会为了尝试一个喜欢的想法而去执行一个项目。这样的想法可能不是通过一个理性的过程从我们的需求中产生的;它们可能是自发地从其他来源产生。 + +7. 由于经济因素,我们经常被鼓励去使用一些其他项目开发的软件。在其他情况下,我们可能会被鼓励跟另一个正在进行的项目共享我们的软件。这会导致得到的软件可能不是这两个项目的理想软件,即我们不是只根据它的需求来开发的软件,虽然它已经足够优秀也能提高工作效率。 + +由于这些原因,软件设计人员以一种理性的、无错误的方式从需求中设计画面是非常不现实的。我们坚信有史以来没有一个系统以这种方式被开发出来,也许永远也不会有。即使小程序开发在教科书和论文中是不真实的。它们经过了修改和润色,直到作者向我们展示了那些他希望自己已做的事情,而不是实际发生的事情。 + +III . 为什么对理性理想化过程的描述是有用的呢? + +我们上文的描述是很浅显的,细心认真的思考者都了解,也被那些真诚的人所认可。尽管如此,我们还是看到了以软件设计过程为主题的会议、软件设计方法论工作组和旨在描述设计软件的逻辑方法的利润丰厚的课程市场。这些人想要实现什么? + + + +Page 5 +--------------------------------------------------------------- + +余慧 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +上文所提及的内容,很明显是被每个深思熟虑过的人均公认、坦诚的人所承认的。尽管如此,我们仍旧能看到以软件设计过程为主题的会议、研究着软件设计方法论的工作小组,以及为了丰厚的市场利益扬言能描述软件逻辑方法的课程。这些人想达到什么样的目的? + +如果我们已经能确定一个理想的过程,就算不能严格地执行它,我们仍然可以编写文档,说明我们在理想情况下产生的结果,这能使阅读文档的人将因参照这个合理的设计而受益。这就是我们所说的“假设一个合理的设计过程”。 + +下面,我们列出了这样自诩的几点理由: + + + 1. 设计师需要指导。当承担一个大项目时,我们很容易被任务的艰巨所压倒,不确定首先要做什么。对理想过程的良好理解将对项目的进行带来帮助。 + + 2. 如果我们试着遵循这一理想过程,而不是建立在一个临时决策的基础上, + 我们的进程一定程度上会更趋于完美,设计更趋于理性。例如,即使我 + 们不能知道设计一个理想系统所需的所有实际情况,但在开始编写代码 + 之前,尽力去理清这些事实的过程可以帮助我们更好地进行设计、减少 + 原地兜圈的错误。 + + 3. 拥有统一的标准,对一个承担许多软件项目的组织是有好处的。这会产 + 生好的设计评定方法,令人员、想法和软件在项目间的转移变得更加容 + 易。所以确定一个标准的过程,将它完善合理就似乎变得有理有据了。 + + 4. 如果我们已经就一个理想的过程达成一致,那么度量一个项目所取得的 + 进展就会变得容易得多。我们可以将项目的成果与理想过程所要求的成 + 果进行比较,来帮我们确定落后(或领先)的范围。 + + + +Page 6 +-------------------------------------------------------------------------- + +魏含饴 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +5.外部人员对项目进展情况进行定期审查会为形成良好的管理造成至关重要的影响。如果项目计划进入一个理想的进程,那么审查就会更容易进行。 +IV.开发过程的描述应该告诉我们什么? +我们相信对于开发过程描述的最有用形式是工作产品。对于过程的每一个阶段,我们都会进行描述: +-下一步我们应该做什么; +-工作产品必须满足什么标准; +-什么样的人能够胜任这项工作; +-他们会在工作中使用哪些信息; +任何无法描述的对工作产品过程的管理只能从精神方面被理解。只有当我们知道哪些工作产品是适当的,它们必须满足什么标准,我们才能审查项目并衡量进度。 +V.合理的设计过程是什么? +在本节中,我们将描述我们所遵循的合理的、理想化的软件设计过程。每个步骤都附有与该步骤相关联的工作产品的详细描述。以下过程的描述既不包括测试也不包括审查。这并不意味着我们忽视了其中的任何一个。在本文中,我们描述的是一个理想的过程;测试和审查属于实际的过程,而不是理想的过程。在应用本文描述的过程时,我们对每一个工作产品进行了广泛而系统的审查,并对生成的可执行代码进行了测试。 + + +Page 7 +--------------------------------------------------------------------- + +叶红霞 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +在实施本文描述的过程时,我们对每一个工作产品进行了广泛而系统的审查,并对生成的可执行代码进行了测试。 + +A.建立并记录需求 + +如果我们要成为理性的设计师,我们必须开始知道我们必须做什么才能成功。我们将其记录在一个称为需求文档的工作产品中。在我们开始之前完成这个文档,就可以让我们设计出所有面临的需求。 + +1.为什么我们需要一个需求文档? +- 在设计程序时,我们不太可能偶然随机地去做需求决策。 +- 我们将避免重复和不一致。没有这个文档,它回答的许多问题会在整个开发过程中被设计师、程序员和审稿人反复提问。这样花费会很昂贵,且易导致回答不一致。 +- 在系统上工作的程序员通常不熟悉应用程序领域。对于外部可见的行为有一个完整的参考可以让他们不必去决定什么是对用户最好的。 +- 对构建系统所需的工作量和资金进行良好估计是必要的(但还不够)。 +- 这是一种有针对人员流动成本的有价值的保险,当有人离开项目时,我们获得的有关需求的知识不会丢失。 +- 它为测试计划的开发提供了良好的基础。没有它,我们不知道该测试什么。 +- 它可以在系统就位后长时间使用,为将来的变更定义约束条件。 + + +Page 8 +-------------------------------------------------------------------------- + +王如韵 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +-它可以用来解决争议;我们不再需要成为或咨询应用程序专家。 +确定详细的需求很可能是这个过程中最困难的部分,因为通常没有组织良好的信息来源。理想情况下,它应该由未来使用它的用户来制作。事实上,它很可能是由软件设计师来设计的,而他们的想法必须得到用户的认可。 +2.需求文档中包含了什么?在理想化的设计过程中,需求文档内容的定义很简单:它应该包含编写正确软件所需的所有内容,仅此而已。当然,如果现有信息准确且组织良好,当然,我们可能会引用。好的需求文件的一般规则包括: +-每一项陈述声明应适用于所有可被接受的产品本身;而不应该依赖于可实现的决策。 +-文件应是完整的,就是说如果产品符合每一项陈述,则该文件应是可接受的。 +-在必须开始开发之前,如果没有可用的信息,则指出不完整的地方,而不是简单地省略。 +-该产品应该是由参考文件组织,而不是介绍系统,因为这是最有用的形式。虽然编写这样一份文件需要付出相当大的努力,而且比介绍系统更难于阅读,但从长远来看,它节省了人力,因为在这个阶段获得的信息是以一种便于在整个项目中引用的形式记录下来的。 + + + +Page 9 +--------------------------------------------------------------------- + +蒋佳玲 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +我们使用关注点分离来获得以下部分,从而在我们的需求文档中获得完整性: + +—— 软件必须在其上运行的机器的一种规格。这台机器不一定是硬件——对于一些系统,这一部分可能只是指向语言参考手册的指针; +—— 软件与外界通信必须使用的接口规范; +—— 对于每个输出,其值在任何时候都以系统的软件可检测状态表示; +—— 对于每个输出,软件需要多长时间或多快重新计算它; +—— 对于每个输出,它需要有多精确。 +—— 如果要求系统易于更改,则需求必须包含被认为可能更改的区域的定义。您不能设计一个系统,使所有的东西都同样容易更改,而且程序员不应该必须决定哪些东西最有可能更改。 +—— 需求还必须包含关于当系统由于不希望发生的事件而不能满足其全部需求时,系统应该做什么的讨论。大多数需求文档忽略了这些情况;他们讨论当一切都完美运行时将会发生什么,但是留给程序员决定在出现部分故障时该做什么。 +我们希望清楚地表明,除非定义了每一个需求,否则无法编写正确的软件,并且一旦您成功地指定了每一个需求,您就已经完全指定了系统的需求。 + + + + +Page 10 +---------------------------------------------------------------------------- + +应舸 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +为了确保文档的统一性和完整性,文档编写的组织过程背后必须有一个简单的数学模型。 +我们的模型是由我们在实时系统上的工作所激发的,但正因为如此,它具有完全一般性。 +所有系统都是实时系统。 + +我们假设对于实时控制系统,理想的产品不是纯数字计算机,而是由控制模拟计算机的数字计算机组成的混合计算机。 + +模拟计算机将输入测量的连续值转换为连续输出。当离散事件发生时,数字计算机带来模拟计算机计算功能的离散变化。 + +实际系统即是该混合系统的数字近似。 + +与其他工程领域一样,我们首先描述这个“理想”系统,然后指定允许的公差来编写我们的规范。 +在我们的需求文档中,我们认为输出的地位远高于输入。如果我们得到输出值是正确的,那么没有人会介意我们甚至采用不读取输入的方法。 + +因此,该过程第一阶段的关键是识别所有输出。 + +我们需求文档的核心可以被表述为表格形式的一组数学函数。每个函数都将单个输出的值指定为与应用程序相关的外部状态变量的函数。 +以这种方式生成的完整文档的一个例子,我们将在本文[9]中给出并在[8]中讨论。 + +B.设计和记录模块结构 +除非产品足够小,小到能由单个程序员生产,否则我们现在必须考虑如何将工作分成多项工作任务,我们称之为模块,应在此阶段生成的文档称之为模块指南。它通过陈述将由该模块封装的设计决策来定义每个模块的职责。 + + + +Page 11 +----------------------------------------------------------------------- + +徐焕众 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +模块可以由子模块组成,或者也可以被认为是单个工作任务。 + +我们需要一个模块指南来避免重复,避免空白,共同实现关注点的分离,以及 最重要的,来帮助一个无知的维护人员找出需要的模块当他有问题报告时必须处理时。再来,记录我们的设计决策的文档与我们在维护阶段使用的文档是相同的。如果我们只是努力地将信息隐藏或关注点分离应用于一个大型系统,那么肯定会产生大量的模块。一个没有其他结构,只是很简单的列出模块的向导,只会帮助那些已经熟悉系统的人。我们的模块是树形结构的,将系统划分成少量的模块,并以相同的方式处理每个模块,直到所有模块都非常小为止。举一个相关文档的完整例子:见[3J]。关于这一办法及其好处的讨论,见[15,6]。 + +C.设计和记录模块接口 + +高效和快速的软件生产需要程序员们能够独立工作。模块指南定义了需求与责任,但是它没有提供足够的信息来允许模块的独立实现。每个模块必须指定精确的接口。每个模块都必须编写模块接口规范;它必须是正式的,并提供每个模块的黑匣子图片。它们是由潜在的实现者与高级设计师一起编写的,并由使用这些界面的程序员一起评审。一个模块的接口规范只包含仅仅足够的信息供另一个模块的程序员使用它的设备,而不能做其他事。这也是系统所要求的。· + + +Page 12 +------------------------------------------------------------------------------ + +何可人 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +我们生产的文件由两者使用。 +虽然,每一此类文件都由一个人专门负责,但它们实际上是由那些负责实现这些模块的人,使用这些模块的人以及对这个模块的设计感兴趣的其他人,例如:评审,谈判产生的。这些规范的主要内容有: +- 一系列可被其他模块用程序(被称为“访问程序”)调用的的程序。 +- 这些访问程序的参数。 +- 这些访问程序对彼此的影响。 +- 必要时的时序约束和精度限制。 +- 不期望事件的定义(禁止发生的事) +在许多方面,这个模块的规格类似于要求文件。但是,符号和组织的使用更适合于我们在这个过程中所关注的软件到软件的接口。 +已发表的例子和解释包括[Ii],[2],[i],[5]。 + +D. 设计并记录模块的内部结构 + +一旦指定了模块接口,其实现可以作为独立任务被执行,但评论除外。但是,在我们开始编码之前,我们希望在模块设计文档中记录主要的设计决策。这个文档旨在开始编码前对设计进行有效的检验,并向未来的维护程序员解释代码背后的意图。 +在某些情况下,模块只是被简单地分成一个个子模块,而设计文档被当制作是另一个模块指南。在这种情况下,该模块的设计过程应在上面的步骤B处重新开始。而在其他情况下,我们首先应描述其内部数据结构; + + +Page 13 +------------------------------------------------------------------------------- + +袁世家 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +在另一些情况中,我们从描述内部数据结构开始;还有一些情况是,数据结构被子模块使用(和隐藏)。对于每一个访问函数,我们引用一种函数或者描述数据结构上的影响的LD关系。对于每一个模块所返回给使用者的数值,我们都提供了另一种数学函数,这个抽象函数将数据结构的值和其返回值一一对应。对于每一个不确定的事件,我们描述了怎样去检查它。最后,我们还提供了一种证明方法,这种使用此类性质来编程的观点可以满足模型的规格。 + +我们继续分解子模块,直到每个工作任务小到我们能够忽略它,并且当程序员离开该工程后可以继续工作。 +如果我们不能编写一个可读的高级语言,例如,如果没有可用的编译器,我们使用伪代码作为文档的一部分。我们发现由另外某个人写伪代码而不是最终的程序员写代码,并且让两个程序员负责两种代码的连贯性是很有用的。 + +E 设计并且记录使用层次结构 + +一旦我们知道所有的模型和它们的许可程序,就可以设计使用的层次结构。他被方便地记录为二进制矩阵,当且仅当位置(a,b)的入口为真,程序A的正确性取决于系统中是否存在正确的程序B。使用层级结构定义了可以由删除整个程序并且没有重写任何程序获得的子集。这对于分阶段递交,故障弱化系统,和程序集合的发展很重要。 + + + +Page 14 +------------------------------------------------------------------------------ + +陈肖飞 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +F. 编写程序 + +在所有这些设计和文档编制完成后,我们已经准备好可以编写实际的可执行代码。 +我们发现这件事进展的迅速而顺利。我们认为,代码不应该包含与已经编写好的 +文档相冗余的注释。这没必要的,并且会使系统的维护更加昂贵,同时增加了代 +码与文档不一致的可能性。VI.文档在这一过程中的作用是什么?A. 当前的文 +档有什么问题?为什么它不便使用?为什么它晦涩难懂? + +很明显,文档在我们描述的设计过程中扮演着重要的角色。大多数程序员认为文 +档是一种必要的累赘,是在事后才做的,只是因为有些官僚需要文档。但我们认 +为,在发布之前都没有使用过的文档一定是糟糕的文档。 + +大多数文档是不完整和不准确的,但这些并不是主要的问题。如果是的话,只要 +简单地添加或者纠正信息就可以纠正它们。事实上,有一些根本的组织问题才是 +导致不完整和不准确的原因,而且这难以修复: + +糟糕的组织。今天的大多数文档可以被描述为“意识流”和“执行流”。意识流写作 +将信息放在作者写作的时候突然想到的那个点上。执行流描述了系统在运行时发 +生的事情的顺序。 + + + +Page 15 +---------------------------------------------------------------------------- + +陈俊蕾 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +这(文档多余的注解)是没必要的,且会使系统维护变得更加昂贵。除此之外,还会增加代码与原文档不符的可能性。 + +文件在此过程中充当什么样的角色? + +通常的文档到底哪儿出错了呢?为何如此难使用?为何不可读? + +这应该被清晰地认识到,在我们描述的过程中文档扮演着一个重要的角色。许多程序员事后回想起都视这种文档为一种不可避免的不幸。它们(文档)被书写只为应一些官僚的要求。我们相信那些在发布前未被使用的文件都将是错误的文件。 + +大多数文件是不完整、不精确的,但这些都不是大问题。如果是,那么可通过添加或修改信息进行简单的修正。事实上那些潜在的、组织上的问题,所引发的不完整和不正确是没那么容易修复的。现如今的文档,可根据其特点分为“意识流”和“执行流”两种。意识流的作者会在每个灵感闪过的瞬间记录所有点的内容。而执行流的作者会根据事件发生的顺序去描述系统。 + +这两种书写文档的风格共同存在一个问题,就是:除了作者本人之外,其他人将难以找到他们所寻找的信息。这会使得判定信息是否丢失或者信息是否出错变得不那么容易;也会使得软件修改时,找到所需修改的所有文档内容变得不那么容易。 + + + +Page 16 +------------------------------------------------------------------------------ + +王海榕 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +如何避免这些问题? + +文档在理想的设计过程中满足了开发人员和后期维护程序员的需求。上面提到的 +每个文档都记录了设计决策,并作为设计其余部分的参考文档。但是,它们也提 +供了维护人员所需要的信息。由于这些文档在整个软件构建过程中都被用作参考 +手册,因此它们将是成熟的,可以在以后的工作中使用并且始终是最新的。我们 +设计过程中的文档不是事后才想到的;它被认为是项目的主要产品之一。可以使 +用一些检查来增加完整性和一致性。这种文档处理方法的一个主要优点是改善了 +神话中的人月效应[4]。当新程序员加入项目时不需要依赖老员工为他们提供项 +目信息。他们将拥有一个最新的和理性的可用文档集合。我们通过花费大量精力 +设计每个文档的结构来避免“意识流”和“执行流”文档。我们通过声明文档必须回 +答的问题来定义文档并将这一原则贯彻到各个部门。我们试图为每一个必须包含 +的事实找到一个位置,并确保只有一个这样的位置。只有在确定了文档的结构之 +后,我们才开始编写它。如果我们编写许多特定类型的文档,我们就为这些文档 +编写并发布一个标准组织[5]。我们所有的文档都是按照指导软件设计的相同原 +则设计的,即关注点分离。系统的每个方面都在一个部分中描述,而在该部分中 +没有其他内容。当审查我们的文件时,我们会审查它们是否符合文件规则以及是 +否具有准确性。 + + + +Page 17.a +-------------------------------------------------------------------------------- + +周佳威 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +这样生成的文档既不简单也不轻松,但也不枯燥。我们利用表格、公式和形式符 +号来增加信息的密度。我们的组织规则防止了信息重复,其结果是文档化,必须 +非常认真地阅读,但回报读者详细和准确的信息。为了避免传统文档中出现混淆 +和不一致的术语,我们使用了特殊括号和类型化字典系统。我们必须定义的许多 +术语中的每一个都包含在一对显示其类型的括号符号中。对于每个这样的类型, +我们都有一个只包含该类型定义的字典。虽然刚开始阅读的读者会发现!+terms+l、 +%terms%、#terms#等符号的存在,但是令人不安的是,像我们这样文档的普通用 +户会发现括号中隐含的类型信息使文档更容易阅读。使用由类型构成的字典使我 +们不太可能为同一个概念定义两个术语,或者为同一个术语赋予两个含义,同时 +特殊的括号符号使对已介绍但未定义或已定义但从未使用过的术语进行机械检查 +变得很容易。现在,我们如何伪造理想过程? + +上面描述了我们希望遵循的理想流程以及在此流程中生成的文档。我们通过生成 +文档来伪造这个过程,如果我们以理想的方式做事,就会生成这些文档。我们试 +图按我们所描述的顺序制作这些文件。如果我们不能得到一条信息,我们就会注 +意到在文档的一部分中,信息应该去哪里并继续设计,就好像该信息会按照预期 +发生变化一样。如果发现错误,我们将更改它们,并在随后的文档中进行相应的 +更正。我们将文档作为设计的媒介,在所有级别的设计决策都被批准纳入文档之 +前,不会考虑任何设计决策。无论我们在途中遇到多少困难,最终的文档都将更 +容易理解和适应。我们没有展示事情实际发生的方式,我们展示的是我们希望事 +情发生的方式和事情的方式。 + + +Page 17.b +----------------------------------------------------------------------------------- + +方梓安 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +vii.那么,我们如何伪造理想的过程呢? +前面的内容描述了我们希望遵循的理想过程以及在这一过程中将产生的文件。如果我们以理想的方式完成了工作,那么我们就可以通过生成文档来伪造流程。我们试图按照我们所描述的顺序提出文件如果我们不能得到一条信息,我们注意到在文档中信息应该放在哪里的部分,并继续设计,就好像97条信息预期会发生变化一样。如果我们发现错误,就会更改它们,并在后续文件的相应改动。我们将文档作为设计的媒介,在将文档纳入文档之前,不会考虑作出任何设计决策。在各个层面都证明了,不管我们经常在中途遇到什么问题,最终的文档都会更容易理解和准确。我们不展示事情发生的方式,我们展示我们希望它们发生的方式,以及事情发生的方式。甚至数学——我们中许多人认为最理性的学科,也遵循这个过程。数学家们孜孜不倦地完善他们的证明,通常提出一个与他们发现的第一个非常不同的证明。第一次证明往往是一个痛苦的发现过程的结果。当数学家研究证明,理解生长和简化被发现。最后,一些数学家找到了一个更简单的证明,使定理的真实性更加明显。简单的证明之所以出版,是因为读者对定理的真实性感兴趣,而不是发现它的过程。我们认为类比推理更适用于软件。 在那些阅读软件文档的人想要理解这个程序,而不是重温他们的发现。通过提供合理的文档,我们提供了他们需要的东西。我们的文档在一个重要的方面不同于理想化的文档。我们制造了一个记录我们所有采纳和排除的所有备选方案,包括记录在文档早期版本中的决定。对于每一个问题,我们都解释了为什么它被采纳,为什么它最终被排除。几个月,几个星期,甚至几个20年后,此软件的维护者将有许多相同的问题,他将在我们的文件中找到答案。 + + + +Page 20 +---------------------------------------------------------------------------------- + +刘莉莉 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +从这个过程得到回报的例证是由我们几年前写的软件需求文档提供的,其作为理 +想过程演示的一部分[9]。通常,人们认为需求文档在编码开始之前就生成了, +并且不会再使用它。然而,事实证明并非如此。那些满足我们的要求文件的软件, +它的原始版本仍在进行修订。每次更改后就必须测试软件的组织,都会广泛使用 +我们的文档来选择他们所做的测试。当需要进行新的更改时,需求文档用于描述 +那些必须更改的内容和不能更改的内容。在软件投入使用后,该过程中生成的第 +一份文件一直被使用了很多年。可以明确的是,如果一个文档是经过精心制作的, +那么它将在很长一段时间内发挥作用。相反,如果它将被广泛使用,那么正确的 +制作是值得的。成为一个理性的设计师是非常困难的,而且我们可能永远不能实 +现它。在我们尝试遵循这个过程的过程中,我们经常发现我们继承了一个由于未 +知原因而做出的设计决策的地方。例如我们想要使用的等式中常量的值。当我们 +要求推导常量时,我们发现它不存在或推导无效。当我们进一步按下时,我们被 +告知该决定是“因为它有效”。在这种情况下,设计师可以打开一个研究项目,找 +出它的工作原理,或者只是“继续使用它”。那些为我们工作付钱的人已经使用 +“GOWI”这样的标准回答去解决许多此类问题,并且我们并不认为真正的工作会有 +所不同。然而“因为它们起作用”,所以无论我们做出哪些决定,我们都会对我们 +的决定记录诚实的理由,而不是误导未来的维护者认为我们对我们所做的事情有 +深刻的哲学理由。 |