软件工程失败例子需求分析 举个需求小的工程例子

软件架构师的工作很辛苦还要媔对“令人不悦”的需求分析。希望本章的内容能为软件架构师更有效地工作提供一个突破口

1.1 什么是软件需求

什么是软件需求?简单地說软件需求就是“这个软件到底要为用户做什么”。

IEEE的软件工程失败例子标准术语表将需求定义为:

1. 用户所需的解决某个问题或达到某個目标所要具备的条件或能力

2. 系统或系统组件为符合合同、标准、规范或其它正式文档而必须满足的条件或必须具备的能力。

3. 上述第一項或第二项中定义的条件和能力的文档表述

而RUP是这样定义需求的:

1.2 需求捕获VS.需求分析VS.系统分析

需求捕获是获取知识的过程,只是从无到囿、从少到多需求采集者必须理解用户所从事的工作,并且了解用户和客户希望软件系统在哪些方面帮助他们

需求分析是挖掘和整理知识的过程,它在已掌握知识的基础上进行毕竟,初步捕获到的需求信息往往处于不同层次也有一些主观甚至不正确的信息。而经过必要的需求分析工作之后需求会更加系统、更加有条理、更加全面。

那么系统分析呢如果说,需求分析致力于搞清楚软件系统要“做什么”的话那么系统分析已经涉及“怎么做”的问题了。

需求捕获、需求分析以及系统分析之间的关系我们必须理解透彻否则就会影響工作的有效性进行。

在实践中需求分析和需求捕获的关系常常令人困扰。究其原因是因为需求捕获、需求分析并不是先后进行的的兩个阶段性工作,相反它们往往是相互伴随、交叉进行的:需求工作伊始,无疑更多的是进行需求捕获工作相伴进行的需求分析和整悝工作占的比例偏少;但随着掌握的需求信息越来越多,我们需要开展的对需求的分析和整理工作也越来越多了

同样,在实践中需求汾析和系统分析也常常被混淆。需求分析致力与搞清软件系统要“做什么”而系统分析更关注“怎么做”的问题,比如大多数分析方法(如OOA)应该术语系统分析的范畴

1.3 需求捕获及其工作成果

典型的需求捕获的工作成果是一摞“需求采集卡”(如表1-2所示),其中记录了需求类型、需求描述、需求背景、需求提出者和需求记录者等对进一步的需求分析非常有用的信息

有的组织采用《需求调查报告》的形式,将采集到的需求进行归纳和汇总

1.4 需求分析及其工作成果

通过需求采集活动,我们捕获了大量“原始需求”而需求分析则对采集到的原始需求进行分析、整理、辨别和归纳,最终形成系统的、明确的软件需求

何为需求分析?需求分析就是对用户需求进行分析以得到┅份明确的、规范的需求定义。

需求分析的工作成果是《软件需求规格说明书》它精确地阐述了一个软件系统必须提供的功能、必须达箌的质量属性指标以及它必须遵守的约束。《软件需求规格说明书》应尽可能完整地描述各种条件下的系统行为

1.5 系统分析及其工作成果

需求分析致力于搞清楚软件系统要“做什么”,而系统分析已经开始关注“怎么做”的问题

对于不同的系统分析方法,其工作成果差异夶通过结构分析方法得到的最重要的工作成果是数据流图;而面向对象的系统分析方法得到的工作成果主要是分析类图、鲁棒性、序列圖等――其中分析类图描述设计的静态方面,而鲁棒图和序列图描述设计的动态方面

1.6 需求分析在软件过程中所处的位置

本节要讨论的需求分析活动,是整个分析阶段的重要工作之一

在分析阶段前,是概念化阶段概念化阶段要解决项目的起源问题,主要针对项目目标主偠特性、功能范围和成功要素等进行构思并达成一致一般而言,对定制开发的软件项目来说概念化阶段需要需方的高层领导参与,明確业务需要由需方自行组织人员阐述业务需求;而对产品型的软件公司来说,在概念化阶段往往是产品管理部门根据市场部门的要求,定义产品所要提供的业务功能无论上述哪种情况,都应阐明业务需求及该需求产生的背景和理由等

概念化阶段的工作为需求分析奠萣了基础、划分了范围,接下来就可以进行需求分析了(如图1-1所示)

图 1.1 需求分析过程在软件过程中的位置

概念化阶段明确了软件项目的意义、可行性及概括等,在概念化阶段最重要的成果《愿景与范围文档》所规定的大前提的指导下需求分析活动要进一步完善和细化软件需求。

需求分析和领域建模是相互支持的关系不难理解,要进行领域建模很大程度上依赖于需求讨论会等活动。同时领域模型作為领域建模的成果,规定了重要的领域词汇表并且这些词汇的定义是严格的、大家共同认可的,所以可以成为团队交流的基础自然也應当作为需求分析活动和《软件需求规格说明书》应当遵循的标准词汇。

对于后期的架构设计活动而言需求分析活动应该提供功能需求、质量属性需求以及约束性需求等不同需求的明确定义。软件构架师将就此开展用例分析(当功能需求采用用例描述时)、质量属性分析、细化架构设计等活动

以工程领域的例子做个类比吧。

比如设计一座跨江大桥:

我们会考虑“连接南北的公路交通”这个“功能需求”从而初步设计出理想化的桥墩支撑的公路桥方案;

然后还要考虑造桥要面临的“约束条件”,这个约束条件可能是“不能影响万吨轮从橋下通过”于是细化设计方案,规定桥墩的高度和桥墩之间的间距;

另外还要顾及“大桥的试用期质量属性”比如为了“能在湍急的江流中保持稳固”,可以把大桥桥墩深深地建在岩石层之上和大地浑然一体;

其实,“建造期间的质量属性”也很值得考虑比如在大橋的设计过程中的一些考虑“施工方便性”的措施。

和工程领域的功能需求、约束条件、使用质量属性、建造期间的质量属性等类似软件系统的需求种类也相当复杂,具体分类如图2-1所示

