1. 先想清楚再动手为什么汽车需求必须模块化做汽车电子需求管理这些年我见得最多的场面就是项目启动时一份几百条的Word/Excel需求文档满天飞供应商拿着PDF来回确认测试团队对着表格逐条设计用例。等到第一轮设计评审需求解释不一致、追溯链断裂、变更影响分析靠拍脑袋问题就像雪球一样越滚越大。最后大家坐在一起开会第一句话往往是“这条需求到底是谁的”——这句话一出来基本就说明需求管理已经失控了。DOORS全称是IBM Engineering Requirements Management DOORS在汽车、轨交、航空航天这些安全相关的行业里基本属于标配工具。它最核心的能力其实就两件事一是把需求当成“对象”来管理每个对象有自己的属性、状态、版本二是通过链接把需求、设计、测试之间的追溯关系显式记录下来。但工具再强也架不住用的人思路混乱。DOORS最常见的使用误区就是把它当成“带数据库的Word”需求一股脑堆在同一个模块里这跟用Excel管理需求本质上没有区别。真正让DOORS发挥价值的是模块化需求拆分。这个概念说起来不复杂把一个复杂系统的需求按照某种清晰的边界拆分成若干需求模块每个模块内部高内聚、模块之间低耦合然后在模块之间用链接建立关系。听起来很像软件工程里的模块化设计事实上它就是。但放到汽车行业里需求模块化不只是“拆分文档”那么简单它直接决定了后续设计、测试、变更管理的效率甚至影响项目能不能通过ASPICE评审。这篇文章我会用一个具体的汽车设计案例——乘用车灯光控制系统的需求管理把模块化拆分的完整思路、DOORS里的实操步骤、我踩过的坑一次讲清楚。适合正在做汽车电子/软件需求管理、刚接触DOORS的工程师也适合被需求混乱折磨了很久想找方法论的团队。2. 案例开局一套灯光控制系统需求有哪些“拆”的潜力2.1 原始需求清单长什么样假设我们现在要管理一套乘用车灯光控制系统的需求。传统的做法需求工程师会从客户那边拿到一份类似下面的需求清单系统需求 SR-01当车辆电源处于ON挡时系统应能根据灯光开关状态控制各外部灯具的亮灭。系统需求 SR-02当开启近光灯时近光灯应点亮关闭近光灯时近光灯应熄灭。系统需求 SR-03当开启远光灯时远光灯应点亮当切换至近光灯时远光灯应熄灭。系统需求 SR-04当转向灯开关拨至左侧时左侧转向灯应以1Hz±0.2Hz频率闪烁。系统需求 SR-05危险报警开关按下后所有转向灯应同时以1Hz±0.2Hz频率闪烁。系统需求 SR-06当环境光传感器检测到光线不足且近光灯未开启时系统应自动开启近光灯。系统需求 SR-07系统应支持CAN总线诊断功能诊断开启近光灯时应能控制近光灯点亮。系统需求 SR-08灯光控制软件应在车辆上电后500ms内完成初始化。乍一看这份清单好像没什么问题每条都是一句通顺的“系统应……”。但如果你把它放进一个真实的DOORS模块里很快就会发现几个致命问题。第一层级混乱。SR-01像是总体要求SR-02和SR-03像是近光/远光功能要求SR-04和SR-05是转向灯和警示灯功能要求SR-06是自动灯光功能要求SR-07是诊断功能要求SR-08又变成了非功能性的性能要求。这些需求根本不在同一抽象层级上混在一个模块里后面的追溯、分配、评审全都会受影响。第二单一职责被破坏。SR-07既描述了诊断功能的开启一种诊断控制方式又描述了近光灯点亮这一物理动作。这条需求实际横跨了“诊断服务”和“灯光执行”两个功能域当近光灯的执行逻辑发生变化时这条需求被要求变更当诊断协议升级时这条需求又可能被要求变更。一条需求挂在两条变更链路上这就是变更管理混乱的根源。第三缺少可验证的边界。SR-01里“控制各外部灯具的亮灭”这种描述在实际测试时根本没法直接验证——是验证控制策略还是验证灯具驱动的PWM输出边界不清晰测试用例设计就没有依据。2.2 这套系统的“真实全景”我们往后退一步看看这套灯光控制系统在整车架构里到底涉及哪些东西。以一台普通的乘用车为例输入类灯光开关组合开关、转向灯拨杆、危险报警开关、环境光传感器、CAN总线信号来自BCM或网关控制类灯光控制器可能集成在BCM里也可能是独立的灯光控制模块LTM执行类近光灯、远光灯、位置灯、日间行车灯、前后转向灯、雾灯、制动灯等外部灯具通信类CAN/LIN总线网络负责信号交互与诊断。仅这个范围就涉及“输入采集—控制逻辑—执行输出—通信诊断”四个不同的技术层面。如果需求不按这些层面做拆分和归位工程师拿到SR-07这种混合型需求时就会很头疼软件工程师不知道自己要实现的是诊断服务还是灯控逻辑硬件工程师不知道这条需求是否影响引脚设计测试工程师也不知道该从哪个接口去验证。其实需求模块化的核心原则就是按“功能内聚 技术分层”来做边界划分而不是按人来分更不是按文档类型分。灯光系统就按“开关/传感器输入、灯控功能逻辑、执行输出、诊断通信”拆成几个功能域再让每个功能域内部的需求形成一个高内聚的模块。3. 在DOORS里落地模块怎么建属性怎么定3.1 DOORS文件夹结构和模块类型选择DOORS里的基础单位是Module模块模块放在Folder文件夹里这个结构决定了你整个项目的需求组织方式。很多团队第一次建库时图省事直接在根目录下建了一个名为“灯光系统需求”的模块然后所有层级的需求像倒豆子一样倒进去。这正是后面所有混乱的起点。DOORS里有两类模块Formal Module正式模块和Composite Module复合模块。Formal Module是真正存放需求对象的模块每个对象有唯一ID如REQ-001、属性、历史记录Composite Module是视图性质的模块它只是把多个Formal Module中的对象链接起来展示本身不存数据。我做车辆项目时通常建议的目录结构是01_系统需求Formal Module存放整车/系统级需求02_功能需求Formal Module按功能域拆分如灯控功能、诊断功能03_软件需求Formal Module对应软件单元需求04_硬件需求Formal Module对应硬件接口需求05_测试需求Formal Module或者直接建立到测试工具链的链接形式上是多个Formal Module逻辑上通过链接串成一条从系统到零部件的需求链。这样做的价值在后面做影响分析时才会真正体现出来当某条系统需求变更时通过链接就能直接看到它影响了哪些软件需求、哪些硬件需求、哪些测试用例一张图全出来不用再把几个文档翻来翻去。3.2 属性表设计先把“元数据”框架搭好DOORS模块的威力一大半在属性Attribute上。属性就是贴在每条需求上的标签支持排序、过滤、生成报表。很多团队DOORS用得浅就是因为属性设计得太随意系统只放了“需求文本”和“编号”两个字段其他信息全写在需求文字里——这等于把数据库当记事本用。我常用的属性方案至少包含以下几类属性名类型用途示例需求编号Text系统自动REQ-001DOORS自动生成不可变需求摘要Text一句话描述本条需求的要点方便报表展示需求类型Enumeration功能需求/性能需求/接口需求/约束/非功能需求优先级EnumerationHigh/Medium/Low影响排期来源TextCustoDoc_2023_v2.0-SR-001记录需求出处分配对象EnumerationSW/HW/System/Test标识责任方验证方法Enumeration测试/检查/分析/演示当前状态EnumerationProposed/Approved/Implemented/Verified创建人/创建时间Text/Date审计用ASPICE评审常用属性这块有个很容易犯的错一上来就把属性表设计得特别庞大二十多个字段结果录入需求时大部分字段没人填。我建议起步阶段只保留上面这些必要字段等团队用顺了再逐步扩展。属性设计的本质是“给需求建立元数据”元数据足够时DOORS的Filter功能才能发挥作用比如“筛选出所有High优先级且尚未Approved的需求”一条查询就能拉出清单这在需求评审会上非常有用。3.3 层级与对象结构的组织逻辑在DOORS里Module内是通过对象Object的层级结构来组织的。默认情况下每个Formal Module内是一个树状结构树根可以是章节标题子节点是具体需求。很多第一次用DOORS的工程师会把“章节标题”也写成需求对象这样在链接追溯时会出现噪声。正确做法是节点对象用于组织章节如“3 近光灯控制”叶子对象才是真正的需求条目如“3.1 当近光灯开关闭合时近光灯继电器应导通”。这样做的原因很简单链接是挂在对象上的如果章节节点也变成需求那么从上级模块追踪下来时一个“章节节点”会被当作需求处理报表中会出现大量无意义的链接项。我见过有人把链接建在标题对象上导致追踪矩阵里出现“标题对标题”的映射真正该追溯的需求反而断链这个习惯一开始就要纠正。4. 七个步骤把需求拆成能直接驱动设计的模块有了上面的基础认知下面进入实操环节。我按真实项目里一步步推进的方式把模块化需求拆分的过程拆成七个步骤每一步都会说明操作细节和判断标准。4.1 第一步需求分类与“洗澡”不管原始需求是客户给的WORD还是从其他格式导入的先用一个临时模块把全量需求过一遍给每条需求做分类标签。这是需求清洗的过程目的不是改内容而是搞清每一条到底属于什么类型、处于什么层级。我常用一个很朴素的三分类法系统级需求描述整车/子系统层面的总体行为或约束不涉及具体软硬件实现例如“灯光系统应在所有电源状态下满足相应功能策略”功能级需求描述一个可观察的功能行为例如“自动大灯功能应依据环境光传感器的信号判断是否点亮近光灯”非功能约束描述性能、安全、通信协议、环境适应性等限制条件例如“灯光控制软件应在车辆上电后500ms内完成初始化”。分类是为了后续决定“这条需求应该放在哪个模块”。分类不清晰时宁可多开会讨论也不要急着入库因为分类决定了模块间的边界后面再调整的代价远大于前期讨论。4.2 第二步建立DOORS库的模块骨架根据第一步的分类结果创建正式模块。按照灯光系统的案例我建议至少建立以下模块模块名称内容定位01_灯光系统需求系统级需求整车/系统行为与约束02_灯控功能需求近光/远光/转向/警示/自动灯等功能行为03_诊断与通信需求诊断服务、CAN/LIN通信相关需求04_硬件接口需求输入/输出引脚、负载驱动、电气特性05_软件需求软件单元级需求对应ECU软件设计注意模块拆分不是越细越好。我见过把“近光灯硬件接口”和“近光灯软件需求”都单独建模块的结果模块之间全是链接维护起来很费劲。合理的粒度是一个模块内的事物职责相近、变更频率相近、可由同一类工程师评审。灯控功能、诊断通信、硬件接口、软件实现这四类恰好对应不同角色的专业分工模块边界贴合组织协作边界运行起来最顺。4.3 第三步属性模板落地并配置列视图模块建好后按之前设计的属性方案创建属性模板。DOORS里可以创建Object Type定义一套默认属性集也可以直接给Module添加属性列。我建议先用Object Type管理这样后续新建模块时可以一键复用属性集。然后做一个列视图配置。DOORS默认打开的视图并不是很友好只显示ID和文本。从实际使用角度我配置的视图至少包含以下几列ID、需求摘要、需求类型、优先级、验证方法、分配对象、状态。这几列并排放在文本左边浏览时只看摘要就能知道这条需求的关键信息评审会上用投影仪过需求时效率极高。有个细节不要把所有属性列都堆到主视图上。DOORS的视图宽度有限列太多就看不到需求正文了。一般主视图放6~8个核心属性其余属性通过右键“Properties”查看。视图配置属于那种“磨刀不误砍柴工”的事情一次配好后续整个团队受益。4.4 第四步逐条拆分与细化这是最核心、最耗时的步骤。我把它总结成拆分五问每条需求都要过一遍这条需求是否只陈述了一个行为/约束单一职责这条需求是否可验证有一条明确的通过/不通过标准这条需求是否做了实现假设尽量避免“应通过XXX芯片实现……”之类这条需求抽象层级是否与模块一致放系统层的不要写软件细节放软件层的不要只写总体目标这条需求是否与已经存在的需求重复重复需求是后续变更管理最大的坑以最初那份清单里的SR-04“转向灯开关拨至左侧时左侧转向灯应以1Hz±0.2Hz频率闪烁”为例。按五问标准看它的问题在于“转向灯开关拨至左侧”是一种物理输入描述但实际整车网络里开关信号可能是通过LIN/CAN传给灯控单元的。如果这条需求放在“系统层”它是合理的如果是要分配给软件模块则应该改写成当接收到左转向开关激活信号时左转向灯输出应以目标频率1Hz允许偏差±0.2Hz进行周期性通断控制。“开关拨至左侧”变成“接收到左转向开关激活信号”从物理域转到了信号域“闪烁”变成“周期性通断控制”更贴近软件控制的验证方式。这就是需求细化的实际过程不是简单删改文字而是从验证角度把模糊描述变成边界清晰的可测描述。4.5 第五步建立模块间链接让追溯关系跑起来需求拆分到不同模块后模块之间必须通过链接建立关系否则就变成了“碎片化需求”比不拆还糟糕。DOORS里的链接是挂在对象上的可以理解为“从A对象指向B对象”的指针同时可以设置链接类型如Satisfy、Derive、Refine等。以灯光系统为例典型的链接流是这样01_灯光系统需求里的“系统应根据灯光开关状态控制灯具亮灭”链接到02_灯控功能需求里的“近光灯开启功能”“远光灯开启功能”“转向灯闪烁功能”等子需求02里的近光灯功能需求再链接到04_硬件接口需求里的“近光灯驱动接口需求”以及05_软件需求里的“近光灯控制算法需求”。判断一次需求拆分做得成不成功有一个很实用的标志从任意一条系统需求出发能否沿链接走通到对应的软件/硬件需求和测试用例。如果中间有断点或者某条系统需求没有向下链接那说明拆分有遗漏反之如果一条系统需求链接了一堆低层级需求那说明你对下层需求的粒度划分不够细还需要继续拆。4.6 第六步需求评审与基线管理拆分完成后需求文档准备进入评审。DOORS里评审是比较重的一个环节我通常的做法是用Filter筛出当前状态下需要评审的需求排除已Approved的历史需求利用DOORS的“Discussion”功能或者直接在对象上添加备注Note记录评审意见评审完成后把需求状态从Proposed改为Approved此时做一个基线Baseline把当前所有模块、对象、属性的状态固化下来。Baseline是DOORS里非常关键的概念可以理解成给整个需求库拍了一张快照。之后任何人修改需求都会在基线之上产生变化记录审计时能看到“哪个版本、改了什么、什么时候改的、是谁改的”。没有基线你就没有“需求版本”的概念出了歧义没法回溯。在汽车行业基线和审计追溯是ASPICE和功能安全评审的硬性要求所以从一开始就要养成打基线的习惯。4.7 第七步需求流转与状态机这一步是很多团队会忽略的。需求不是写完就结束了它需要在“草稿→评审中→已批准→已实现→已验证→关闭”这些状态间流转。DOORS允许通过DXL脚本DOORS的扩展语言自定义状态机或者用属性用户约定管理流转规则。我建议即使是小型项目也要在DOORS里用属性状态做流转管控。最简单的方法是约定任何人未经批准不得修改Approved状态的需求如果要改先把状态转成“Change Requested”然后经过评审重新批准。这看起来死板但能救命的。实际项目里最痛苦的场景就是某条需求被默默改了软件代码已经按新需求写了等到测试阶段才发现测试用例对应的是旧需求这时候整个测试基线已经乱套了。5. 实操中的高频踩坑DOORS模块化拆分常见问题速查我做了这么多年的需求管理自己踩过的泥坑不算少也看过很多新人在DOORS里走得磕磕绊绊。挑几个最典型的讲一讲多少能帮你绕开一些不必要的痛苦。5.1 用“Copy/Paste”代替链接这个错误几乎每个新手都会犯。当模块A里的需求需要在模块B里引用时有些人图省事直接把文本复制一份到B模块。表面上两者内容一样实际上两个对象完全独立没有任何关联。当A模块的源需求变更后B模块里的副本不会同步最终两份“看起来一样”的需求就悄悄分叉了。正确做法是把源需求留在原模块在B模块里通过链接Link引用它。DOORS里可以在B模块建立一条指向A模块对象的链接这样A里内容变更后B里能通过链接看到最新状态。记住一个原则同一份需求只允许一个“居住地”其他模块只能引用不能复制。这个原则坚持下来需求的一致性才有保障。5.2 过度拆分拆出一堆僵尸模块模块化拆分强调“不过度”也很重要。前面说按功能域拆分但如果拆到“一个功能一条需求拆成一个模块”会适得其反。模块之间的链接管理是有成本的模块越多链接越复杂维护负担越大。我见过某个供应商把转向灯逻辑拆出十几个模块最后追查一条“左转向灯不亮”的需求链工程师要跨六个模块、点七八层链接才算摸清严重拖累效率。判断标准还是回到“内聚”和“变更频率”。如果一个模块里的需求总是被同时修改、由同一角色评审那它们就该在同一个模块里。反之两个模块的需求如果经常需要跨模块关联那就考虑要不要合并。模块是一个组织协作工具不是给需求做“归档”用的。5.3 属性值随手填报表根本没法用属性是DOORS的“灵魂”要求属性规范就必须规范到底。项目里最常见的惨案是Priority字段的枚举值有“高/中/低”“High/Medium/Low”“H/M/L”三种写法并存Filter查询时把自己都搞糊涂了。这是属性模板没有加约束导致的结果。DOORS的Enumeration类型本身就已经限定了取值范围所以问题不在于工具而在于团队有没有统一配置模板。我的建议是在项目启动阶段就冻结属性字典不允许自由输入。如果团队内部确实需要不同写法就用视图View做映射而不是让每个人按自己的习惯填。报表和追溯矩阵的可靠性本质上依赖的是属性数据的规范性。5.4 基线打得跟开玩笑一样追不到版本有些团队觉得打基线是“走形式”项目做到一半才补了几个基线到后期审计时根本解释不清哪个版本对应哪次里程碑。DOORS的Baseline一旦创建就不可变这是它最有价值的地方——“不可变”才能做合规审计。我经历的几个通过ASPICE评审的项目每一次评审前必做基线基线上还必须有对应的评审记录和批准签名。这个习惯越早建立越省事后期补的时候极其痛苦因为对象状态和属性已经被改得一塌糊涂。6. 从需求模块到项目落地后续的联动怎么跟上6.1 影响分析如何真正提速模块化需求拆分最大的收益出现得最明显的地方其实是变更管理。假设场景是这样的市场部门提出“日间行车灯需要在近光灯点亮后自动降低亮度到50%”这条变更不只是新增一条系统需求那么简单——它同时影响近光灯功能、日间行车灯功能、PWM驱动策略和诊断功能。在没有做模块化拆分前影响分析靠的是“翻文档问人”。需求模块化之后这件事变成了一次标准的“沿着链接走”的查询在DOORS里找到“日间行车灯”对应的系统需求对象查看它下east链接出来的所有功能需求、软件需求、硬件需求和测试用例一遍就能列出全部影响范围。我实测过一个中等复杂度的变更需求用这种方法做影响分析时间能从两三天压缩到半天以内。6.2 与测试的追溯DOORS-SI/DOORS Next的联动思路DOORS在汽车行业的使用往往不仅限于它自己会跟测试管理工具如DOORS Next、Polarion、TestStand等做集成。哪怕不做工具链集成模块化需求拆分本身就为手工追溯打下了坚实基础。每个功能模块对应一套测试用例测试用例通过链接指向软件需求软件需求再指向系统需求从功能到用例的映射关系清清楚楚。在DOORS里可以利用“Traceability Matrix”生成追溯矩阵横向是模块A的需求列表纵向是模块B的需求列表交叉点就是链接关系。做测试覆盖度分析时矩阵一眼就能看出哪些需求没有对应的测试用例。这个矩阵对评审和审计来说是黄金文档很多项目的合规评委都直接要求提供它。6.3 对未来工程复用的价值最后说一个经常被低估的好处需求模块化做得好是可以被复用的。如果公司有多个车型平台彼此之间有大量共性的灯光功能需求那么在搭建新车型的需求库时完全可以复制原平台的需求模块结构只改造差异部分。我见过一个团队通过模块化需求库把新车型灯光系统的需求开发时间缩短了近40%。需求库不只是“记录”更是组织级的资产模块化就是把资产做成“可插拔组件”。7. 最后一层心得模块化拆分的本质是“为协作建模”做了这么多年需求管理我越来越觉得模块化需求拆分表面上看是一个技术操作本质上是在为团队的协作方式建模。你拆出来的模块边界就是团队里不同角色之间的“接口协议”你在DOORS里建立的链接就是协作的显性化表达。DOORS只是把这些关系固化成工具里的结构但真正的“模块化”来自你对系统的理解和对协作流程的认识。如果你所在的团队正打算做这套事情我的建议是从一个规模适中的子系统先试水不要一上来就推全车。选一个类似“灯光控制”这种边界清晰、参与角色不过于复杂的系统按本文的步骤走一遍分类清洗、建模块、定属性、拆分细化、链接追溯、评审基线。跑通一个完整循环后团队对DOORS的掌握和对模块化的理解都会上一个台阶再推广到其他系统时阻力就会小很多。另外还有一个小技巧拆分过程中如果拿不准某两条需求是该合并还是该分开就去问测试工程师——你最不想看到的场景是测试工程师为一条需求设计用例时要同时验证两个不相关的行为。这条“测试视角的检验法”比任何检查清单都管用。