3. 需求分类与层级结构建模
在SysML需求建模中,需求不是一张平铺的清单,而是一棵有类型、有方向、有追溯关系的树。分类决定了每条需求“是什么”,层级结构决定了需求之间“谁支撑谁”。如果分类混乱,后续的验证用例就无法准确挂接;如果层级断裂,追溯链就会在某个中间层失效,导致验证覆盖出现盲区。本节围绕五类需求的判别方法,以及包含、派生、细化三种关系的建模规则展开。
一、五类需求的判别标准
SysML本身不强制规定需求类型,但工程实践中通常按以下五类组织,每类都有明确的判别特征:
- 功能需求:描述系统“做什么”,通常包含动作动词和可观测的输入输出。例如“无人机在接收到返航指令后,应在3秒内切换至返航模式”。判别要点是存在明确的行为响应。
- 非功能需求:描述系统“做得怎么样”中的质量属性,如可靠性、安全性、可维护性、可用性。例如“飞控计算机的平均无故障时间不低于5000小时”。它不直接对应某个动作,而是约束整体行为。
- 性能需求:非功能需求中可量化的子集,包含明确的指标、数值和容差。例如“巡航速度不低于60 km/h,最大爬升率不小于5 m/s”。性能需求必须可测量,否则应归入一般非功能需求。
- 接口需求:描述系统与外部或内部组件之间的交互约定,包括数据格式、协议、电气特性、时序。例如“飞控计算机通过CAN总线以500 kbps向舵机控制器发送指令,周期20 ms”。
- 约束需求:描述设计或实现必须遵守的限制,通常来自标准、法规、物理限制或项目决策。例如“整机质量不超过2.5 kg”“必须符合DO-178C Level C”。约束需求不描述行为,而是划定可行域。
判别时容易混淆的是功能需求与性能需求。一条需求如果同时包含动作和指标,例如“在2秒内完成姿态解算”,应拆分为两条:功能需求“系统应完成姿态解算”,性能需求“姿态解算时间不超过2秒”,再通过细化关系关联。这样拆分后,验证用例可以分别针对功能和性能设计,避免一条需求对应多个验证方法。
二、三种层级关系的语义与建模
SysML需求图提供三种核心关系,它们的语义不同,不能混用:
包含(containment):表示父需求由若干子需求组成,子需求是父需求的必要组成部分。父需求通常较抽象,子需求覆盖其全部内容。例如“导航系统需求”包含“定位需求”“路径规划需求”“导航显示需求”。包含关系是“整体—部分”,删除任一子需求都会导致父需求不完整。
派生(derive):表示子需求从父需求推导而来,通常发生在层级下移或设计决策之后。派生需求可能引入父需求中没有的新信息。例如从“整机质量不超过2.5 kg”派生出“电池质量不超过0.8 kg”,后者是前者在电池子系统上的分配结果。派生关系是“来源—推导”,父需求是子需求的依据。
细化(refine):表示一条需求对另一条需求的补充说明,不改变原需求的范围,只增加细节。例如“通信需求”被“通信协议采用CAN 2.0B”细化。细化关系常用于将抽象需求逐步具体化,但不产生新的需求层级。
建模时,包含关系用于构建需求分解结构(RBS),派生关系用于跨层级追溯,细化关系用于挂接设计细节和验证方法。三者可以组合使用:一个父需求先包含若干子需求,子需求再派生出更低层的需求,同时被测试用例细化。
三、构建可追踪需求分解结构的操作要点
在实际建模工具(如Cameo Systems Modeler、Enterprise Architect或Rhapsody)中,需求分解结构通常以需求图或需求表的形式呈现。构建时建议遵循以下操作顺序:
- 先分类,再分层:拿到一组原始需求后,先逐条标注类型(功能/非功能/性能/接口/约束),再按系统层级(整机→分系统→组件)组织包含关系。分类不清会导致后续派生方向错误。
- 包含关系只用于同类型分解:父需求与子需求应属于同一类型。例如功能需求包含功能子需求,性能需求包含性能子需求。跨类型分解应使用派生或细化,否则会破坏类型一致性。
- 派生关系必须标注来源:每条派生需求都应能回答“从哪条需求推导而来”。在SysML中通过«derive»依赖指向父需求,工具会自动生成追溯矩阵。
- 细化关系挂接验证用例:细化关系常用于将需求与测试用例、设计参数或仿真模型关联。例如“姿态精度±0.5°”被“测试用例TC-021”细化,表示该用例验证此需求。
- 检查追溯链完整性:从顶层需求出发,沿包含和派生关系向下遍历,确保每条叶子需求都有明确的父需求;从底层向上回溯,确保每条需求都能追溯到顶层。断裂处即为追溯盲区。
- 每条需求是否已标注唯一类型?
- 包含关系的父子需求是否同类型?
- 派生需求是否标注了来源需求?
- 细化关系是否指向了验证用例或设计参数?
- 是否存在无父需求的“孤儿需求”?
- 是否存在无子需求的“悬空父需求”?
- 追溯矩阵中是否存在空白单元格?
四、常见错误与修正
初学者最容易犯的错误是把包含、派生、细化混为一谈。例如,将“整机质量不超过2.5 kg”直接包含“电池质量不超过0.8 kg”,这在语义上不成立——电池质量不是整机质量的组成部分,而是从整机质量约束派生出的分配结果。正确做法是使用«derive»,并在属性中注明分配依据(如“按电池占总质量32%估算”)。
另一个常见问题是性能需求与功能需求混写。例如“飞控计算机应在20 ms内完成一次控制律计算”,这条需求同时包含功能(控制律计算)和性能(20 ms)。应拆分为两条需求,再用细化关系关联。拆分后,功能需求可以独立验证“是否完成计算”,性能需求可以独立验证“是否在20 ms内完成”,验证方法更清晰。
接口需求也容易被忽略。很多团队把接口细节写在功能需求里,导致接口变更时功能需求频繁修改。正确做法是将接口需求独立建模,用«refine»挂接到相关功能需求上。这样接口协议升级时,只需修改接口需求,功能需求保持不变。
约束需求则常被当作“备注”处理,不纳入追溯链。但约束需求往往来自适航标准或客户合同,必须可追溯。例如“符合DO-178C Level C”应作为独立约束需求,并通过«refine»关联到软件开发和验证活动,确保审查时能提供符合性证据。