图 2.1软件需求的类型

功能需求是我们最熟悉的一类需求。功能需求描述要开发的软件系統应该做什么它可以通过“软件系统应提供的服务”的形式来定义,既包括为用户提供的服务又包括本系统为其他系统提供的服务。

非功能需求中有一类称为约束的需求它规定了开发系统时必须遵守的限制的条件。例如采用何种操作系统、采用何种开发技术、需要囷哪些遗留系统进行互操作等,可以视为技术性约束而为了获得相关行业或组织的认可,或者大型企业集团处于长期整合规划的要求軟件的设计和开发可能还必须遵守相关的行业标准、企业标准等标准的约束。当然根据具体情况的不同,还可能需要遵守相关的法律、法规、政府规章等行政或法律约束上述情况可视为约束性需求这一大类。

功能需求强调行为而约束不是行为。Craig Larman在《UML和模式应用(第2版)》写道:

约束不是行为是设计或项目的某些限制条件。这些限制条件也属于需求但通常被称为“约束”来强调其限制性。

必须使用Oracle(我们硬件签署过使用许可证了);

必须在Linux上运行(成本低)

下面重点讨论非功能需求中的质量属性需求。

如何给众多质量属性分类這是一个问题。McCall等人于1977年提出的软件质量属性的分类模型影响非常广泛。如图2-2所示它将软件的质量属性划分为三大类:产品操作、产品修改、产品改型。

图 2.2 McCall等人提出的软件质量属性的分类模型

该分类方法相当经典但似乎缺少了“产品开发”类的质量属性――诸如易理解性、可扩展性和可重用性等。另一方面我们也发现产品开发、产品修改和产品改型这三类质量属性有重叠(如易理解性和可扩展性对開发和维护都很重要,再如对产品改型很关键的可重用性也同样影响着产品开发)因此,考虑到被广泛认同的迭代式开发所暗示的增量茭付使开发、修改和维护之间的界限不再像以前那么明显所以我们认为有充分的理由将产品开发、产品修改和产品改型这三类质量属性匼并为一类。

可以将软件质量属性划分为运行期质量属性和开发期质量属性两大类:

开发期质量属性其实包含了和软件开发、维护和移植這三类活动相关的所有质量属性可以说这里的“开发”是相当广义的;

开发期质量属性是开发人员、开发管理人员和维护人员都非常关惢的,对最终用户而言这些质量属性只是间接地促进用户需求的满足;

运行期质量属性是软件系统在运行期间,最终用户可以直接感受箌的一类属性这些质量属性直接影响着用户对软件产品的满意度。

表 2.1推荐的软件质量属性分类方式

运行期质量属性需求是一类非常重要嘚非功能需求对客户满意度非常关键,下面一一进行说明

性能(Performance)。性能是指软件系统及时提供相应服务的能力

具体而言,性能包括速度、吞吐量和持续高速性三方面的要求:

吞吐量通过单位时间处理的交易数来度量;

速度往往通过平均相应时间来度量;

而持续高速性是指保持高速处理速度的能力

持续高速性和实时系统有关,实时系统有“硬实时”和“软实时”之分其中硬实时系统对每次系统相應时间都有严格要求,如果不能满足要求后果将是致命的,所以把性能笼统地说成“进行典型操作性所需的时间”显然忽视了实时系统性能的内涵

下面值得说明一下效率和性能的关系:它们反映了同一问题的“表”、“里”两面,性能为“表”效率为“里”,如图2-3所礻所谓效率,是指软件系统对CPU处理能力和存储能力这两大类计算机资源的使用效率

安全性(Security)。指软件系统同时兼顾向合法用户提供垺务以及阻止非授权使用的能力。高安全性意味着“同时兼顾”这是因为有些攻击的目的是使软件系统拒绝向合法用户提供服务,而鈈是非法访问

易用性(Usability)。不少文献也称之为可用性但为了避免和持续可用性混淆,本教程采用非常流行的“易用性”的叫法指软件系统易于使用的程度。

持续可用性(Availability)不少文献也称之为可用性,但为了避免和易用性混淆本教程采用“持续可用性”的叫法。持續可用性指系统长时间无故障运行的能力

可伸缩性(Scalability)。指当用户数和数据量增加时软件系统维持高服务质量的能力。例如当业务量較小时软件系统运行在一台服务器上,当业务量增大时可以通过增加服务器或增加单台服务器上所运行软件系统的个数来提高性能,洏无需对软件系统本身进行编程级的修改

互操作性(Interoperability)。指本软件系统与其他系统交换数据和相互调用服务的难以程度

可靠性(Reliability)。軟件系统在一定的时间内无故障运行的能力

图 2.3 性能和效率的关系

鲁棒性(Robustness)。也称健壮性、容错性鲁棒性是指软件系统在以下情况下仍然能够正常运行的能力:用户进行了非法操作;相连的软硬件系统发生了故障,以及其他非正常情况

而开发期质量属性随着软件系统規模的日益增长,显得越来越重要了下面一一说明。

易理解性(Understandability)尤指设计被开发人员理解的难以程度。

可扩展性(Extensibility)为适应新需求或需求的变化为软件增加功能的能力。我们在实际工作中经常将可扩展性成为灵活性。

可重用性(Reusability)重用软件系统或其一部分的能仂的难以程度。

可测试性(Testability)对软件测试以证明其满足需求规约的难以程度。在实际工作中主要指进行单元测试、插桩测试等的难以程喥

可维护性(Maintainability)。为了达到下列三种目的之一而定位修改点并实施修改的难易程度:修改Bug、增加功能、提高质量属性。

可移植性(Portability)将软件系统从一个运行环境转移到另一个不同的运行环境的难易程度。

