☰
软件概要设计说明书写作指南:从模块切分到评审避坑
2026/10/13 8:38:18 网站建设 项目流程

简介:软件概要设计说明书案例提供了一份可直接参考的软件设计文档范本,主要面向软件开发工程师、系统架构师及项目管理者,帮助解决概要设计阶段文档结构混乱、规范缺失等问题。文档参照相关国际标准组织编写,完整覆盖引言、定义、参考资料、软件系统结构设计、测试计划与维护计划等章节,并对系统主要目标、软件需求、性能与安全要求、模块命名规则等关键内容给出示例,还提供了软件程序结构图样式的演示,便于读者快速套用或对照修改。包内仅含1个doc文件,整体大小约335KB,适合作为团队内部模板或学习资料。目前已有136人学习下载,对于需要编写高质量软件设计文档的开发者而言,这份案例能有效提升文档编写效率与规范性。

1. 概要设计说明书案例:一份文档为什么值得当“缓存”来抠

接手过十几个项目的概要设计评审后,我最大的感受是:多数团队不是不会写概要设计说明书,而是把概要设计写成了详细设计的流水账,或者把详细设计压缩成了概要设计。真正能用的概要设计说明书案例,不是给你一个模板让你填表,而是告诉你哪些内容必须在概要阶段定死、哪些内容留到详细设计再说,以及每一张图、每一条接口定义背后要回答什么问题。这篇笔记围绕软件概要设计说明书的案例写法展开,覆盖从模块切分、接口建模到数据字典的全过程,重点讲清可复现的步骤和评审现场的高频雷点,适合正在准备软考软件设计师中级论文、或者第一次独立承担设计文档的工程师照着抄作业。

2. 动手前的三层底稿:范围确认、模块切分与架构图工具选型

2.1 先确认设计边界:需求文档里哪些内容不能写进概要设计

很多人拿到需求文档就开始画架构图、写模块清单,结果评审时被问“这个功能对应哪个需求条目”就答不上来。概要设计说明书的第一页应该是一张需求追踪表,把每一条用户需求映射到对应的子系统或模块,而不是直接进入技术方案。常见做法是先把需求文档里的功能需求和非功能需求分别编号,然后逐个判断:这个需求能不能在一个模块内闭环,需不需要跨模块协作,有没有外部系统接口。这个判断过程决定了后续模块切分的粒度,也决定了概要设计文档的目录结构。

我自己习惯在动手前先列一张边界确认表,表头包括:需求编号、需求描述、涉及子系统、是否对外接口、优先级。这张表的价值在于强制把需求翻译成设计任务,避免在概要设计阶段混入需求分析的内容。比如需求文档里写“系统支持批量导入用户”,概要设计只需要定义导入模块的职责、输入输出格式和异常处理策略,至于导入文件的Excel模板长什么样、每列怎么解析,那是详细设计的事。边界确认表完成后,再把每个子系统拆成模块,模块的粒度以“一个人能在两周内完成详细设计和编码”为参考,过粗会导致模块内部耦合失控,过细会让概要设计文档变成详细设计。

按我实践过的项目统计,一个中等规模的管理系统,概要设计文档里模块清单的合理数量在20到40个之间,超出这个范围说明切分粒度可能有问题,少于这个范围通常意味着模块职责合并过度。模块命名也有讲究,建议用“业务动词+业务对象”的结构,比如“订单状态流转”“库存阈值预警”,而不是“订单模块”“库存模块”,这样的命名在评审时更容易让人理解模块职责,也更容易和需求追踪表对应。

2.2 模块切分的两种方式和五条判断标准

模块切分常见的有两种方式:按业务域切分和按技术层次切分。按业务域切分适合业务逻辑复杂的系统,比如电商系统拆成商品、订单、支付、售后四个域;按技术层次切分适合以数据处理为核心的系统,比如拆成采集层、解析层、存储层、服务层。实际项目中两种方式会混合使用,但概要设计说明书里要明确主导原则,否则详细设计阶段会出现模块职责交叉。

我一般用五条标准来判断模块边界是否合理。第一条,模块内部高内聚,模块之间低耦合,这在概要设计阶段靠检查模块间的调用关系来判断,如果A模块要频繁读取B模块的内部状态,说明边界可能划错了;第二条,每个模块有明确的对外接口,接口数量控制在5到10个之间,接口过多说明模块职责过重;第三条,模块可以独立替换,比如换一个数据库连接池不应该影响业务模块的代码;第四条,模块的输入输出能明确描述,不能出现“处理一下数据”这种模糊表述;第五条,模块规模可控,这回到之前说的两周完成原则。

