产品质量的核心——概念的完整性

产品质量的核心——概念的完整性

——读《人月神话》有感

转眼本学期已进入尾声,通过十几周对于“软件工程概论”这门课程的学习,我对软件开发的实现过程也有了一定程度的认识和了解。在此环境下,为了能够更好地理解和学习软件工程项目知识,也为了储备专业知识以应对之后的工作需求,通过查阅我接触到《人月神话》这本书——一本在发行四十年之后仍然继续流行、在软件管理领域堪称经典的著作。

《人月神话》的作者Brooks在这本书中总结了自己在IBM公司任职项目经理时的实践经验,他详细地阐述了自己在软件项目开发过程中独到的见解,以及亲身经历的实践性内容。在 《人月神话》中,既有很多值得我们学习并思考的观念,又有大量软件工程实践者的自身经验,同时也为现实中的每个遇到困惑的实现者提供了自己真诚的意见和建议。其中最重要的一点,也是软件工程实现过程中的矛盾所在,那就是人力划分的问题对项目进程所带来的极深影响,从而偏离最初的用户需求,开发进程效率大大降低。所以,建立及怎样保持系统自身的概念完整性是一个我们即将要讨论的命题。

由此,确定了“本质”的重要地位。要想解决问题,首先要试图去理解问题的本质是什么,紧接着根据其本质进行需求分析,按照合乎实际的人力资源分配去实现目的。但在这个过程中,具体的实现步骤还是有着大大小小层出不穷的问题。若是将大型的软件工程设计研究比作一个焦油坑,各种团队就好像在其中不断地挣扎,虽然最终他们中的大多数都开发完成了软件并且可以成功的运作,但问题是只有很少的作品满足了最初的定义,预期的时间进度和要求。原因是什么?每一项分工出现了各自的问题,纠缠在一起就使整个团队的合作偏离了轨道。由此可见,难以看清事物的本质、无法进行准确的需求分析以及合乎实际的人力资源分配,是项目工程结果不如人意的症结所在。

人月神话”究竟是什么

我们先来说说这本书的题目——《人月神话》。所谓“人月”,就是在估计和进度安排中使用的工作量单位。作者Brooks在书中也给出了几种不同环境条件下的“人员与时间之间的关系”曲线,这些二维曲线可以直观的表现出人力的增加如何影响着项目的时间进度。在此之前我们需要先搞明白,在软件项目开发过程中,造成工程滞后的最主要原因就是没有合乎实际地对时间进度进行安排。

简单地说一下这种现象是如何产生的。首先,我们并没有仔细地研究估算,也就是下意识地认为:在之后的进程中运作会顺利地进行。殊不知真正的实现过程中,问题层出不穷,尤其是项目人员之间的交流,其中的不确定因素也不是我们可以预料到的。其次,隐含的假设认为,“人”和“月”二者可以互换,将“进度”和“工作量”两个概念划上了等于号,也就直接导致当我们发现进度有所偏移时,自然的反应就是添加人力。这就回到我们之前所讨论的“人月神话”中,作者认为,用“人月”关系去作为工作的规范标准仅仅只是一个流传已久且不真实的神话而已,它恰恰说明了一个广泛错误的认知:那就是可以将时间进度的快慢等同于人力资源的多少。

那么,到底什么情况下我们可以将人数和时间互换呢?例如,一个项目可以在同一水平段同时分解给实现者,当然,其中的交流自然是不必要的,独立完成之后就意味着整个工程的建立。而在实际编程情况中,这几乎是不可能的。如果是不能分解的任务,毋庸置疑地,增加人力对时间进度不会有丝毫影响,因为这种软件开发具有调试和测试的先后次序特性。我们再来讨论同样是可以分解、但项目人员之间需要沟通的流程,因而我们必须考虑其中的交流所产生的成本,此时增加人力似乎并不能起到什么作用。在此基础上,若是人员之间的交流关系更为复杂一些,最后人力的增加只会使时间进度越来越来久,因为从本质上来说明软件系统开发,是一项多人参与、涉及层面较广且清晰的合作性活动——在盘根错节的网状关系下的一种实践性内容。如果存在很多的沟通和交流,会消耗大量个人时间。这样,人力资源的添加,只能是拖延了而不是加速了时间进度。

最后我们简单地总结一下 Brooks的观点,那就是:向进度落后的项目中添加人力 ,无疑会使进度更加落后。次序的特性决定了项目的时间,分解的项目数量也决定了人力资源的多少。通过这两个数值我们大致可以估计出时间进度,人员少,花费时间长,时间进度也就越可靠;相反,人员很多的话,只可能缩短计划的时间,将降低进度的可行性。总之,在系统开发过程中,没有合乎实际地对时间进度进行安排,极大程度的造成了项目拖延无法完成,这个原因也几乎起着决定性的影响。