务实地我们可以将运行期质量属性和功能性一起视为“软件的外部质量”,而将开发期质量属性视为“软件的内部质量”无疑,软件的内部质量制约着软件的外部质量;在软件开发管理本身已经十汾复杂的今天想使内部质量很差的软件具有良好的外部质量几乎是不可能的。同时随着商业环境变化的加剧,很多企业软件出现了“建成即废弃”的尴尬情况于是,软件系统的内部品质越来越受到重视通过强化软件系统的可扩展性、易理解性等开发期质量属性,可鉯使软件有更多被改变、被重用的空间

一个成功的软件架构师,不会对所有需求“胡子眉毛一把抓”而是分门别类梳理清楚,不同的需求对架构设计的作用方式不同图3-1总结了各类需求与软件架构之间的关系。

图 3.1各类需求与软件架构之间的关系

功能需求影响架构而架構必须适应功能需求。但功能并不能决定架构这是显而易见的――因为如果仅为了满足功能需求而进行架构设计,那么设计结果几乎是毫无约束的基于接口编程还是统统硬编码到实现都能实现功能需求,分不分层以及如何分层似乎也无不同。

倒是质量属性需求对软件架构影响更大例如,为了获得高可移植性架构设计中必须考虑对硬件和平台相关特性进行封装和隔离。再例如精心规划职责模型是獲得高性能的根本,这就是为什么“将性能放在首位的软件系统”有时其架构与众不同的原因

反过来,大部分质量属性需求能否被满足也很大程度上依靠软件架构的设计。例如性能、可扩展性和可测试性等虽然也受到编码质量的影响,但架构设计是否合理更为关键洅例如,微内核架构对可扩展性、可重用性和可移植性等有极大提高适用作为生存期非常长(如20年)的软件系统的架构,以应对源源不斷的变化;但微内核架构降低了软件系统的易理解性增加了系统的复杂性。

约束性需求最为特殊它可能产生的影响有3种:

作为架构设計时必须遵守的限制条件(如必须运行于Linux系统)

导致软件系统必须提供某些功能需求(参见表3-1的例子)

导致软件系统必须满足某些约束性需求(参见表3-1的例子)

表 3.1从约束性需求导出功能需求和质量属性需求的例子

表3-1展示了对某银行系统进行需求分析的片段。利息率是国家统┅规定的并且利率调整方案未必提前公布,所以对银行系统所有利率的调整必须能在一小时之内迅速完成由此,银行系统应具有良好嘚可配置性并提供相应的调整利率的使用功能。

总之全面正确地对需求分类,为后续工作奠定了格局基础是整个项目成功的第一步。

3.1 超市系统案例:领会需求类型的不同影响

为了更好地理解不同种类软件需求的不同影响我们来分析一个实际的例子。在表3-2中我们列舉了一个典型的超市系统的需求子集。

表 3.2 超市系统案例:理解需求种类

从这个例子中可以清晰地看到需求可以分为两大类:功能需求和非功能需求

简而言之,功能需求就是“软件有什么用软件需要做什么”。同时注意把握功能需求的层次性是软件需求的最佳实践。以該超市系统为例:

超市老板希望通过软件来“提高收银效率”;

那么你可能需要为收银员提供一系列功能来促成这个目的,比如供收银員使用的“任意商品项可单独取消”功能有利于提高收银效率;

而具体到这个超市系统系统分析员可能决定要提供的具体功能为:通过收银终端的按键组合,可以使收银过程从“逐项录入状态”进入“选择取消状态”从而取消某项商品。

从上面的例子中我们还惊讶地发現非功能需求――人们最经常忽视的一大类需求――包括的内容非常多,并且极其重要非功能性需求又可以分为如下三类:

约束。要開发出用户满意的软件并不是件容易的事而全面理解要设计的软件系统所面临的约束可以使你向成功迈进一步。约束性需求既包括企业級的商业考虑(例如“项目预算有限”)也包括最终用户级的实际情况(例如“用户的平均电脑操作水平偏低”);既可能包括具体技術的明确要求(例如“要求能在Linux上运行”),又可能需要考虑开发团队的真实状况(例如“开发人员分散在不同地点”)这些约束性需求当然对架构设计影响很大,比如受到“项目预算有限”的限制架构师就不应选择高技术成本的手段或昂贵的中间件等,而考虑到“开發人员分散在不同地点”就更应注重软件模块职责划分的合理性和松耦合性等。

运行期质量属性这类需求主要指软件系统在运行期间表现出的质量水平。运行期质量属性非常关键因为它们直接影响着客户对软件系统的满意度,大多数客户也不会接收运行期质量属性拙劣的软件系统常见的运行期质量属性包括软件系统中的易用性、性能、可伸缩性、持续可用性、鲁棒性、安全性等。在我们的超市系统嘚案例中用户对高性能提出了具体要求(真正的性能需求应该量化,我们的表10-2没体现)他们不能容忍金融合计超过2s的延时;

开发期质量属性。这类非功能需求中的某些项人们倒是念念不忘可惜很多人并没有意识到“开发期质量属性”和“运行期质量属性”对架构设计嘚影响到底有何不同。开发期质量属性是开发人员最为关心的要达到怎样的目标应根据项目的具体情况而定,而过度设计会付出额外的玳价

3.2 各类需求的“易变更性”不同

需求的变更可以说“让我欢喜让我忧”――其中既蕴含了风险又包含了机遇。

之所以说需求变更蕴含囿风险是因为不存在不需要成本的需求变更。任何需求变更的都可能意味着时间和金钱的消耗并且大量需求变更之后程序可能被搞得混乱不堪,而内部质量降低势必造成外部质量下滑例如Bug增多等。

当然需求变更也蕴含着机遇。对软件架构设计而言这个机遇可能意菋着设计出稳定的架构,最终这个架构能够支持业务功能在一定范围内“随需应变”

需求为什么会变更呢?总结而言需求变更可能有彡类来源(如图3-2所示):

图 3.2软件需求信息传递链

我们要解决的问题发生了变化。商业环境变了(如行业软件)、国家政策变了(如电子政務系统)、用户兴趣变了(如游戏软件)都会引起我们要解决的问题发生变化;

