3.9 系统工程
概述与动机
系统工程是端到端地工程化整个复杂系统的一门学科,目的是让系统的所有部分协同工作,满足真实的需要。这里的“部分”远不止软件。一个现代系统通常把软件、硬件、人员、数据和流程结合在一起,并且必须在一个混乱的真实世界中运行。系统工程要在系统的整个生命周期内,让所有这些要素保持对齐。
这与软件架构不同。软件架构(第 3.1 章)决定软件组件如何组织结构、彼此如何通信。系统工程则处在更高的一个层面。它问的是:系统作为一个整体必须做什么,软件、硬件和人类操作员之间如何分工,以及你将如何证明最终建成的东西确实可用。这门学科的专业归属是 INCOSE(国际系统工程理事会),其奠基性标准是 ISO/IEC/IEEE 15288,该标准定义了系统整个生命周期的各项流程。
这一点对大型企业和政府项目尤为重要,因为它们的系统体量庞大、生命周期漫长,且往往安全攸关或使命攸关。一个国防平台、一套空中交通管制系统,或一个卫星星座,会把定制硬件、第三方零部件、嵌入式软件与云软件,以及人类操作员融合在一起,没有任何一个团队能够把整个系统装在脑子里。你也经常要构建一个系统的系统:由许多各自独立、各自有用的系统组成,它们必须协同工作才能交付更大的能力。
本章与软件需求(第 2.8 章)、架构基础(第 3.1 章)、软件模型与方法(第 2.12 章)、互操作性与开放标准(第 3.8 章),以及项目管理(第 10.6 章)等内容相关联。
关键原则
- 要工程化整体,而不只是各个部分。 一个系统的成败取决于整体,因此孤立地优化某个子系统,反而可能让整体变得更糟。
- 遵循生命周期。 一个系统的生命,从最初的概念一直延续到最终退役。要为全过程做规划,而不仅仅是构建阶段。
- 追溯每一项需求。 每一项需要都应当映射到一项需求、一个设计元素和一项测试上。如果你无法追溯它,你就无法证明它。
- 有意识地管理接口。 大多数故障发生在各部分之间的边界处,因此接口理应有明确的归属和管控。
- 验证与确认要分开进行。 “把事情做对”(验证)和“做对的事情”(确认)是两个不同的问题,你需要同时得到这两个问题的答案。
- 预料到涌现行为的出现。 各部分组合在一起会产生任何单一部分都不具备的行为。其中一些正是设计的初衷,另一些则是令人不快的意外。
- 硬件与软件要协同工程化。 当两者都是定制的时候,一方的决策会制约另一方,因此要把二者放在一起规划。
建议
管理完整的系统生命周期
把系统看作拥有完整生命的事物,并为每个阶段做规划。一个常见的生命周期依次为:概念阶段(理解需要并探索各种选项)、需求阶段(精确表述系统必须做什么)、设计阶段(确定架构和各个组成部分)、集成阶段(把各部分组合到一起)、验证与确认阶段(证明它能用、且是正确的系统)、运行阶段(运行并维护它),以及退役阶段(安全地停用它,包括数据和处置事宜)。ISO/IEC/IEEE 15288 为此提供了一套流程框架。这些阶段不必是一个僵化的单向瀑布流程;你可以迭代、做原型,并分增量交付。关键在于,你要有意识地面对每一个阶段()包括那些早期计划常常忽略、代价高昂的后期阶段。
收集利益相关者需要,并带着可追溯性分配需求
从关心这个系统的人开始:用户、操作人员、所有者、监管机构和公众。先用平实的语言收集他们的需要,再把这些需要转化为具体、可测试的工程化需求(参见第 2.8 章)。接下来是需求分配:把每一项系统级需求分配给某个具体的子系统,这样你就知道哪个部分负责满足它。要维护一份可追溯性矩阵()一份持续更新的记录,把每一项需要与其需求、满足它的设计元素,以及验证它的测试关联起来。有了它,你可以在任何时刻证明每一项需要都得到了覆盖,每一个部分的存在都有其理由。
显式地管理接口
接口是各部分相遇的地方,也是系统最常出故障的地方。接口可以是一个物理连接器、一个网络协议、一种数据格式,或者一套人工流程。对每一个接口,都要撰写一份接口控制文档(ICD):一份就两个部分如何连接和交换信息达成一致的规范说明。为每一个接口的双方都指定明确的归属人。依靠共享、已发布的规范,而不是一次性的定制连接器,会让集成工作容易得多()这正是第 3.8 章所论证的互操作性观点。在可能的情况下尽早冻结接口,因为一次后期变更会波及所有接触到它的部分。
先集成,再验证与确认
系统集成把各个子系统组合成一个可运行的整体,通常是分阶段进行,而不是一次性完成,这样你能在问题还很小的时候就发现它们。集成之后是验证与确认(V&V),这是两项不同的检查。验证问的是:我们是否把系统做对了,也就是说它是否满足其规定的需求?验证通过检查、分析、演示和测试来完成。确认问的是:我们是否做了对的系统,也就是说它是否满足利益相关者在实际使用中的真实需要?一个系统可能通过验证(符合规格),却在确认上失败(规格本身就是错的)。要从一开始就规划这两项工作,并且要把需求和接口写得让它们本身就可以被验证。
采用基于模型的系统工程
传统的系统工程会产生堆积如山、彼此逐渐脱节的文档。基于模型的系统工程(MBSE)用一个单一的、共享的、形式化的系统模型取代了这堆文档,各种视图和报告都从这个模型中生成。通用的建模语言是 SysML(系统建模语言),一种用于描述系统需求、结构、行为和约束的图形化语言。由于一切都存在于一个相互关联的模型中,一次变更会在各处同步更新,可追溯性也从一项人工追查工作变成了一次查询操作。MBSE 与第 2.12 章中的建模理念相互关联。要循序渐进地采用它,从风险最高、共享模型能最快带来回报的部分入手。
用系统思维应对涌现行为
要践行系统思维:对整体以及各部分之间的关系进行推理,而不是逐个孤立地思考各个部分。这正是你预见涌现行为的方式:那些只有在各部分组合起来之后才会出现、任何单一部分都不具备的属性。良性的涌现往往正是系统存在的目的所在(一群无人机能够覆盖任何单架无人机都无法覆盖的区域)。恶性的涌现则是意外的故障(两个各自安全的子系统相互作用,产生出一种危险状态)。对于一个你从未建模过的系统,你无法把涌现行为测试出来,因此要借助仿真和结构化的危害分析,在系统投入运行之前把它找出来。
硬件与软件协同工程化
当一个系统包含定制硬件时,要让硬件和软件协同进行工程化,这种做法被称为软硬件协同设计。二者的决策彼此制约:硬件设定了软件必须遵守的时序、内存和功耗上限,而软件的需求也塑造着硬件必须提供的能力。漫长的硬件交付周期也往往主导着整个项目的进度安排。要尽早决定哪些功能放在硬件上实现、哪些放在软件上实现,并随着各种约束的显现不断重新审视这一划分。
权衡:优缺点对比
| 方法 | 优点 | 缺点/成本 |
|---|---|---|
| 完整严谨的系统工程 | 后期意外更少,可追溯性强,更安全、可审计 | 前期成本高,启动慢,流程繁重 |
| 轻量级/纯软件方式 | 快速、低成本,适合小范围场景 | 在大型多学科系统上会失效,会遗漏接口和涌现问题 |
| 基于模型(MBSE) | 单一事实来源,追溯性容易实现,视图一致 | 工具和培训成本高,需要文化变革,存在学习曲线 |
| 基于文档的系统工程 | 熟悉、工具成本低、易于分享 | 文档会逐渐脱节,可追溯性依赖人工、容易出错 |
其中核心的权衡在于严谨性与速度之间的取舍。完整的系统工程把大量精力前置投入到概念、需求和接口工作中。在大型、长期存续、安全攸关的系统上,这份投入会带来数倍的回报,因为一个在运行阶段才被发现的缺陷,其代价可能是在需求阶段发现同一个缺陷的成百上千倍。而在一个小型、短生命周期、纯软件的产品上,这种严谨程度就是杀鸡用牛刀。要让流程的力度与系统的规模、生命周期和风险相匹配。常见的失败模式,是把一次性项目的习惯套用到一个要运行三十年、并承载真实世界风险的系统上。
与团队讨论的问题
在哪些情况下,你严格按照规格说明的要求构建,最终交付出来的却仍是错误的系统?当时什么措施本可以发现这一点? 验证(我们是否把它做对了)和确认(我们是否做了对的东西)回答的是不同的问题,一个系统完全可能通过每一项验证测试,却因为规格说明本身就是错的而未能通过确认。在大型项目中,这两者常常被混为一谈的“测试”,导致直到很晚才有人对照真实的操作者需求进行确认()而这时候一次修复的代价可能是一次需求变更的成千上万倍。找出一个过去的例子,交付的系统满足了需求却没有满足实际的需要,并思考什么样的确认活动(与真实操作者一起进行的仿真、在现场的早期原型)本可以更早地暴露这个问题。要从一开始就规划好这两项检查,并且把需求和接口写得让它们从根本上就是可验证的。这个区分决定了你稀缺的评审精力该花在哪里。
你是在系统投入运行之前,还是运行之后,才去排查恶性的涌现行为? 把各自安全的子系统组合在一起,可能产生出任何单一部分都不具备的危险状态,而对于一个你从未建模过的系统,你无法把涌现行为测试出来。对于安全攸关或使命攸关的项目而言,那种意外的相互作用,恰恰就是会伤人或导致任务失败的那一种,因此必须在系统正式投入运行之前把它找出来。说说你对整体建模的方法(仿真、结构化危害分析、能够捕捉相互作用的 SysML 模型),并问一问:哪些跨子系统的行为是你真正探索过的,哪些只是被想当然地忽略了?良性的涌现往往正是系统的目的所在,值得朝着它去设计;恶性的涌现则是你必须通过工程手段去防范的故障。如果你唯一的集成策略只是把各部分接在一起、看看会发生什么,那你其实是在计划着到生产环境中才去发现涌现行为。
交付周期长的硬件决策必须在什么时候冻结?这个截止日期如何驱动你的软件进度安排? 当一个系统包含定制硬件时,二者必须协同工程化:芯片设定了软件必须遵守的时序、内存和功耗上限,而硬件的交付周期往往主导着整个项目进度。把软件当作可以独立处理的团队,会进行局部优化,然后在集成阶段与硬件约束发生冲突,白白损失数月时间。说说硬件的交付周期,以及必须敲定软硬件功能划分的日期,并随着各种约束的显现不断重新审视这一划分,而不是盲目地一次性冻结。你越早决定哪些功能放在芯片上、哪些放在软件上,你所面临的代价高昂的反复就越少。软硬件之间的接口理应有一份接口控制文档和双方各自的归属人,因为那里的一次后期变更会波及所有接触到它的部分。
你能否把某一项利益相关者的需要,一路追溯到需求、设计元素,以及证明它的测试?谁在维系这条链条? 可追溯性让你能够在任何时刻证明每一项需要都得到了覆盖、每一个部分的存在都有理由,但在一个大型项目中,只要无人负责,这份矩阵会立刻开始腐坏。这里存在着真实的拉锯:工程师会把可追溯性体验为一种官僚式的负担,而一份靠人工维护的矩阵,其过时速度往往快于设计本身的变化速度。找出当前项目中一条真实的线索,尝试在会议室里从头到尾完整地走一遍()从一位具名利益相关者的需要,到分配到的需求,到满足它的子系统和设计元素,再到验证测试,并记下链条在哪里断裂。决定谁拥有这份矩阵的所有权,以及它是否应当存在于一个模型中()在那里可追溯性是一次查询,而不是一场人工追查。对企业和政府项目而言,这份矩阵还是监管机构和采购当局所要求的审计凭证,因此一条断裂的链条不仅会拖慢工程进度,还可能使认证或付款陷入停滞。
基于模型的方法,对你来说,其工具和文化成本是否值得投入?还是说它会变成昂贵的摆设? 基于文档的系统工程为人熟悉、工具成本低,但其文档会逐渐脱节,可追溯性依赖人工、容易出错;MBSE 用一个相互关联的模型取代了这堆文档,代价是工具、培训以及真正的文化变革。两个极端都代价高昂:在一个大型多学科项目上跳过 MBSE,你会在集成阶段付出意外的代价;采用了 MBSE 却没有保持模型持续更新的纪律,它就会腐坏成比没有模型更糟糕的摆设。说说你对自身工具成熟度的真实评估、团队中真正能够撰写并维护 SysML 模型的人是谁,以及哪一个高风险子系统适合作为试点()共享模型能在那里最快带来回报。要循序渐进地做出决定,而不是一次性在整个组织内强制推行。对于拥有众多供应商的大型企业或政府项目,要权衡:共享模型是否是唯一现实可行的方式,能让需求、接口和测试在各个承包商之间保持一致()否则他们之间交换的往往是过时的文档。
你的生命周期计划是否真正为运行和退役阶段提供了资金?还是说它悄悄地在上线那一刻就结束了? 主导长期存续系统总成本的那些阶段()运行数十年,以及安全地退役()恰恰是早期计划经常忽略的阶段,因为压力总是集中在按时交付上。与之相互竞争的现实是,恰恰在这些后期阶段看起来最遥远的时候,资金和关注度也最为稀缺,于是运行、维护、数据迁移和处置就被一再推迟,直到变成一场代价高昂、风险重重的仓促应对。找出当前的生命周期计划,检查它是否为运行和退役阶段指定了负责人、预算和退出标准,还是把上线当作了终点线。问一问系统生命终结时数据和硬件将何去何从,以及在这期间数年的维护费用由谁承担。对于必须运行二十年或三十年、然后在公众监督下退役的企业和政府系统而言,一次没有计划的停用可能违反监管、环保或记录留存方面的义务,因此退役从第一次概念评审开始就应当被纳入计划和预算。
行业视角
初创企业。 一个小团队无法运行一套正式的系统工程项目,也不应该去尝试,但它仍然可以把固件、应用和云端当作一个系统来对待,而不是三个独立的项目。撰写一份简短的接口文档,明确各部分之间如何通信,维护一张简单的表格,把每一项客户需要与满足它的部分关联起来,并跳过繁重的流程。你最稀缺的资源是工程关注力,因此可追溯性方面的投入,只应花在边界处的一个错误假设会悄悄破坏产品实际运行效果的地方。
小型企业。 在没有专职系统工程师、预算又紧张的情况下,要依靠已发布的标准和购买来的子系统,而不是自己去设计和验证定制化的集成工作。优先选择那些公开清晰接口规范的供应商,这样各部分就能自然契合,而不必拥有一个需要你永远维护下去的定制连接器。围绕在产品的整个生命周期内你能够真正掌控并验证哪些接口来构建“自建还是购买”的决策框架,其余部分则直接购买。
企业。 在这种规模下,问题在于跨众多团队和供应商的一致性:一套与 ISO/IEC/IEEE 15288 对齐的共享生命周期流程、每一个供应商边界都有一份接口控制文档和一位具名负责人,以及端到端的可追溯性,使一次组件变更不会引发全项目范围的仓促应对。要在共享模型能让需求、接口和测试在各承包商之间保持一致的地方投资 MBSE。治理好这一流程,使验证与确认保持区分,且每一项需求都被分配给一个负责的部分。
政府。 采购规则、透明度和公共问责制塑造着每一个选择。要在合同中明确规定系统工程流程、可追溯性和 V&V 证据,要求供应商交付你可以审计的接口控制文档和生命周期工件,并在任何正式切换之前,为安全和使命方面的确认工作留出由真实操作人员参与的独立评审环节。要明确规划并为运行和退役阶段提供资金,因为一个公共项目要对整个生命周期负责,包括安全退役和记录留存。
示例
初创企业。 一家四人组成的硬件初创公司正在构建一款联网传感器,负担不起一套正式的系统工程项目,但它仍然把产品当作固件、移动应用和云端后台组成的一个系统来对待,而不是三个独立的项目。他们撰写了一份简短的接口文档,明确设备、应用和服务器之间如何通信(消息格式、单位、错误代码),并维护一张简单的表格,把每一项客户需要与满足它的部分关联起来。当更换更便宜的传感器芯片迫使固件发生变更时,这份共享接口文档立刻显示出应用和后端需要做出哪些调整,因此一次组件替换不会悄悄破坏产品在实际使用中的表现。
企业。 一家全球汽车制造商正在构建一个新的电动车平台:一个由软件(电池管理、驾驶辅助、信息娱乐系统)、硬件(电机、传感器、芯片)和人因工程组成的系统,还有众多供应商各自交付子系统。该公司运行着一套系统工程项目。利益相关者的需要被输入到已分配的需求中,每一个供应商接口都有一份接口控制文档,一个 SysML 模型把需求、设计和测试串联在一起。当某个电池芯供应商更换某个组件时,可追溯性模型能准确显示哪些需求、接口和测试受到了影响,因此这次变更被控制在局部,而不会引发全项目范围的仓促应对。
政府。 某国家空中导航管理局正在对其空中交通管理系统进行现代化改造()这是一个安全攸关的系统的系统,涵盖雷达、管制员工作站、通信设备和软件,需要全天候运行。该项目在整个生命周期中遵循 ISO/IEC/IEEE 15288 标准。验证证明每个子系统都满足其规格说明,而与真实管制员一起进行的仿真确认,则在任何实时交通依赖于该系统之前,证明这个集成后的系统能够支持安全运行。严谨的 V&V 让该管理局能够分阶段完成切换,每一步都留有回退方案,因为在这里,一次未经测试的涌现故障就是一起公共安全事件。
商业论证:动机、投资回报率与总拥有成本
其动机在于:缺陷被发现得越晚,代价就呈指数级上升。一个在需求阶段就被发现的需求错误,修复成本几乎为零。同样的错误如果在运行阶段才被发现,代价可能是前者的成千上万倍,而在一个安全攸关的系统上,它甚至可能付出生命、召回或任务失败的代价。系统工程把缺陷的发现时机,推向了成本低廉的早期阶段。
就投资回报率(ROI,所获价值与所花成本的比较)而言,回报体现为避免了返工、减少了集成失败,以及项目能够按期、按预算完成,而不是超支超期。对大型项目的行业研究反复发现,扎实的系统工程投入与更小的超支幅度相关。就总拥有成本(TCO,构建、运行和退役一个系统的全生命周期成本)而言,系统工程照顾到了主导长期成本、却往往被临时性项目所忽视的运行和退役阶段。从一开始就为可维护性、接口和处置进行设计,会降低系统在服役数十年间的成本。参见项目管理(第 10.6 章)。
反模式与常见陷阱
- 没有迭代的大规模前期设计。 把生命周期当作一个僵化的单向瀑布流程,结果只有在把一切都建完之后,才发现需求原来是错的。
- 没有可追溯性的需求。 一堆无人与设计或测试关联起来的需求,因此你既无法证明覆盖情况,也无法为任何部分的存在辩护。
- 忽视接口。 想当然地以为各子系统能够自然契合,结果在集成阶段因无人负责的边界不匹配而损失数月时间。
- 只有验证没有确认。 证明系统满足其规格说明,却从未检查这份规格说明是否契合真实需要,结果交付出错误的系统。
- 把软件当作独立事项对待。 软件团队只做局部优化,却忽视硬件约束、时序和人类操作员。
- MBSE 沦为摆设。 只建一次模型,然后任由它逐渐脱节,最终比没有模型还要糟糕。
- 跳过退役规划。 没有停用、数据迁移或处置的计划,导致生命终结时变成一场代价高昂、风险重重的仓促应对。
成熟度模型
第 1 级:启动。 系统工程是临时性、被动式的。需求散落在各处文档中,接口是在集成阶段才被发现的,验证工作则是随便做到什么程度算什么程度。大型项目经常超支超期,并在后期给团队带来意外。
第 2 级:发展。 主要项目中存在一些基本实践。需求被收集并纳入基线,关键接口有控制文档,并且存在一份验证计划。但各团队之间的实践并不一致,依赖于个人而非共享的方法。
第 3 级:标准化。 系统工程是一门有文档记录、全组织统一、与 ISO/IEC/IEEE 15288 对齐并在各团队中强制执行的学科。完整的生命周期得到规划,可追溯性得到端到端维护,接口得到正式管控,验证与确认相互区分并且都经过规划。复杂项目中使用 MBSE。
第 4 级:管理。 系统工程依据数据进行度量和管控。组织依照基线追踪各项指标:需求波动性和可追溯性覆盖率、在集成阶段发现的接口缺陷、验证与确认的通过率,以及按生命周期阶段划分的缺陷逃逸率(有多少缺陷从某个阶段逃逸、要到之后以更高代价才被发现)。评审会依据这些数据来引导项目,阈值会触发纠正措施,而不是事后救火。
第 5 级:协同。 系统工程在整个组织范围内持续改进并相互集成。一个持续更新的 MBSE 模型是唯一的事实来源,可追溯性是自动化的,仿真在构建之前就能预测涌现行为,来自以往项目的指标反哺下一个项目。硬件和软件的协同工程化已成为常态,流程也随着项目、供应商和风险的变化而不断调整。
讨论思路
- 在你的组织中,系统工程与软件架构之间的界线在哪里?谁负责管理二者之间的空间?
- 在你规模最大的项目中,你能否把某一项利益相关者的需要一路追溯到验证它的那项测试?如果不能,需要具备什么条件才能做到?
- 你最近的哪些故障发生在接口处?归属人是谁?
- 对你而言,MBSE 会带来回报,还是会因为你的文化和工具条件而变成昂贵的摆设?
- 你的生命周期计划是否认真处理了运行和退役阶段?还是悄悄地在上线时就止步了?
要点总结
- 系统工程端到端地工程化整个系统(软件、硬件、人员和流程),与软件架构是两回事。
- 要规划完整的生命周期,从概念阶段到需求、设计、集成、V&V、运行,再到退役。
- 把每一项需要追溯到一项需求、一个设计元素和一项测试,并把每一项需求分配给一个负责的部分。
- 通过明确的归属和控制文档,显式地管理接口,因为边界正是系统出故障的地方。
- 验证(做对了这件事)与确认(做了对的事情)是两种不同的检查,二者都不可或缺。
- 使用 MBSE 和 SysML 来获得一个相互关联的单一事实来源,并运用系统思维去预见涌现行为。
- 让流程的力度与系统的规模、生命周期和风险相匹配。
参考文献与延伸阅读
- INCOSE 编,INCOSE Systems Engineering Handbook: A Guide for System Life Cycle Processes and Activities
- ISO/IEC/IEEE 15288,Systems and Software Engineering: System Life Cycle Processes
- ISO/IEC/IEEE 29148,Systems and Software Engineering: Requirements Engineering
- Sanford Friedenthal、Alan Moore 和 Rick Steiner 合著,A Practical Guide to SysML: The Systems Modeling Language
- NASA 编,NASA Systems Engineering Handbook(NASA/SP-2016-6105)
- Andrew P. Sage 和 William B. Rouse 合著,Handbook of Systems Engineering and Management
- Dennis M. Buede 和 William D. Miller 合著,The Engineering Design of Systems: Models and Methods
- Donella H. Meadows 著,Thinking in Systems: A Primer
- Eberhardt Rechtin 和 Mark W. Maier 合著,The Art of Systems Architecting
- 美国国防部编,Defense Acquisition Guidebook(系统工程指南)