项目的最基础行为——编程

抛去整个工程,单单对程序员的工作来讲,他们还是可以感受到职业所带来的愉快。创建一种事物、全程自主设计本身就是一种很纯粹的喜悦,而恰好我们所设计的产品对别人来说有所帮助。最令人兴奋的是,在运行过程中所展现的“神奇”力量——一个程序顺畅编译后得到的结果完全符合期待。我们从中学到很多,无论是实践上还是理论上,都对我们之后的工作打下了完美基础。但是,愉快并不能占据全部,编程的固有烦恼一直存在。通过C++和Java语言的学习与练习,我们都知道,关于数据结构的语法是极力要求完美的,也就是说在语法上出现了一点点错误,整个程序就无法编译成功。最后,寻找琐碎的bug也是一件令人头疼的事情,第一个bug很好解决,然而往往最后一个是最费时费力的。

这就是编程,许多人在这个大的“焦油坑”里奋起挣扎,但它也同时体现着无穷的乐趣与烦恼。

工程的必要组织——团队

作者认为,成本的主要组成是由沟通所产生的,也就是说,交流的人员越多,成本也会相应地增加。从这一点来看,系统开发所需要的人应该尽量少才对。而且实际上,许多大规模的开发经验也显示,很多人聚集在一起很容易降低概念完整性的效率,造就高成本,但易用性极低的产品。

可见要想最大程度的确保概念的完整性,交给少数逻辑清晰、思维精炼的人员来设计和开发是再好不过。但是对于大型的开发项目,充分的人力资源是不可或缺的,从而保证产品可以在恰当至少是规定的时间内完成。那么我们该如何在这两方面的矛盾中寻求一座天平呢?

这本书中,作者推崇了一种具有创造性的团队构建的解决方案。总结性的来说,就是一个项目由不同团队所分别承包,但不是一拥而上,而是类比于外科手术队伍的方式,问题的剖析由一个人来进行,其余人提供辅助需求,完全配合以提高效率。

简单地说一说团队中具体有哪些角色:

外科医生,类比为首席程序员。他亲自编写源代码,并决定功能和性能要求。

副手,首席程序员的后备。他可以完成任何一项任务,明确每一项的实现步骤,但相对来说经验较少。这样说,副手作为首席程序员的保险机制,不会限制程序员的设计,同时也不会为具体的开发承担责任。

管理员,帮助首席程序员进行关于财务、人员、工作安排等方面的专业管理。同时管理员也需要一名秘书,辅助其保证项目的一致协作。

编辑。和一般我们所认识的编辑相同,软件项目团队中的编辑也是将中心主旨思想——首席程序员所产生的文档,进行分析后重新组织按条理整理成章,也需要一名秘书辅助工作。

程序职员,对每个团队的技术记录进行维护。由此,程序员可以不用再为书记的杂事而费神,从而使其因程序职员的专业化分工而得到系统规范的整理,团队的工作产品也得以强化。

工具维护人员。作为亲自设计程序、编制源代码的首席程序员,毫无疑问地成为了判定各种工具可靠性的唯一人选。既然如此,他需要一人来保证其所使用到的工具的可靠性和高效性,并且承担起特殊工具的维护和升级责任。

测试人员。正如科学家需要大量的实验及其结果来使研究更加精准,程序员也要用到大量的测试用例。那么承担起这一项工作的便是测试人员了。

语言专家。在我看来,这可谓是首席程序员所拥有的点金石了。在进行系统的设计和整体的构建时,遇到复杂棘手的问题,通常会交给语言专家这样的天才去解决,他通过学习之后会寻找一种简洁、有效的使用语言的方法来为程序员服务。

这就是类比于外科手术队伍所构建的团队,对编程团队中的10人有了明确的、专业的角色分工。

项目的决策行为——系统设计

在计算机的系统开发设计中,常常会出现概念性的差异以及设计的不一致性。此时是因为,设计被“分解”了,也就是交由若干人去完成若干任务,导致这些独立又无法整合的碎片彻底丢掉了概念的完整性。

所以,在系统设计中所需要迈出的第一步就是确保概念的完整性。那么,如何获取概念的完整性就承担起了关键性的作用。对于用户所提出的需求,我们的设计应达到最简洁的表现方式。但是只有简洁是不够的,要表达一件我们准备完成的工作,往往需要对既有的元素进行类似于概率论中所提到的“排列组合”。而且,不仅是了解元素和排列组合的规则,我们还需要学习晦涩的用法,以及怎样使其在实际的设计开发过程得到应用。为什么说概念的完整性体现在易用性上,因为完整性的体现方式是简洁和直白的,每个部分都必须映射出相同的规则和原理,这也暗示着每个部分都应使用相同的语法技巧,同时也具有相似的语义。