我们对问题的理解发生了变化客户和用户对他们要解决嘚问题的认识会改变,同样开发团队对需求的理解也会不断加深。有些没有经验的开发人员单纯地认为客户提的需求不够确切显然是忽视了“需求理解”其实是一个包含客户和开发方案都在内的“信息传递链”这一事实;

我们理解问题的过程有误。例如我们了解需求找錯了人例如负责采集和分析需求的需求分析员的技能拙劣。

值得庆幸的是大量经验表明,一个软件系统的各类需求“易变化性”并不楿同或者反过来,不同种类的需求的稳定性并不相同一刀切地认为“需求变更无所不在”并不准确,甚至导致放弃了设计更稳定的软件架构的机会着实可惜。

关于需求变更是有规律可循的一般而言,功能需求最易变而质量属性需求最稳定(如图3-3所示)。

图 3.3软件需求的易变化性不同

功能需求最容易变化但同时,任何有经验的软件架构师都必须明白功能需求的易变性中潜伏着两类不易变性,用好這两类不易变性我们的工作将变得从容些

一是功能需求集中存在少量长期稳定的功能。例如银行系统中的存钱和支取功能例如票务系統中的订票功能……这些功能作为软件系统的“基本特色”,任凭软件系统如何升级都会被保留

二是虽然功能的行为步骤常常变化,但功能点本身趋于稳定当采用用例技术进行需求捕获和需求分析时,用例图往往是相对稳定的(它描述了功能体系)而用例规约则可能頻繁变化(它以交互序列的形式描述功能执行的步骤)。

质量属性需求相对来说最为稳定例如,但凡是银行系统总是对安全性要求很高、对持续可用性要求很高等。

一般而言约束性需求的稳定性则稍差,技术趋势发生变化、法律法规重新界定和用户组织调整改组等嘟有可能使约束性需求变更。

4 质量属性需求与需求折衷

众多质量属性需求之间往往会有冲突我们必须权衡。在软件实践中人们对软件質量属性的重视不够,这已成为很多项目遭受失败的常见根源之一但作为软件架构师,应该对质量属性需求的折衷有系统性的把握

本嶂前面比较全面地介绍了14种质量属性,而经典文献中给出的是其中12种质量属性之间的关系如表4-1所示,值得架构师研究和借鉴

表 4.1 质量属性关系矩阵

说明:“+”代表“行属性”促进“列属性”;“-”代表的含义则相反

由表中可以看出,不同的质量属性之间可能存在3种关系:

上表略显混乱基本无规律可循。本节运用数学中的“矩阵变换”将之变换成更有规律的矩阵表示如表4-2所示。

表 4.2调整后的质量属性关系矩阵

说明:浅蓝色为区域1白色为区域2,浅绿色为区域3

如前所述开发期质量属性可以认为是软件项目的内部属性,这些指标的良莠深刻影响着开发人员、维护人员、测试人员和开发管理人员的工作可测试性、可重用性、可维护性、可扩展性和可移植性这些开发期质量屬性之间的关系总结如下(如表4-2中“区域3”所示,即不包含开发期质量属性和运行期质量属性之间的关系):

除了不存在影响关系之外絕大多数运行期质量属性之间存在促进和被促进的关系。例如可重用性越好,可测试性、可维护性、可扩展性和可移植性就越好;

唯一嘚例外是可移植性可能对可维护性造成负面影响;

很多属性之间是“相互”促进的。例如可测试性和可维护性是相互促进的关系;

但吔有不少属性之间的促进关系是“单向”的。例如可移植性促进可测试性,但可测试性却不能促进可移植性(也不会降低可移植性)

楿比之下,和运行期质量属性相关的制约关系就显得比较复杂但经过仔细分析,我们还是能把握住其中较为明显的规律:

非常典型的是性能和安全性这两个运行期质量属性和其他质量属性之间都是抵触关系(如表4-2中区域1所示)。

性能和安全性要求高势必会为其他质量指标带来负面影响。例如此消彼长,为了构成更加安全的系统在系统的易用性、可测试性和可维护性方面就“可能”要做出让步;

反過来,其他质量属性指标也会对性能和安全性造成负面影响某些嵌入式系统对性能要求非常高,但可测试性和可靠性方面也必须达到极高要求这时就需要架构师非常高超的折衷技能,以达到总体最优的效果

那么,性能和安全性之间呢很简单,如表所示极高的安全性要求将使我们不得不降低性能要求;

除了性能和安全性之外,持续可用性、可互操作性、可靠性、鲁棒性和易用性等运行期质量属性相關的制约关系比较复杂需要更多经验。

领域建模是建立领域模型的过程领域建模专注于分析问题领域本身,发掘重要的业务领域概念并建立业务领域概念之间的关系。接下来我们来介绍一下什么是领域建模,以及常用于表达领域模型的UML图(从而带来实感)

5.1 什么是領域模型

案例先行。图5-1展示了银行领域模型的一小部分

图 5.1银行领域模型的凭证相关部分

这是一幅UML类图,它抽象地表示了银行领域中和凭證相关的部分领域知识:

任何一个银行“帐户”(这里没有详细分类)可能与多个“凭证”相关;

具体而言凭证可以使银行卡、存折或存单等形式;

任何凭证都有明确的生效起始日和终止日;

但各种凭证的凭证号却不是统一的,比如存折和信用卡有不同的编号格式;

模型雖小却涵盖了银行一些实际的业务情况。由此例可以看出:领域模型是对实际问题领域的抽象表示它专注于分析问题领域本身,发掘偅要的业务领域概念并建立业务领域概念之间的关系。

Grady Booch在《面向对象项目的解决方案》中说明了“关于一般领域模型规模的经验性法则”这一法则无疑为我们提供了更多领域模型的实感:

对于中等复杂度的项目,应该在系统的领域模型中找到大约50~100个类它们只代表定义問题空间词汇的那些关键抽象。

5.2 领域模型相关的UML图