模块清单最终要落到一张表格里,表头包括模块编号、模块名称、职责说明、依赖模块、对外接口数。这张表是概要设计说明书的核心产出之一,后续的接口设计、数据设计都以这张表为纲。依赖关系建议用编号引用而不是直接写模块名,比如模块M03依赖M01和M02,这样在文档维护阶段调整模块排序时不会破坏引用关系。模块编号建议采用层级编码,比如S2-M05表示第二子系统下的第五个模块,评审时定位问题会快很多。

2.3 架构图工具选型:从白板到数字化,注意三个坑

画架构图是概要设计阶段最直观的产出,工具选择上我踩过不少坑。第一类坑是过度依赖Visio,Visio画出来的图确实规范,但多人协作时版本管理很痛苦,常常出现架构图更新了但设计文档里的截图还是旧版的情况;第二类坑是用代码仓库画图,比如用PlantUML写架构图源码,好处是能版本化管理,坏处是学习成本和评审门槛高,团队里不是每个人都愿意读PlantUML语法;第三类坑是直接用白板拍照放文档里,白板图作为草稿没问题,但作为正式交付物会让整体文档的专业度大打折扣。

现在团队协作工具比较成熟,我倾向于用支持多人实时编辑的在线绘图工具,比如draw.io、ProcessOn这类,画完直接导出SVG放到文档里,并且把源文件一并入库。注意架构图不是画得越复杂越好,概要设计说明书里的架构图应该控制在一页能看完的信息量。一张合格的系统架构图要表达四层信息:外部系统和用户在哪里、系统内部有哪些子系统或模块、模块之间的主要调用关系、关键数据流向。画完架构图后,自己检查一遍:能不能用三句话向一个没参与项目的人讲清楚这张图?如果讲不清楚,说明图里的信息过载了或者模块切分边界模糊了。

模块划分完成后,还有一个容易被忽略的动作:写一段“设计约束”放概要设计说明书的前置章节。设计约束要说明技术栈选型、部署环境、第三方依赖版本约束,比如数据库只能用MySQL 8.0、消息队列只能用Kafka 2.8以上版本。很多人觉得这些写进详细设计就行,但概要设计评审时评审专家通常先看设计约束,因为技术选型决定了整个架构的可行性和成本。这段内容控制在半页到一页,用列表逐条说明即可,不需要展开论证。

3. 接口设计与时序建模:把模块间的“合同”写死

3.1 接口清单的五个必填字段和常见误用

概要设计阶段的接口设计,重点不是定义每个函数的参数列表,而是定义模块之间交互的契约。我习惯把接口分为三类:同步调用接口、异步消息接口、外部系统对接接口。每类接口的字段要求不同,但接口清单表格里至少要包含五个字段:接口编号、接口名称、调用方向、同步/异步标识、接口用途说明。其中调用方向要写清楚谁调谁,比如“订单模块→支付模块:创建支付请求”,不要只写接口名,否则评审时别人还要去翻代码才能理解。

接口命名规范和模块命名一样重要。常见误用是接口名照搬HTTP路径或者类方法名,比如写“POST /api/order/create”,这个信息在详细设计里才有意义。概要设计阶段的接口名建议用“动词+业务对象+场景”的结构,比如“创建订单并触发支付”“查询库存并锁定数量”。接口用途说明不能写“处理订单数据”这种废话,要写清楚输入是什么、输出是什么、异常时怎么办。

接口清单里还应该包含一个“数据约束”字段,标注这个接口传输的数据量级和频率。比如“单次请求返回商品列表不超过500条”“每秒最多接收100个库存变更消息”,这些信息对后续的详细设计和性能测试都非常关键。很多团队忽略这个字段,结果详细设计阶段选了不合适的序列化方案,或者数据库索引设计没跟上,上线后接口超时才发现问题。

3.2 用时序图验证接口设计的合理性

接口清单画完后,不要急着写详细设计,先画核心业务场景的时序图。时序图的价值在于暴露接口设计中的“隐藏依赖”。举个常见的例子:用户下单这个操作,从表面看只涉及订单模块和支付模块,但画时序图时会发现,订单创建后还需要调用库存模块锁定库存、调用优惠券模块核销优惠券、调用消息服务发送通知。这些隐藏依赖在接口清单里如果没体现,详细设计阶段就会反复返工。

画时序图不需要覆盖所有场景,挑选业务价值最高的5到6个场景即可,比如主流程、最复杂的异常流程、性能敏感流程。具体画法上,我用标准的UML时序图,每个模块对应一条生命线,消息用箭头标识,返回结果用虚线。时序图完成后,逐条检查:每个消息都在接口清单里有对应的接口定义,每个接口的调用顺序和时序图的顺序一致。这个检查动作能在概要设计阶段抓住80%以上的接口遗漏问题。

