引语
第一,你必须弄清问题,第二,找出已知数与未知数之间的联系.......
-----波利亚,<<怎样解题>>
那些没有经验的问题解决者们,几乎无一例外,都是去匆忙的寻找解决办法,而不是先给要解决的问题下定义.
------杰拉尔德.温伯格,<<你的灯亮着吗>>
业内对架构的讨论仍沿用了传统思想;如果知道了系统需求,就可以为此系统构建架构,这种观点是缺乏远见的......
------Len Bass,<<软件构架实践>>
一、什么是软件需求
简单的说,软件需求就是"这个软件到底要为用户做什么".
IEEE的软件工程标准术语需求定义为:
1.用户所需求的解决某个问题或达到某个目标所需具备的条件或能力。
2.系统或系统组件为符合合同、标准、规范或其他正式文档而必须满足的条件或必须具备的能力。
3.上述第一项或第二项中定义的条件和能力的文档表述。
RUP这样定义需求的:
需求描述了系统必须满足的情况或提供的能力,它就可以是直接来自客户需要,也可以来自合同、标准、规范或其他正规约束力的文档。
二、软件需求要做哪些事情呢?
需求捕获 vs. 需求分析 vs. 系统分析
需求捕获:是获取知识的过程,知识从无到有、从少到多。需求采集者必须理解用户所从事的工作,并且了解用户和客户希望软件系统在哪些方面帮助他们。
成果:一摞“需求采集卡”,其中记录了需求类型、需求描述、需求背景、需求提出者和需求记录者等对进一步需求分析非常有用的信息。
需求分析:是挖掘和整理知识的过程, 它在已掌握知识的基础上进行。毕竟,初步捕获到的需求信息往往处于不同层次,也有一些主观甚至不正确的信息。而经过必要的需求分析工作之后,需求会更加系统、更加有条理。更加全面。
成果:《软件需求规格说明书》(Software Requirements Specification,SRS),精确地阐述了一个软件系统必须提供的功能、必须达到的质量属性以及它必须遵守的约束。SRS应尽可能完整地描述各种条件下的系统行为。
系统分析:针对系统所要面临的问题,搜集相关的资料,以了解产生问题的原因所在,进而提出解决问题的方法与可行的逻辑方案,以满足系统的需求,实现预定的目标。
成果:通过结构化分析得到的最重要的工作成果是数据流图;而面向对象的系统分析方法得到的工作成果主要是分析类图、鲁棒图、序列图等--其中分析类图描述设计的表态方面,而鲁棒图和序列图描述设计的动态方面。
需求捕获、需求分析是相互伴随、交叉进行的;需求工作伊始,无疑更多的是进行需求捕获工作,相伴进行的需求分析工作占的比例偏少,但随着掌握的需求信息越来越多,我们需要开展的需求的分析和整理工作也越来越多了。
用做什么和怎么做来区分分析与设计。需求分析致力于搞清楚软件系统要做什么,而系统分析更关注怎么做的问题。大多数分析方法(如OOA)应该属于系统分析的范畴。
需求分析在软件过程中所处的位置?
概念化阶段明确了软件项目的意义、可行性及概况等。在《愿景与范围文档》所划定的大前提的指导下,需求分析活动要进一步完善和细化软件需求。
需求分析和领域建模是相互支持的关系。不难理解,要进行领域建模,很大程度上依赖于需求讨论会等活动。同时,领域模型作为领域建模的成果,规定了重要的领域词汇表,并且这么词汇的定义是严格的、大家共同认可的,所以可以成为团队交流的基础,自然也应当作为需求分析活动和《软件需求规格说明书》应当遵循的标准词汇。
对于后期的架构设计活动而言,需求分析活动应该提供功能需求、质量属性以及约束性需求等不同需求的明确定义。软件架构师将就此开展用例分析、质量属性分析、细化架构设计等活动。
三、架构师必须掌握的需求知识?
架构师是需求分类、需求折衷和需求变更的研究方面的专家。
需求分类 :
运行期质量属性:
性能 (Performance)
安全性 (Security)
易用性 (Usability)
持续可用性 (Availability)
可伸缩性 (Ssclability)
互操作性 (Interoperability)
可靠性 (Reliability)
鲁棒性 (Robustness)
开发期质量属性:
易理解性 (Understand)
可扩展性 (Extensibility)
可重用性 (Reusability)
可测试性 (Testability)
可维护性 (Maintainability)
可移植性 (Portability)
性能 (Performance)。性能是指软件系统及时提供相应服务的能力。具体而言,性能包括速度、吞吐量和持续高速性三方面的要求:
吞吐量通过单位时间处理的交易数来度量;
速度往往通过平均响应时间来度量;
而持续高速性是指保持调整处理速度的能力。
持续高速性和实时系统有关,实时系统有“硬实时”和“软实时”之分,其中硬实时系统对每次系统响应时间都有严格要求,如果不能满足要求,后果将是致命的,所以把性能笼统地说成“进行典型操作所需的时间”显然忽视了实时的系统性能的内涵。
效率(Efficiency)和性能的关系:它们反映了同一问题的“表”、“里”两面,性能为“表”,效率为“里”,所谓效率,是指软件系统对CPU处理能力和存储能力这两大类计算机资源的使用效率。
安全性(Security)。指软件系统同时兼顾向合法用户提供服务,以及阻止非授权用户的能力。高安全性意味着“同时兼顾”,这是因为有些攻击的目的是使软件系统拒绝向合法用户提供服务,而不是非法访问。
易用性(Usability)。不少文献也称为可用性,但为了避免和持续可用性(Availability)混淆,本文采用非常流行的“易用性”的叫法。指软件系统易于使用的程度。
持续可用性(Availability)。不少文献也称为可用性,为避免和易用性(Usability)混淆,本文采用“持续可用性”的叫法。持续可用性指系统长时间无故障运行的能力。
可伸缩性(Scalability)。指当用户数据量增加时,软件系统维持高服务质量的能力。例如当业务量较小时,软件系统运行在一台服务器上,当业务量增大时,可以通过增加服务器或者增加单台服务器上所运行软件系统的个数来提高性能,而无需对软件系统本身进行编程级的修改。
互操作性(Interoperability)。指本软件系统与其他系统交换数据和相互调用服务的难易程度。
可靠性(Reliability)。软件系统在一定的时间内无故障运行的能力。
鲁棒性(Robustness)。也称健壮性、容错性。鲁棒性是指软件系统在以下情况下仍能够正常运行的能力;用户进行了非法操作,相连的软硬件系统发生了故障,以及其他非正常情况。
开发期质量属性则随着软件系统规模的日益增长,显得越来越重要了,下面做一下说明。
易理解性(Understandability)。尤指设计被开发人员理解的难易程度。
可扩展性(Extensibility)。为适应新需求或需求的变化为软件增加功能的能力。我们在实际工作中,经常将可扩展性称为灵活性。
可重用性(Reusability)。重用软件系统或其一部分的能力的难易程度。
可测试性(Testability)。对软件测试以证明其满足需求规约的难易程度。在实际工作中主要指进行单元测试、插桩测试等的难易程度。
可维护性(Maintainability)。为了达到下列三种目的之一,而定位修改点并实施修改的难易程度:修改Bug、增加功能、提高质量属性。
可移植性(Portability)。将软件系统从一个运行环境转移到另一个不同的运行环境的难易程度。
务实地,我们可以将运行期质量属性和功能性一起视为“软件的外部质量”,而将开发期质量属性视为“软件的内部质量”。无疑,软件的内部质量制约着软件的外部质量;在软件开发管理本身已经十分复杂的今天,想使内部质量很差的软件具有良好的外部质量几乎是不可能的。同时,随着商业环境变化的加剧,很多企业软件出现了“建成即废弃”的尴尬情况,于是,软件系统的内部品质越来越受到重视,通过强化软件系统的可扩展性、可重用性、易理解性等开发期质量属性,可以使软件更多被被改变、被重用的空间。
各类需求对架构设计的不同影响
功能需求影响架构,而架构必须适应功能需求。但功能需求并不能决定架构,这是显而易见的。因为如果仅为了满足功能需求而进行架构设计,那么设计结果几乎是毫无约束的,基本于接口编程还是统统硬编码到实现都能实现功能需求,分不分层,以及如何分层似乎也无不同。
倒是质量属性对软件架构影响更大。例如,为了获得高可移植性,架构设计中必须考虑对硬件和平台相关特性进行封闭和隔离。再例如,精心规划职责模型是获得高性能的根本,这就是为什么“将性能放在首位的软件系统”有时其架构与众不同的原因。
反过来,大部分质量属性需求能否被满足,也很大程度上依靠软件架构的设计。
约束性需求最为特殊,它可能产生的影响有三种:
1.作为架构设计时必须遵守的限制条件。
2.导致软件系统必须提供某些功能需求。
3.导致软件系统必须满足某些约束性需求。
各类需求的“易变更性”不同