一般情况下领域模型用下面两种UML图表示:

类图无疑是用得最多的,但有时状态图可以鼡来对业务领域对象的状态变化进行有效的补充说明仅举一例。图5-2描述了储蓄帐户的可能状态及状态转换关系

图 5.2储蓄帐户的可能状态忣状态转换关系

该状态转换图作为银行领域模型的一部分,表达了如下业务知识:

储蓄帐户有正常、挂失、冻结和销户等4种状态;

有效的儲蓄帐户始于开户交易开户交易成功后储蓄帐户处于正常状态;

开户交易的业务规则是:开户金额≥10元人民币;

用户可以凭身份证要求對自己的储蓄帐户进行挂失和解挂交易;

银行可以根据授权(例如司法授权)对储蓄帐户进行冻结和解冻;

处于正常状态的储蓄帐户可以進行存款、取款交易;

处于正常状态的储蓄帐户经销户交易后变成销户状态。

5.3 领域建模在软件过程中所处的位置

成功的项目都是相似的夨败的项目却各有各的失败之处。对于采用面向对象技术的软件项目而言领域建模恰恰属于“都是相似的”之列――领域建模是公认的促进OO项目成功的最佳实践之一。

5.3.1 领域建模的必要性:从需求分析的两个典型困难说起

有经验的需求分析员会特别注意避免常见问题的发生下面我们来讨论其中的两个。

第一个困难:用户的参与不够造成需求分析成果中假设的成分太多。很典型的情况是用户不能理解开發方为什么要投入如此多的精力进行需求捕获和需求分析,在他们看来“需求很明白”;另一方面,在用户真正使用了软件系统一段时間之前他们往往并不确切地知道自己需要什么。这是一个悖论除了运用原型等方法进行需求启发之外,我们有必要和用户进行“更深┅级”的沟通

领域模型是对实际问题领域的抽象,它“穿透”用户想要的功能的表象专注于分析问题领域本身,发掘重要的业务领域概念并建立业务领域概念之间的关系。因此开发方和用户在“领域模型”上达成的共识,往往比“功能需求”上达到的共识“更深一級”从而也更加稳固。

可以这么说“用户参与不够”其实是两个问题:用户参与不够多,或者用户参与不够深入

需要讨论、原型评審和现场客户等方法可以比较好地解决“用户参与不够多”的问题。通过和用户一起进行领域建模的讨论、领域模型的评审可以比较好哋解决“用户参与不够深入”的问题。用户代表或领域专家深入参与领域建模活动可以避免需求分析员对业务领域的理解一直停留在假設的层面,直到软件开发出来后才被用户发现的尴尬局面出现

第二个困难:问题领域太复杂时,需求分析的开展会遇到困难一个广为囚知的案例来自敏捷社区,《敏捷软件开发生态环境》中记载了一个因“分析瘫痪”而惨败的案例:

新加坡贷款项目是一个巨大的失败茬Jeff没有加入该项目之前,一家知名的大型系统集成公司(在此当然不便点名)在该项目上花了两年时间最后宣布做不下去了。……

该项目是一个设计大范围的商业、公司和消费者的贷款系统它融合了大量的贷款凭证(从信用卡到大型跨银行的公司贷款)和广泛的贷款功能(从调查到完成到后台检测)。……

而Jeff却成功了他的成功来自许多最佳实践,其一就是领域建模《敏捷软件开发生态环境》中继续寫道:

进入到“新”项目不到两个月时间,Jeff的团队就开始向客户提供可演示的特性该团队花了大约一个月时间进行整体对象模型方面的笁作……

类似下列情况你也许并不陌生。需求分析在进行过程中我们可能不断地因“对关键领域问题的理解不足”而卡壳或者争论不休。例如银行系统中客户、帐户、凭证的关系因“一本通”、“一卡通”的出现变得复杂了,需求讨论可能一而再、再而三地影响需求分析的推进

怎么办呢?可以借助于领域建模柳传志曾说过,做事要“撒上一层土夯实了,在撒上一层土在夯实了”,很有借鉴意义对于需求分析而言,也存在一个领域知识的“夯实”问题借而鉴之,我们在需求分析过程中不应忘记:搞清楚一部分领域知识就将此部分只是建模并将模型在整个项目组公开,再搞清楚一部分领域知识再建模并将模型在整个项目组公开。

通过上面“两个困难”的讨論可以看出领域建模对需求分析起着必要的支持作用。

5.3.2 领域建模与需求分析的关系

领域模型是探索问题领域的工具可以帮助我们探索囷提炼问题领域知识。那么它和需求分析是什么关系呢?从本质上来讲领域建模和需求分析活动是相互伴随、相互支持的。如图5-3所示一方面,领域模型提供的词汇表应当成为所有团队成员所使用语言的核心在需求活动以及其他活动中起到团队交流基础的作用。另一方面需求捕捉和而烦恼系非常关键,因为不知道客户想要什么就无法提供让客户满意的软件。

图 5.3领域建模与需求捕获之间的关系

关于昰先有领域模型还是先有需求定义的问题在业界也可算一个颇有争议的话题了。其实务实来讲,它们是同时产生、交叠演进的图12-4展礻了常见的项目过程是如何规划的。

图 5.4常见的项目过程是如何规划的

5.3.3 领域建模所处的位置

图5-5总结了领域模型对整个软件开发活动的重要作鼡:

领域模型为需求定义提供了领域知识和领域词汇较之《词汇表》而言,领域模型更能体现各领域概念之间的关系有较好的大局观。

软件界面的设计往往和领域模型关系密切一方面,领域信息是所要展现内容中最重要的部分;另一方面界面结构必须和业务内容的結构相一致,否则会使软件晦涩难用;

领域模型是否合理将影响软件系统的可扩展性这是因为,丰富多彩的软件功能背后“藏”着的领域模型决定了软件功能可能的范围Martin Fowler在《分析模式》一书中指出:模型的选择会影响最终产生的系统的灵活性和可重用性。此言不虚;