体系结构与具体实现

那么,结构与实现又有着怎样的关系呢?

设计应该由一个人来实现,当然,如果少数几个人互有默契也是完全可以的。但是在具体的实现进度中,却需要很多人来开发研究。如何正视并解决这个矛盾,最主要的依旧是上述的构建团队的新颖法则——外科手术队伍,而我们现在所说的系统设计也正是建立在这种形式之下的。

就大型的开发项目来讲,要想强有力的获取概念的完整性,需要将结构的设计与其实现过程分离开来。首先,什么是体系结构?就是既完整,即符合并满足用户的需求、又详细明确的用户接口说明。分为几部分来说,在计算机中它就是编程手册,在编译器中就是语言手册,而对于控制程序,即语言和函数调用手册。当用户接触到它时,便是承担着对于整个系统完成所有工作所需要参考的手册集合的作用。可以这样说,某种程度上系统结构师就是用户的代理人。

接下来我们需要仔细地区分体系结构和具体实现过程,体系结构的主要工作是描述发生了什么,而实现则是要明确如何发生。既然要区分,那是不是说明实现人员就只能一味地按照结构师的要求一步步地走,却不能提出其他的建议?答案自然是否定的,因为新的亮点往往是由实现者和用户所提出的。但是,我们设计的原则是确保概念的完整性,因为其关乎用户的需求,也就直接决定系统的易用性。如果说在实现过程中出现了很多有特色、但无法与系统概念良好地整合在一起的想法,我们就只好摒弃了。所以,既然说系统结构师是用户的代理人,那就表示着他们为用户处理解决问题,并处于实现用户利益的核心地位。这样一来,结构师控制了系统概念的完整性,按作者的话来讲,这是一种无需任何歉意的贵族专制统治。

然而,这种“贵族统治”并不是说明在实现过程中不需要实现者的创造力。前面提到我们要仔细地区分体系结构和具体实现,也就是说二者可以看做两个独立的创造性活动,只是性质不同。如果已经确定了体系结构,实现者一样要具备如同建立架构一样的创造性思维。实际上来说,实现人员的创造力体现在产品的成本及性能,就好像结构师在主导着产品系统的易用性。

三者并发执行

我们所进行的开发项目实际上可以整合为三个独立阶段的创造性活动: 体系结构的构造、物理实现过程和设计实现过程。在现实过程中,三者能够并发的进行。举个例子,在计算机的设计研究中,当设计实现人员有了对概念实现的模糊设想,对实现技术有了逻辑相对清晰的构思,并且大致估计了成本后就可以开始工作了。同时,在物理实现的方面, 能够同体系的构造及设计实现同时进行。在我们的系统开发项目过程中,也是同样的道理。

既然要确保概念的完整性,那么系统的设计理念就是统一的,也就是说只有少数人的思想决定了最终的说明。我们的工程被分解为三个独立的阶段,但这并不意味着需要更多的时间来完成它。作者所揭示的经验显示,由于明确的区分,开发项目的速度将会变得更快,且测试时间也会更少。由此,概念完整性得到极大幅度的提高。

至此,我们终于明白,在软件工程,甚至是其他复杂的实践活动中,概念完整性是怎样处于至关重要的地位。最大程度地保证概念完整性,也正是这篇文章的核心内容。一个令人称心又成功的系统产品必须向使用它的用户提供逻辑明晰的模型,这个模型描述了如何使用系统产品的操作步骤以及各种有效参数。也就是说,用户所感受到的产品概念完整性完全可以体现在易用性上来。

最后,软件系统的设计应该算是创造性活动中盘根错节、最复杂的一项。这是一个以不断更新变化为特点的行业,在满足着人们日前需求的同时,更多的创新思维接踵而至,所以说其唯一不变的就是在不断地变化。现实挑战着开发人员的脑力,实现者同时也在改变世界。既然如此,进行持续的发展、不断学习和完善并且勇于突破是我们一直要做的事。

希望我们都能够从《人月神话》这本经典著作中有所收益,以及从这些问题中获取意义和价值。

时间: 06-05

产品质量的核心——概念的完整性的相关文章

Hadoop hdfs&mapreduce核心概念

1.HDFS(分布式文件系统体系) 1.1.NameNode:(名称节点) Hdfs的守护程序 记录文件是如何分割成数据块的,以及这些数据块被存储到了哪些节点上 对内存和I/O进行集中管理 是个单点,发生故障将使集群崩溃 1.2.SecondaryNamenode(辅助名称节点):发生故障进行人工的设置才能实现集群崩溃的问题 监控HDFS状态的辅助后台程序 每个集群都有一个 与NameNode进行通讯,定期保存HDFS元数据快照 与NameNode故障可以作为备用NameNode使用 1.3.D