// 接口契约定义示例(伪代码) public interface IOrderService { // 创建订单并返回支付所需参数 // orderRequest: 包含商品ID列表、用户ID、收货地址ID // 返回值: PayToken,供支付模块创建支付单 // 异常: OrderCreateException(库存不足、优惠券不可用) PayToken CreateOrder(OrderRequest orderRequest); }

上面这段接口定义就包含了三层信息:输入参数结构、返回值用途、异常情况。其中注释部分写的“库存不足、优惠券不可用”,是在概要设计阶段就要明确的异常边界,指示了主流程之外可能需要跨模块通信的异常路径,而不仅仅是函数签名。参数里的每个对象在后续数据设计阶段都要给出字段级定义,这是概要设计中“先合约后实现”的具体体现。

3.3 异步接口的设计要点:消息格式与消费语义

异步接口在概要设计阶段常被忽视,但一旦涉及系统间解耦,异步消息的设计比同步接口更考验设计能力。这部分我一般单独成章,说明每个异步消息的主题或队列名称、消息体格式、生产者消费者对应关系、消费失败的重试策略。消息体格式建议在概要设计阶段就用JSON Schema定义,而不是等到详细设计才定,因为消息格式一旦发布出去,多个消费者依赖它,改动成本很高。

{ "messageId": "uuid", "timestamp": 1735689600000, "source": "order-service", "type": "ORDER_CREATED", "payload": { "orderId": "SO20250101001", "userId": "U10086", "totalAmount": 299.00, "items": [{"skuId": "SKU001", "quantity": 2}] } }

这段消息体示例中,messageId和timestamp是每一条消息都要有的通用字段,其中messageId用于消费端做幂等去重。type字段是消息路由的关键,不同type可以路由到不同的消费者。payload里只放业务必需字段,不要图方便把整个订单对象序列化进去,否则下游消费者会依赖你并不想暴露的内部数据。幂等去重的具体策略在概要设计阶段要写明,比如按messageId查重还是按业务唯一键查重,这直接影响后续消费者的表结构设计。

时序图和消息格式完成后,接口设计部分基本就完整了。这部分内容在文档里的排版建议是:接口清单表格放前面,时序图放中间,消息格式定义放后面,这样读者从头到尾读下来符合“接口有哪些→接口怎么交互→交互传什么数据”的逻辑。评审专家通常也是按这个顺序翻文档,编排合理会让他们更容易抓到重点。

4. 数据设计:E-R 图、数据字典与容量估算

4.1 E-R 图的画法要点:看清关系还是看清字段

概要设计说明书里的数据设计,目标是定义核心实体及实体间的关系,而不是把所有字段和索引都列全。E-R图在这个阶段只需要画到实体级,实体内部的字段清单放到数据字典里。但很多新手会把E-R图画成字段级,一张A4纸塞了密密麻麻的字段名,评审时根本看不清关系,这种图就失去了概要设计阶段的表达力。

正确画法是先用矩形框表示实体、菱形表示关系、直线上的标注表示基数,一页图控制在10到15个实体之间。超过15个实体就按业务域拆成两张图,比如订单域一张、商品域一张。E-R图画完后,逐个关系检查:是否标明了1对多还是多对多,多对多关系是否需要中间实体,以及每个关系是否真的需要跨模块调用或者通过数据库关联实现。概要设计阶段的E-R图还要标注每个实体归属哪个模块,这能校验模块划分是否合理——如果一个实体的字段被三个模块频繁修改,说明这个实体的归属关系有问题。

4.2 数据字典的粒度:哪些字段必须在概要设计阶段定死

数据字典是概要设计说明书的另一个核心产出。我常用的数据字典表格字段包括:字段名、字段类型、长度、是否必填、默认值、业务说明。但要注意,概要设计阶段的表格里不需要把所有字段都列出来,只需要定义每个实体的关键字段。哪些是关键字段?我的判断标准是第一,跨模块传输的字段必须定义,比如订单号、用户ID、商品ID;第二,涉及数据一致性约束的字段必须定义,比如状态字段的取值范围、金额字段的精度;第三,数据生命周期相关的字段必须定义,比如创建时间、更新时间、逻辑删除标识。