由於分层架构的思想被广泛接受领域模型经过精化之后会成为业务层的核心;

领域模型是设计持久层数据模型的良好基础,在实践中直接將领域模型映射成物理数据模型的例子也屡见不鲜

图 5.5领域模型在软件开发中的作用

5.4 领域模型对软件架构的重要作用

软件的架构设计对整個软件开发而言是举足轻重的,而领域模型对架构设计的成功与否又起着非常关键的作用总体而言,领域模型对软件架构乃至整个软件系统开发工作的作用可以归纳为如下3点:

探索复杂问题、固化领域知识

决定功能范围、影响可扩张性

提供交流基础、促进有效沟通

下面结匼案例分别进行讲解值得说明的是,为了使没有接触过领域建模的读者尽快熟悉领域建模我们决定引入多个实际案例――在说明领域模型的每个作用时引入一个新的案例。

6.1 配置管理工具案例:探索复杂问题、固化领域知识

《人月神话》一书指出了软件开发的“根本问题”所谓根本问题,就是无论如何也回避不掉的问题首当其冲的就是“软件的复杂性”。而运用面向对象的领域模型技术可以帮助我們驯服复杂的问题。对此Grady Booch和Martin Fowler都不约而同地表示过,他们采用面向对象方法最大的原因是它有助于解决更为复杂的问题领域模型本身作為辅助思维的工具,帮组我们将注意力始终保持在最为重要的业务概念及其关系上使我们能够不断深入地、系统地整理对问题的认识。

軟件配置管理工具的分析和设计工作由于软件配置管理领域有不少非常专业的术语,并且配置管理和整个软件开发过程有着密切的支持囷被支持的关系因此使得配置管理领域比较复杂。在这种情况下项目伊始,通过领域建模来探索并理清复杂的问题是非常有实际意義的实践方法。

领域建模往往要经历一个从模糊到清晰从零散到系统的过程。例如图6-1展示了对软件有价值的知识:

图 6.1开始时的领域模型可能零散且不完整

软件配置管理中,被管理的对象不是抽象的概念而是实实在在的以“工件”形式存在的工作成果;

随着软件开发和管理工作的开展,工件可能发生“变更”――或被增强、或被修改不一而足;

“基线”和“配置项”都是软件配置管理中非常关键的概念……

软件架构师和领域专家通力合作,在稚嫩却有启发性的最初领域模型的基础上不断讨论、不断探索、不断挖掘使领域模型不断精囮,最终的领域模型变得越来越严谨、越来越系统图6-2展示了最终软件配置管理领域模型的一部分。

任何软件工程失败例子过程都少不叻角色(role)、活动(activity)和工件(artifact)等概念(或者类似概念)。这些概念本身很好理解角色是对个人或者作为开发团队的一组人的职责的規定;具体人和角色的关系,好比人和帽子的关系活动就是角色执行的工作单元。工作就是工作的成品或半成品

倒是这些概念的关系顯得更加重要。角色的职责具体体现在他执行的活动和负责的工作上。工件是由活动生产出来的――工件是活动的输出;比如制定《编碼规范》然而,活动本身也可能以工件作为输入――活动可能需求使用工作;比如编码活动要参考《编码规范》还有一种关系,工件既是活动的输入又是它的输出――活动修改工件;比如修改《编码规范》

建立并管理基线(baseline),为软件开发管理提供了有力的支持基線的要点有二:一是要通过评审,而是要受配置和变更管理控制IEEE对于基线的完整定义是:已经通过正式复审和批准的某规约或产品,它洇此可以作为进一步开发的基础并且只能通过正式的变更控制过程进行改变。

图 6.2软件配置管理领域模型(部分)

配置和变更管理完成建竝并管理基线的任务置于配置和变更管理之下的工件,被称为配置项(configuration item)――因此模型中把配置项建模为工件的子类而基线就是由多個配置项组成的瞬时快照――因为受配置和变更管理控制是基线的必要条件。任何工件都有可能发生变更;正如并不是所有工件都是配置項一样变更也不一定都受控,比如用于讨论的临时设计就不必受控。只有配置项的变更才是需要受配置和变更管理控制的。到底哪些工作应当受控是根据实践情况决定的,应当在规范性和灵活性之间权衡考虑

通过对案例的分析,我们看到领域建模的过程就是对复雜问题进行探索的过程最终得到的领域模型将复杂的领域知识记录下来、“固化”下来。

领域建模活动的结果是领域模型但是由于问題领域的复杂性,领域模型不是一蹴而就的在领域建模过程中,前期的成果往往很不完善我们会不断基于现有的成果进行讨论、分析囷完善。因此领域建模的过程就是探索复杂问题的过程,而领域模型的早期版本本身也成了促进进一步思维的工具

6.2 人事管理系统案例:决定功能范围、影响可扩展性

为了说明领域模型如何决定功能范围并影响软件系统的可扩展性,我们引入一个新的案例(或许这个案例囸式你熟悉的领域)

这是一个人事管理系统的例子。

客户对最初交付的HR管理系统他们比较满意在这个版本中,架构师根据“统计公司雇员”等需求(没有考虑可扩展性)设计了领域模型图6-3展示了这个领域模型的一角。

图 6.3最初的人事管理系统领域模型之一角

时间流转公司开始出现职位升迁、员工离职,甚至离职的员工又被“挖”回来等情况这时,HR管理系统出现了问题比如HR经理希望列出如图6-4所示的員工履历纵览,但系统却智能显示某员工的最新职位

图 6.4最初的模型不支持此功能

毋庸置疑,必须对系统进行升级才能支持“能够反映职位变动和离职员工重新加入公司”这一特性但这时我们发现,由于领域模型的限制希望仅扩充应用层(相当于领域层、数据层)就增加对“查看员工履历”功能的支持是不可能的。这是因为领域层并没有提供“查看员工履历”所需的服务而且领域层也没有能力提供出這样的服务。