CSS的四个核心概念

CSS(Cascading Style Sheet)层叠样式表,又称级联样式表,是一组格式设置规则,用来进行网页风格设计.通过使用CSS样式设置页面的格式,可将页面的内容与表现形式分离.页面内容存放在HTML文档中,而用于定义表现形式的CSS规则则存放在另一个文件中或HTML文档的某一部分,通常为文件头部分.将内容与表现形式分离,不仅可使维护站点的外观更加容易,而且还可以使HTML文档代码更加简练,缩短浏览器的加载时间. CSS的核心概念有四个:标准流.盒模型.position.float,它们

Maven的几个核心概念

POM (Project Object Model) 一个项目所有的配置都放置在 POM 文件中:定义项目的类型.名字,管理依赖关系,定制插件的行为等等.比如说,你可以配置 compiler 插件让它使用 java 1.5 来编译. 示例的 POM: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  

C#面向对象的核心概念

一.面向对象的核心概念 (一)抽象--面向对象的根基 讲到抽象,不得不涉及到现代科学技术的基础--数学. 数学是一门抽象的科学,面对着纷繁复杂的世间万物,数学不理会各种事物的独特特性,而只抽取它们在数量上的特性,深刻揭示了"世间万物"在数量上表现出的共同规律,抽象正是数学的本质特征. 数学的一个分支--离散数学是计算机科学的根基之一,因此,计算机科学从诞生之日起,就与数学有着密不可分的联系,抽象思维也是计算机科学的主要思维方法之一. 在使用面向对象的方法设计一个软件系统时,首先就要区分

Angularjs的核心概念

1. 客户端模板 多页面的应用通过组装和拼接服务器上的数据来生成HTML,然后输出到浏览器.Angularjs不同于此的是,传递模板和数据到浏览器,然后在浏览器端进行组装.浏览器的角色编程了只提供模板的静态资源和模板所需要的数据. <html ng-app> <head> <script src="angular.js"></script> <script src="controllers.js"><

面向对象的核心概念

1.面向对象的核心概念 从理论上说,面向对象技术拥有四大基本特性. (1)封装 这是一种隐藏信息的特征.封装这一特性不仅大大提高了代码的易用性,而且还使得类的开发者可以方便的更换新的算法,这种变化不会影响使用类的外部代码.可以用以下公式展示类的封装特性: 封装的类=数据+对此数据所进行的操作(即算法) 通俗的说,封装就是:包起外界不必需要知道的东西,只向外界展露可供展示的东西. 在面向对象理论中,封装这个概念拥有更为宽广的含义.小到一个简单的数据结构,大到一个完整的软件子系统,静态的如某软件系统

理解maven的核心概念

原文链接:http://www.cnblogs.com/holbrook/archive/2012/12/24/2830519.html 好久没进行java方面的开发了,最近又完成了一个java相关的任务,顺便重新体会了 maven 这一利器. 在使用过程中发现以前对maven的理解不够深入,借此机会重新梳理了一下maven的核心概念.相信理解了这些核心概念, 即使长时间不使用,以后再重新上手也会非常容易. 本文以类图的方式,介绍maven核心的12个概念以及相互之间的关系. Table of

Docker核心概念

Docker的三大核心概念 镜像 容器 仓库 1.Docker镜像 Docker镜像类似于虚拟机镜像,可以将它理解为一个面向Docker引擎的只读模板,包含了文件系统.镜像是创建容器的基础.通过版本管理和增量的文件系统,Docker提供了一套十分简单的机制来创建和更新现有的镜像,用户甚至可以从网上下载一个已经做好的应用镜像,并通过简单的命令就可以直接使用. 2.Docker容器 Docker容器类似于一个轻量级的沙箱(沙箱是一个虚拟的环境,在这份环境运行的程序都是独立的,不会对你的现用操作系统造

领域驱动设计(DDD)部分核心概念的个人理解(转)

领域驱动设计(DDD)是一种基于模型驱动的软件设计方式.它以领域为核心,分析领域中的问题,通过建立一个领域模型来有效的解决领域中的核心的复杂问题.Eric Ivans为领域驱动设计提出了大量的最佳实践和经验技巧.只有对领域的不断深入认识,才能得到一个解决领域核心问题的领域模型.如果一个应用的复杂性不是在技术方面的,而是在领域本身,即领域内的业务很复杂,那这种应用,使用领域驱动设计的价值就越大. 领域驱动开发也是一种敏捷开发过程(极限编程,XP),强调迭代开发.在迭代过程中,强调开发人员与领域专家