-- 订单主表核心字段定义(概要设计阶段) CREATE TABLE order_main ( order_id VARCHAR(32) NOT NULL COMMENT '订单号,全局唯一', user_id VARCHAR(32) NOT NULL COMMENT '下单用户ID', order_status TINYINT NOT NULL DEFAULT 0 COMMENT '订单状态:0待支付 1已支付 2已发货 3已完成 4已取消', total_amount DECIMAL(12,2) NOT NULL COMMENT '订单总金额,单位元,精度2位', created_at DATETIME NOT NULL COMMENT '创建时间', updated_at DATETIME NOT NULL COMMENT '最后更新时间', deleted_flag TINYINT NOT NULL DEFAULT 0 COMMENT '逻辑删除:0未删除 1已删除', PRIMARY KEY (order_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

这段SQL值得琢磨的是order_status字段的注释。它不只是写了一个TINYINT,而是把每个枚举值对应的业务含义都写明,这消除了不同模块对状态定义的分歧。设计时如果状态比较多,还可以用独立的枚举表,但核心业务的状态机字段建议直接在字典里定死,不用关联表,不能为了追求设计上的“对称”去过度建表。DECIMAL(12,2)和DATETIME这些类型选择也属于概要设计阶段的决策,因为涉及存储精度和跨时区问题,此时不拍板就等于把风险推迟到详细设计。

数据字典全部完成后再回过头检查一件事:统计每个表的预估数据量和占用空间。容量估算不需要精确到行,给出量级即可。比如订单表,按日均订单1万单、订单数据保持3年计算,再按单行平均1KB估算,很容易算出让评审专家信服的存储需求,这比笼统地写“估计数据量很大”有说服力得多。

4.3 数据一致性方案:哪些用数据库约束,哪些用业务逻辑保证

数据设计里最容易翻车的是数据一致性方案。概要设计阶段要明确每个核心数据的一致性级别,尤其是跨模块的数据操作。常见做法是区分三类场景:第一类,单模块内的数据变更,靠数据库事务保证;第二类,跨模块的同步调用,考虑分布式事务框架;第三类,跨模块的异步消息通知,通常用“本地消息表+定时补偿”或者“事务消息”模式。

我遇到过最典型的翻车案例是订单创建后扣减库存,团队在概要设计阶段没定义一致性方案,详细设计时用了同步接口调用,结果库存服务异常导致下单失败率飙升。后来改成“订单先创建为待支付状态、库存锁定走异步消息、支付成功后确认扣减、超时未支付自动释放”的模型,但改动涉及三张表和两个消息主题。这类问题的成本在概要设计阶段解决几乎是零成本,在详细设计阶段解决就要改代码,到了测试阶段解决就是返工。所以数据一致性方案在概要设计文档里要单独成节,并明确写出推荐方案和备选方案,以及推荐理由。

5. 概要设计的五个高频埋雷点:评审现场最容易翻车的细节

5.1 需求追踪表断裂:评审专家问“这个模块服务哪个需求”答不上来

现象:概要设计说明书里的模块清单和需求文档对不上,评审时被追问某个新加的报表模块是哪个需求提出来的,作者支支吾吾说不清楚。

原因:常见的做法是写完需求追踪表之后没有再同步更新模块清单,或者需求文档迭代了版本,但概要设计文档还在按旧版本需求做设计。更深层的原因是团队没有把需求变更的传递机制跑通,需求分析人员改文档后,概要设计文档的维护者不知道。

解决:写概要设计文档时,在每个模块的职责说明后用括号标注需求编号,比如“销售报表模块(需求编号REQ-2025-011)”。另外一个习惯是,每次需求评审会结束后,对照最新需求版本核对一遍模块清单,这个动作花不了半小时,但能避免评审现场的尴尬。需求追踪表不要放在文档末尾附录里,应该放在前言或设计约束之后,评审专家第一眼就能看到。

5.2 接口只写了名字没写语义:下游模块没法开工

现象:接口清单里写“获取订单信息”“查询库存状态”,但没写清楚输入参数是什么、返回结果长什么样、出错时行为如何。下游模块的详细设计完全没法开始,只能一边做一边找上游问。

原因:接口清单只完成了“有哪些接口”这一步,没有完成“接口的契约”。多数团队把接口语义的定义推到详细设计阶段,实际上详细设计阶段各模块并行开发,上游没定契约,下游就被阻塞。

解决:每个接口补上输入输出示例和异常约定,至少对跨模块的关键接口要做到。输入输出示例用JSON或表格写清楚,异常约定至少说明关键错误码和重试策略。概要设计阶段的接口如果连关键接口的语义都定义不全,说明模块拆分的粒度还需要调,通常是模块太大了。

5.3 数据字典漏定义枚举值:两个模块搞出两套状态码

现象:订单状态字段,订单模块的文档里定义0为待支付、1为已支付,支付模块的文档里定义1为待支付、2为已支付,双双上线后消息里传的状态码对不上,排查了半天。

原因:各模块的数据字典在概要设计阶段没有统一评审,每个模块自己定义了字段含义。有时甚至同一个实体出现在两个模块的数据字典里,字段列表还不一致。

解决:数据字典统一归口到概要设计说明书里,以核心实体为单位集中定义,模块文档引用概要设计中的数据字典编号,不单独复制。评审时把订单、用户、商品、支付流水等核心实体的枚举值逐一过一遍,特别注意状态类字段的取值范围,因为这些字段跨模块传播时最容易产生误解。执行层面建议在这个阶段用共享表格维护数据字典,方便多人同时编辑和留痕。

5.4 架构图画得太细:评审专家看不到系统全貌

现象:架构图里画了所有微服务的内部类结构,还画了连接池配置,图画得很大,放大才能看清,评审专家看了一分钟找不到系统边界在哪里。

原因:把详细设计的图搬到了概要设计阶段。架构图在不同阶段的观看目标不一样,概要设计阶段的目标是理解系统全貌和模块关系,不是理解某个类怎么实现的。

解决:概要设计说明书里的架构图控制在两到三张:一张系统上下文图,画外部系统和用户;一张系统架构图,画模块和子系统;如果涉及部署,再画一张简化的部署视图。每张图的元素控制在12个以内,图里的文字尽量用短语不用句子,图上线条尽量少交叉。画完图后想象一下自己在评审现场投影这张图,最后一排的人能不能看清线条上的标注?看不清就拆图、精简。

5.5 容量和性能指标没写:上生产环境才发现设计不满足要求

现象:文档里写“系统应保证一定性能”,没有量化指标。测试阶段做压测,发现某个接口的响应时间远超预期,再回头看概要设计文档,没有关于该接口性能的任何约束记录。

原因:非功能需求在概要设计阶段被忽略,或者只抄了需求文档里“高性能、高可用”这种口号,没有转成可验证的指标。

解决:概要设计文档里增加非功能需求表,把关键业务的性能指标翻译成设计指标,比如“订单创建接口TP99小于500毫秒”“核心数据RPO为15分钟”。这个翻译动作的意义在于让后续的详细设计、架构选型、甚至硬件采购都有据可依。如果不做这个翻译,评审专家没法判断当前的架构和模块划分能否满足要求,上线后的性能差距完全变成“玄学”。

6. 用“白盒自查”和评审问询,把文档打磨到能签字

概要设计说明书写完初稿后,不急着发评审邮件,先自己做一轮白盒自查。我习惯把自查分成两个层面:一是完整性检查,逐条对着需求文档的功能清单,确认每个需求都有对应的模块和接口承接;如果发现某个需求找不到承接模块,要么是需求遗漏了没设计,要么是模块划分存在盲区,两种情况都必须补上,没有任何特例。二是逻辑性检查,从第一个模块的职责描述开始,逐个判断“这个模块要完成职责,需要哪些输入、依赖哪些模块、输出给谁”,沿着这个逻辑走一遍,通常会暴露出一批接口定义不足或依赖关系缺失的问题。这一整套自查流程走完,通常能发现3到5处设计问题,比评审时被抓出来体面得多。

评审问询阶段也有技巧,建议把问题和答复记录下来,不解释、不评价,只做事实记录。评审专家提出的设计问题里,相当一部分确实是原始设计的瑕疵;但还有一部分是评审专家不理解设计意图,需要作者给出背景说明和权衡依据。这两类要分清楚,前者是真实的设计改进项,后者是文档表达问题,反过来也能检验文档信息是否完整。评审答复记录表是我从某一次比较波折的评审里沉淀下来的习惯——那次评审纪要里只写了问题没写答复,结果三个月后有人质疑当时为什么选择消息队列而不是HTTP调用,文档里没有依据可查。从那以后,我把每条评审意见都列成表格,表头包括:意见描述、涉及章节、处理决定、修改说明,表格随文档一起入库,作为设计的可追溯记录。

最后一个建议是关于保存和版本管理。概要设计说明书是doc还是markdown都行,但源文件和导出的PDF必须入库,不要只留一份在个人电脑里。在不同阶段,文档里如果涉及方案调整,建议在文档开头留一个“修订记录”小节,每次改动合入时写一行变更描述和原因,这个习惯在项目后期回顾时价值极大,能准确印证当初是否考虑了备选方案。这些习惯积累下来,我承担过的项目在概要设计评审阶段很少返工。设计文档这东西,从来不是写给别人看的,是写给你自己三个月后还能翻得懂、说得清,希望这些经验帮到你,也帮到正在为文档头疼的你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询