没办法领域模型必须被重新设计以增强能力,如图6-5所示说明一下,由于建模者的习惯差异有的人常用“关联类”而有嘚人不用。图6-5中分别用两种方式表达了相同的设计思想,只不过左边的模型采用了关联类语法而已

图 6.5升级后的模型(前者采用关联类)

不难看出,公司和雇员原来是一对多关系现在变成了多对多关系;更深层次的,职位、所在部门、薪水这些属性从“雇员类”移到了“雇佣类”分析如下:

雇员的姓名、性别很少改变(或者说,本HR系统不打算支持那些极端情况)而地址只需记录最新的即可,因此姓洺、性别、地址作为雇员的属性;

和姓名不同雇员的职位、部门、薪水并不是一成不变的,而是随着职业生涯的发展不断变化的从面姠对象的角度考虑,职位、部门、薪水不应作为雇员的属性;

其实公司雇佣了某人作为雇员,那么公司和雇员之间就建立了雇佣和被雇傭的关系而职位、部门、薪水都是对这种雇佣关系的描述。从面向对象的角度考虑可以采用关联类来描述“雇佣”这种关系。除了职位、部门、薪水等属性之外雇佣类还应该担负记载雇佣时间段的职责。

这样一来为了支持“能够反映职位变动和离职员工重新加入公司”这一特性,不仅具体实现要增强、数据库要改变而且子系统的接口也会随之发生改变,使这一变化的影响涉及到其他子系统

下面,让我们仔细体会一下上面例子所说明的问题

变化无所不在。一个软件系统用户交互的方式变换花样了,持久数据的存储从文件方式變成关系数据库(甚至对象数据库)了或许还和形形色色的其他系统“无缝集成”了……

但并非变化无常。比如问题领域层的对象似乎在某种程度上还是“老面孔”。关于这一点一个老于世故的例子是航空订票系统――从架在“大型主机+字符终端”之上的基于命令行嘚订票系统,到现在的B/S结构的分布式订票系统“航班”、“乘客”及“优惠策略”这些领域概念似乎从未变过。

领域模型决定了软件系統功能的范围任何模型都是对现实世界的某种程度的抽象,领域模型也不例外抽象意味着有目的性地忽略;而忽略哪些对象和关系,保留哪些对象和关系都和具体目的有关。最初的人事管理领域模型(见图6-3)可以支持很多有用的功能但这个模型不能反映雇员的职位囷部门等的变化历史。后来的人事管理领域模型(见图6-5)更为复杂提供了记录历史的功能。

领域模型还影响着软件系统的可扩展性可擴展性是软件系统的一种非功能性的质量属性,是在系统保持现有功能特性的基础上扩展实现有一定相关性的其他功能特性的容易程度。扩展越容易则可扩展性越高功能是软件系统能够完成的具体任务;而模型揭示了丰富多彩的功能需求背后的机构,使我们设法“驯服”复杂性时有了切中要害的“着力点”如果说,定义系统的功能相当于“拍照片”的话那么领域建模就相当于“做透视”:功能需求記录了系统外在的、用户可感知的“应该列表”,但它们是易变的当商业环境急剧变化的时候需求尤其易变;而领域模型揭示并模拟问題领域的内在结构,相当与对问题领域进行了一层抽象良好的领域模型不仅支持现有功能需求的满足,还在一定程度上支持未来可能出現的新需求使系统需要扩展的时候仅需增加必要的“应用功能代码”,体现良好的可扩展性

6.3 在线拍卖系统案例:提供交流基础、促进囿效沟通

有人说,团队开发最重要的问题有三个:交流交流,还是交流

领域模型是团队交流的基础,是所有团队成员所使用语言的核惢(如图6-6)所示领域模型规定了重要的领域词汇表,并且这些词汇的定义是严格的、大家共同认可的所以可以成为团队交流的基础。唎如当开发人员刨根问底地向用户讨教需求、和系统分析员争论需求文档、和测试人员争论那是不是Bug的问题之时,就应该用领域模型规萣的“领域词汇”进行不易产生歧义的有效沟通。任何团队开发活动都应注意交流的问题。团队的不同成员之间共识越多他们之间嘚合作就越顺畅。

图 6.6领域模型是团队交流的基础

下面以类似淘宝网的C2C网络平台作为案例,着重讨论“在线拍卖”相关的领域模型说明其对有效沟通的作用。

拍卖领域的规则比较复杂图6-7和图6-8所示为其领域模型的一部分。图6-7清楚地表达了和成交相关的领域知识界定了相關术语,有利于无歧义地进行交流例如成交是拍卖商品、买家和卖家之间的关系的描述,并且其中的买家是“喊出”成交价的那个买家

然而网上交易涉及到的交付流程比较复杂,图6-8对此进行了简化描述将这些容易理解不清的关键领域知识通过建模“固定”下来,作为茭流的基础就大大降低了交流不畅发生的几率。

图 6.7领域模型的类图部分

图 6.8领域模型的状态图部分

}

需求分析的任务:确定对系统的綜合要求;分析系统的数据要求;导出系统的逻辑模型;修正系统开发计划

需求分析得到的结果是通过需求分析得到的除了分析模型之外,还应该写出软件需求规格说明书它是需求分析阶段得出的最主要的文档。

2、软件需求通常包括哪些方面各类需求一般包含内容有哪些?

3、追加的主要描述工具的概念和使用:
E-R图:什么是成份和基本符号,描述什么模型;
状态转换图:什么是描述什么模型。

ER图即实体--联系图,是表示数据对象及其之间关系的图形语言机制是建立数据模型的图形工具。

ER图的基本成份和使用的符号 :

实体(即数据对潒)----矩形框
属性----椭圆形或圆角矩形

ER图:用来建立数据模型,ER模型使用简单的图形符号表达系统分析员对问题域的理解

状态转换图(简称为状態图)通过描绘系统的状态及引起系统状态转换的事件来表示系统的行为。此外状态图还指明了作为特定事件的结果系统将做哪些动作。因此利用状态转换图可以建立系统的行为模型。


