英文原文:Non-functional Requirements in Architectural Decision Making
本文由《IEEE Software》杂志首发,现在由InfoQ和IEEE Computer Society联合向您呈现。
在软件工程中,非功能性需求(nonfunctional requirements,简称NFRs)与软件架构(software architectures,简称SAs)之间存在着紧密联系。早在1994年,Rick Kazman和Len Bass就肯定地说过,软件架构与实现非功能性需求之间存在密切联系。1这一想法在软件开发领域已经流行很多年,它也解释了为什么开发项目要在实现非功能性需求方面做大量投入。2
当我们认识到软件架构的概念如何从简单的结构性表示演变为决策视角时,这个笼统的观点就显得更加具体了。 3从决策角度来看,非功能性需求是对各种设计方案进行选择的标准。4 例如,从可维护性或可移植性方面考量,需要一种层次性架构风格;从效率方面考量,需要一种专门的数据库技术。
软件架构师在执行软件架构设计任务时,必须连续不断地应对非功能性需求。他们必须了解系统有哪些非功能性需求,以及架构决策对实现这些非功能性需求的影响。 在本文中,我们将介绍一项实证研究,它揭示了软件架构师们在决策过程中应对非功能性需求的有关实践。这项研究以一个调研活动为基础,该调研活动由两部分组 成。首先,我们从工程角度对非功能性需求加以分析,尤其是与三类需求工程活动(获取、文档化和验证)的关系。然后,我们深入研究了非功能性需求是如何影响 架构决策的。
调研
我们针对同一个软件项目,多次组织了半结构化访谈(semi-structured interviews),访谈的对象都是参与过该项目的软件架构师。相对其他定性研究策略(如结构化问卷调查)而言,半结构化访谈更具灵活性,它使我们可 以更好地研究对话中出现的相关问题。另外,我们把讨论范围限定在单个软件项目以内,而不是考虑一般性的架构原则,这有助于我们更好地理解与评估背景信息。5
访谈对象及所在机构
本调研涉及13位访谈对象,他们来自12家跨越不同业务与应用领域的软件密集型机构(见表1)。根据业务种类不同,这些机构可分为三类:
本调研涉及的软件项目,其功能与大小也有差别。
尽管所有访谈对象都在各自项目中履行架构师职责,但他们的所在机构并没有专门设置软件架构师职位。相反,机构是根据技术知识或经验来为各个项目选择架构师的。除去一个例外,其他所有访谈对象都同时还兼任其他角色(如项目经理、顾问或开发者)。
访谈实施
我 们为访谈制作了一个访谈指南,并通过两位研究者和两位软件架构师对它进行了测试,以确保有效。然后,我们把访谈指南预先发送给所有访谈对象,让他们有机会 熟悉访谈话题,并挑选一个用于访谈的项目。访谈是面对面进行的,每次访谈大约一小时。我们对访谈进行了录音,然后将它们转录为文本,以便进行分析。而后, 我们请访谈对象来验证转录内容。有时,我们会明确请求访谈对象澄清某些方面。我们使用了NVivo软件来评估收集到的数据。我们对所有语句和词语进行了归类,把描述相同想法、动作或属性的语句和词语归为一组。最后,我们根据机构和项目的特征来分析了数据。
局限性
我 们了解我们的样本不是随机的,因此未必能够代表更广泛的软件开发全体。所以,为了试图缓解可能存在的偏差,我们让机构自己挑选访谈对象,并允许访谈对象自 己挑选项目。我们承认,访谈对象可能会倾向于选择较为成功的项目。为了缓和这一问题,我们向访谈对象说明,该项研究不用于分析最佳实践,只是想了解做事方 式。我们承诺为反馈内容保密。大部分机构是中小型机构,而且都来自西班牙。当然,调研结果可能受到上述因素的影响。此外,大部分都不是紧要领域的项目。不 过,由于我们试图通过这些项目来揭示工业界实践,而不是提出一般性理论,所以这不算重大弱点。
架构师如何应对非功能性需求
我们向软件架构师们提出了好几个具体的问题,关于他们如何获取并文档化非功能性需求,以及之后如何在系统中进行验证。我们认为,这对理解架构师在项目中进行决策制定的背景十分重要。关于这部分的详情,请参见我们的另一篇文章6。问题列表见下。由于我们实施的是半结构化访谈,因此这些问题只是作为指导,访谈是依据对话情况来推动的。关于需求获取、文档化和验证方面的话题自然而然地在对话中出现。
获取非功能性需求,由谁负责?
需求获取的目的是从涉众等处得到系统需求,并细化之。研究者和实践者都认同需求获取是需求工程中最具挑战的部分。致力于精确无歧义表达需求的技术有很多,如调研、创意研讨会等。
这些技术假定来自客户方面的涉众(最终用户、经理等)在需求获取方面将贡献很多。就功能性需求而言,一些访谈对象认同该假定。例如,访谈对象A说:“[业务分析师]编写一个详细的文档来反映所有[功能性]需求”。
但 是,该假定对非功能性需求来说并不成立。在我们的调研中,有10个项目,软件架构师是非功能性需求的主要来源。有些客户从未提到非功能性需求。访谈对象E 说:“[客户]从没提到过网页加载时间不能超过2秒这样的需求,但他后来却对此颇有抱怨。”访谈对象L2说:“客户提到一个基本的[非功能性需求],然后 我们根据自己的经验作了补充”。”
这一数值已经超过了Uwe van Heesch和Paris Avgeriou提到的架构师显著涉及需求获取的比例(60%)。7
只 有访谈对象D、H、I的所在机构是由客户来领导非功能性需求获取的。有趣的是,也只有这几个机构的项目是外包的(管理方分别是一家航空工业公司、一家软件 公司和一家银行)。这一情况是由机构之间的从属关系造成的。然而,即便在这些案例中,架构师仍然在定义非功能性需求方面发挥着积极作用。访谈对象D说: “我们的客户是一个航空系统部门,所以所有非功能性需求都是良好定义的。另外,我们需要基于我们的经验再补充一些非功能性需求。”
如何获取非功能性需求?
非 功能性需求难以捉摸的特性,决定了不容易事先获取。根据这条一般性的看法,所有访谈对象都认同非功能性需求的获取是一个迭代的过程,需要跨越整个系统生命 周期。因为在达到一定重要阶段(通常是原型)之前,可能不太容易对系统的部分行为提出期望。访谈对象J称:“我们首先确定一些相关的非功能性需求,比如与 其他系统的兼容性等,然后开发一个原型,并分析其他候选方案。”
此外,我们无法在第一次开发之前把非功能性需求考虑完全。他们需要纠正性维护, 以纠正未符合预期的不正确行为。访谈对象K说,“在效率方面,我们必须作出改变,因为在项目开始之时并没有就服务水平提出要求。”这样是合理的。有些非 功能性需求(例如安全性方面)只有在目标环境中部署系统或意外发生时,才能进行全面检查。
如何档案化非功能性需求?
为 了让档案化更加有效,学术界与标准化组织已经提出了许多用于编写系统需求规格说明书的表示法和模版。然而,13位访谈对象中有9位承认他们不对非功能性需 求进行档案化。访谈对象H说:“[功能性需求]是用UML、概念模型、用例来表示的,但没听说过非功能性需求。”一些访谈对象说,只有当客户需要,或者项 目属于紧要领域时,才有必要档案化。有四位访谈对象表示他们明确记录非功能性需求。访谈对象D的所在机构采用一种领域特定语言(domain- specific language)。“因为我们为航空领域工作,我们必须以可验证的方式来明确表达非功能性需求。我们有专门的模版,我们采用来自其他工程领域的不同技术 (如风险模型、故障树等)。”两位访谈对象表示,他们采用具有一定结构的自然语言来记录非功能性需求。访谈对象B采用Volere需求模版(它提供了一个 高度结构化的需求模版);访谈对象K采用符合ISO/IEC 9126质量模型的纯文本。
访谈对象J只采用纯文本文档。只有访谈对象B和 D是不断维护需求文档的;J和K只记录最初的非功能性需求。访谈对象K说:“起初,我们用自然语言记下一些关于非功能性需求的想法,... 不过之后,我们并没有跟踪它们,在设计过程中也没有出现新的非功能性需求。”人们似乎很自然地认为,可度量性与连续(或至少规律的)记录更新之间存在一定 关系。但要确认这种关系是否存在,需要做进一步研究。
所以我们可以看到,非功能性需求很多是不言而喻的,甚至是隐含的。把它们档案化,准 确性和及时性会受到严重损害。这种情况可以用成本和收益来解释。访谈对象C直率地说:“我几乎不对项目进行适当的档案化,主要是它耗费太多钱。”如果实践 者们无法从中感到益处,那么非功能性需求将继续保持难以捉摸的状态。
如何在系统中验证非功能性需求?
验证系统的行为 是否满足非功能性需求是有难度的。不同非功能性需求之间存在差异,因此相应的验证方法也有所不同。不过,有11位访谈对象说,所有非功能性需求都在项目中 得到了满足,尽管总有改进余地。然而,当我们问道如何针对非功能性需求进行验证时,他们的回答显得含糊。访谈对象D是这么说的:“对于一些[不是全部]非功能性需求,由于不容易测试,我们只是非正式地跟客户进行了讨论。“因此,我们有必要把自以为满足非功能性需求(正如访谈对象中的那11位(85%)所做 的)和真正的验证区分开来(访谈对象中有8位(61%)对某些类型的非功能性需求进行了验证)。(这与过去研究得出的60%是相称的。8)
八位访谈对象执行了一些非功能性需求的验证,不过仅限于一到三种。他们只考虑以下类型的非功能性需求。
安 全性,作为十分重要的一类非功能性需求,所有访谈对象都没有提到。访谈对象F描述了一个极端的不作验证的例子:“我们等客户来抱怨,他们会发现问题的。” 尽管这是个不令人满意的回复,但它再次反映了这点(和前面提到的档案化一样):出于预算和时间上考虑,工程实践可能没法按照理想的方式进行。
与之形成鲜明对比的是,访谈对象D采用基于统计分析和模拟的形式化方法来检查系统的可靠性。当然,这是预料之中的,因为他们的项目涉及到航天工业中的信息系统,属于紧要领域。过去有研究发现,评估方法与评估目标有关。9 我们的发现与之不谋而合。
我们有一个可能与前人研究结果一致的发现,即档案化与验证之间的联系。如Andreas Borg及其同事所说的那样,“如果用不可度量的词语来表达需求,那么测试会很消耗时间,甚至根本无法测试。”10仅有两位访谈对象采用了可度量的方式来表达非功能性需求,这可能是验证水平整体较低的原因之一。
非功能性需求如何影响架构决策
毫无意外,所有访谈对象都认同:非功能性需求会影响他们的决策。但是他们的具体回答反映出了一些细微差别。
决策类型
非功能性需求影响着四类决策。
架构模式
对于给定类型的项目,大部分访谈对象会很自然地选择层次架构,尽管他们中有些人明确给出了决策理由。访谈对象J说:“我们采用层次架构,因为它允许以后变化。”
实现策略
有些类型的需求可能需要具体的架构级策略。它可以是一般性的设计决策(比如访谈对象L1说“我们采用单点登录,以增强子系统的集成性”),也可以是有关个别组件的具体决策(比如访谈对象A说“我们为数据库表建立副本,因为访问时间过长”)。
横向决策
有 些非功能性需求会影响到整体架构。访谈对象L1说,“我们更倾向于采用我们已经掌握的技术。”一个反复出现的问题是,第三方组件尤其是开源软件(open source software,OSS)的使用。访谈对象D说,“出于可维护性考虑,我们希望能够获得源代码,所以我们选择了开源软件方案。”
技术平台
非 功能性需求也许可以通过选择正确的数据库或中间件等来满足。在这种情况下,它们可能是影响整个系统的。访谈对象K说:“我们需要高可用性 (availability),而只有Oracle能够保证这一需求。”非功能性需求也可能是局部的。访谈对象H说:“有一个查询是直接通过 JDBC(Joint Database Connectivity)实现的,由于效率原因,所以没有采用Hibernate。”
不同的决策制定过程
我 们在本次调研中发现了一个关于决策制定的特别方面,即技术决策与其他决策的交织。我们听到三种不同的反馈。有四位访谈对象表示,非技术性决策优先。访谈对 象C说:“架构师应该在之前设计好的逻辑结构上,选用合适的技术。”另外四位访谈对象说,重大技术决策优先,之后的决策应该与之配合。访谈对象H说:“客 户给我们设了一些限制,比如,架构必须基于开源软件(OSS)和Java。”而其他五位访谈对象认为,技术决策和其他决策是交叉并彼此影响的,可以看成是 一种架构设计层面上的局部双峰模型。11
影响程度
我们询问访谈对象在进行架构决策时会考虑哪些非功能性需求。我们以ISO/IEC 25000质量标准为统一框架,将他们的回答汇总如下。
明确性(Explicitness)
很 明显,架构师们期望一定的非功能性需求,即便还没有将它们作为需求明确列出。访谈对象I说:“我不会考虑一个不安全的系统。”由于所采用技术与平台的当前 特性,这些不言而喻的非功能性需求经常浮现在架构师的脑海里。访谈对象E说:“我们不会去考虑文档的安全性,因为它是由SharePoint管理系统负责 的。”
来源(Source)
有些需求直接来自开发团队或架构师。访谈对象B说:“未来要维护这个系统的人是我们, 所以,确保它的可维护性对我们来说是很重要的。”相对于来自客户的非功能性需求,这些来自开发团队的非功能性需求与架构决策过程更加接近,因为技术人员从 解决方案的角度去思考,而客户的思考角度是面向问题的。
非技术性(Nontechnicality)
非技术性的非功 能性需求(NFRs)指那些不与软件内在质量直接相关、而是与系统环境有关的的需求,比如许可证或成本等。12架构师要考虑这些基本因素;访谈对象们表 示,所有非功能性需求中有大约40%属于非技术性的。有时,他们会以最高优先级来考虑这些需求。访谈对象J称:“成本是第一位的,所有别的都得服从 它。”
重要性(Importance)
我们询问访谈对象哪种类型的非功能性需求是最为重要的。许可证问题、易用 性、可靠性、性能效率,以及可维护性是被提到最多的。而只有两位访谈对象提到了可移植性。我们将该信息与访谈对象在面谈中提到的决策案例进行了交叉检查; 我们发现,性能效率和可维护性对决策的影响最大。
术语问题(Terminology issues)
在与访谈对象讨 论非功能性需求时,我们碰到一些术语上的问题。有些访谈对象请求对术语进行补充解释,比如“可用性(availability)”和“准确性 (accuracy)”。其他的访谈对象会在给定上下文中错误地使用术语,比如用“人体工学”来表达“易用性”。有些访谈对象甚至采用错误的定义,比如 “可维护性(maintainability)是十分重要的,因为我们不能对运转中的系统进行修改。”另一个常见的问题是混淆使用“性能 (performance)”与“效率(efficiency)”。ISO/IEC 25000将性能效率定义为“一定条件下相对于所用资源数量的性能”。”13 该定义有助于我们解除混淆。
为了 检查研究中的观察结果是否有效,我们与一些大型IT企业展开了一项新的研究。我们期望在文档化和验证上看到改善,并且有可能的话,在各种非功能性需求的重 视程度上有所变化。我们还想研究,如果把非功能性需求与架构决策之间的关系明确表达出来(比如,考虑了哪些权衡,放弃了哪些选择等等)的话,将对最终的系 统架构决策有何影响。关于本课题的相关研究,请见下方。
致谢
我们非常感谢参加本课题的参与者,感谢他们的时间和贡献。本课题获得西班牙项目TIN2010-19130-C02-01的资助。
参考文献
非功能性需求领域的相关工作
尽管相关研究不多,但我们还是试图把非功能性需求方面的实证研究结果汇总起来。Richard Svenssion和他的同事描述了18个与我们的提议有一定关系的研究。1 然而,这些研究没有涉及非功能性需求与架构决策之间关系的研究。他们的研究大部分是关注非功能性需求(NFR)方面,而其他研究者对软件架构(SA)问题 做了更深入的探索;Uwe van Heesch和Paris Averiou专门对非功能性需求与软件架构之间的关系进行了研究。2
在 我们的观察结果中,有一部分与前人的发现是一致的——比如,软件架构师常常也承担其他职责。我们其他的观察结果之前还没人公布过。比如,本课题参与者会在 只做简单验证的条件下就认为非功能性需求(NFRs)已经符合要求。在我们的观察结果中,有一些与前人的研究结果不同。比如,我们发现非功能性需求的可度 量性很弱,这与过去报告的案例不一样。3我们还分析了不同类型的非功能性需求的影响程度。我们发现这与之前的研究存在一定相似性。比如Jose de la Vara和他的同事也把效率和易用性列为最重要的因素。4 不过,我们的研究结果在必要的严格性上还差了一点。首先,本课题采用了不同的非功能性需求分类方案。另外,所涉及的职责经常不同,所以非功能性需求的类型也有所不同。1
参考文献