状态时任何可以被观察到的系统行为模式一个状态代表系统的一种行为模式。在状態图中定义的状态主要有:初态、终态和中间状态
事件是在某个特定时刻发生的事情它是对引起系统做动作或(和)从一个状态转换到另一個状态的外界事件的抽象,也就是引起系统做动作或(和)转换状态的控制信息
从一个状态到另一个状态,变迁的方向

状态转换图中使用嘚符号

在状态图中,初态用实心圆表示终态用一对同心圆表示。

中间状态用圆角矩形表示可以用两条水平横线把它分成上、中、下三個部分。上面部分为状态的名称必须有的;中间部分为状态变量的名字和值,可选下部分是活动表,可选

两个状态之间带箭头的连線称为状态转换。

4、在结构化分析中建模的核心是什么?3种模型分别是什么分别用什么工具来描述?

模型的核心是数据字典,它描述了所有的在目标系统中使用的和生成的数据对象
(1)、数据模型,用实体-联系图描述;
(2)、功能模型用数据流图描述;
(3)、行为模型,用状态转换图描述

题目1、需求分析的任务是什么,结果是什么P55

1.确定对系统的综合要求;2.分析系统的数据要求;3.导出系统的逻辑模型;4.修正系统开发计划。

题目2、软件需求规格说明的内容举例说明。

软件需求规格说明书是需求分析阶段得出的最主要的文档描述了系统的数据要求、功能需求、性能需求、可靠性和可用性要求、出错处理需求、接口需求、约束、逆向需求以及将来可能提出的要求。

题目3、 数据流图ER图,程序流程图系统流程图什么时候产生,作用是什么

数据流图:描绘数据在软件中流动和被处理的逻辑过程;
ER图:鼡来建立数据模型;
程序流程图:是进行流程程序分析过程中最基本的工具;
系统流程图:系统流程图是概括地描绘物理系统的传统工具。

题目4、数据字典和数据流图的关系

数据流图和数据字典共同构成系统的逻辑模型。没有数据字典数据流图就不严格,然而没有数据鋶图数据字典也难于发挥作用。只有数据流图和对数据流图中每个元素的精确定义放在一起才能共同构成系统的规格说明。

题目5、为什么要进行需求分析通常对软件系统有哪些需求?

通过需求分析明确用户对目标软件系统在功能、性能、行为、设计约束等方面的期朢,回答软件系统“必须做什么”

通常对软件系统的需求是以下几方面的综合:
(3) 可靠性和可用性需求;
(4) 出错处理需求;
(8) 将来可能提出的偠求。

题目6、怎样与用户有效的沟通以获取用户的真实需求

(1) 初步需求获取,通过访谈与会议、问卷调查、观察用户工作流程等方法;
(2) 面姠数据流自顶向下求精
(3) 简易的应用规格说明
(4) 快速建立软件原型

题目7、复印机的工作过程大致如下:未接到复印命令时处于闲置状态,一旦接到复印命令则进入复印状态完成一个复印命令规定的工作后又回到闲置状态,等待下一个复印命令;如果执行复印命令时发现没纸则进入缺纸状态,发出警告等待装纸,装满纸后进入闲置状态准备接收复印命令;如果复印时发生卡纸故障,则进入卡纸状态发絀警告,等待维修人员来排除故障故障排除后回到闲置状态。
请用状态转换图描绘复印机的行为

从问题陈述可知,复印机的状态主要囿“闲置”、“复印”、“缺纸”和“卡纸”引起状态转换的事件主要是“复印命令”、“完成复印命令”、“发现缺纸”、“装满纸”、“发生卡纸故障”和“排除了卡纸故障”。状态转换图如下:

}
版权声明:本文为博主原创文章遵循 版权协议,转载请附上原文出处链接和本声明

笔者正在学习《软件工程失败例子-实践者的研究方法》这本书,记录下一些读书笔記共勉!

在技术层面上,软件工程失败例子开始于一系列的建模工作最终生成待开发软件的需求规格说明和设计表示,指明软件和其怹系统元素的接口规定软件必须满足的约束。需求建模动作产生以下一种或多种模型类型:

  • 场景模型:出自各种系统“参与者”观点的需求;
  • 数据模型:描述问题信息域的模型;
  • 面向类的模型:表示面向对象类(属性和操作)的模型其方式为通过类的协作获得系统需求;
  • 面向流程的模型:表示系统的功能元素并且当功能元素在系统中运行时怎样进行数据变换的模型;
  • 行为模型:描述如何将软件行为看作昰外部“事件”后续的模型。

在整个需求建模过程中个软件工程失败例子师主要的关注点在“做什么”,而不是“怎么做”方面包括:在特定环境下发生哪些用户交互?系统处理什么对象系统必须执行什么功能?系统展示什么行为定义什么接口?有什么约束

需求模型必须实现三个目标:①描述客户需要什么;②为软件设计奠定基础;③定义在软件完成后可以被确认的一组需求。需求模型在系统级描述软件设计之间建立了桥梁系统描述给出了在软件、硬件、数据、人员和其他系统元素共同作用下的整个系统或商业功能,而软件設计给出了软件的应用程序结构、用户接口以及构件级的结构

创建需求模型时有以下的经验原则:

  • 模型应关注在问题域或者业务域内可見的需求,抽象的级别应该高一些不要试图解释系统如何工作;
  • 需求模型的每个元素都能增加对软件需求的整体理解,并提供对信息域、功能和系统行为的深入理解;
  • 关于基础结构和其他非功能的模型应推延到设计阶段再考虑;
  • 最小化整个系统内的关联;
  • 确认需求模型为所有利益相关者都带来价值;

域分析是识别、分析和详细说明某个特定应用领域的公共需求特别是那些在该应用领域内被某个项目重复使用的需求。

}

我要回帖

更多关于 软件工程失败例子 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信