
刚入行那阵我最怕听到的一句话就是“你把概要设计和详细设计写一下。”当时我对着空白Word文档能发呆半小时脑子里全是问号——这俩东西到底有什么区别写到多细算“详细”写完给谁看有什么用后来被leader带着做了几个项目又亲手把设计文档从前到后完整写了几轮才慢慢摸清楚这里面的门道。这篇文章就把这件事彻底讲透。我会从两份文档的定位差异讲起然后分别拆解概要设计和详细设计各自要写哪些内容、写到什么程度再聊一聊它们之间怎么衔接、怎么评审、怎么在项目验收的时候顺利过关。这套打法不是教科书里的理论而是我在真实项目里反复用过、验证过的流程可以直接拿来用。1. 先分清楚概要设计和详细设计到底在解决什么问题很多同学分不清这两份文档是因为它们的名字里都带“设计”两个字感觉像是同一件事的前后两半。我的理解不太一样——这两份文档面对的是完全不同的两个问题概要设计回答的是“系统由哪些部分组成、这些部分怎么协作”详细设计回答的是“每一部分内部到底怎么工作、代码具体怎么写”。用盖房子来类比就很好懂了。概要设计是建筑师手里的总平面图和结构方案它确定了楼盖在哪里、地下几层地上几层、承重墙在哪、水电暖通怎么走——你看到的是整个楼的骨架。而详细设计是施工队手里的全套施工图它精确到每一面墙的钢筋布置、每一根管道的直径和走向、每一个房间的开关插座标高——拿着这套图工人就能直接动手干活。这两个阶段缺一不可。没有概要设计就直接做详细设计你连模块边界和依赖关系都没定清楚详细设计写出来大概率要推翻重来。反过来概要设计做完不继续做详细设计留给开发的还是一堆抽象描述每个人对“怎么实现”的理解都可能不一样代码风格和实现路径五花八门后患无穷。从交付节奏上看概要设计一般在需求评审通过后、技术选型基本确定时启动产出的是系统架构、模块划分、接口规划、数据模型框架、部署方案。详细设计在概要设计评审通过后启动产出的是类设计、方法签名、时序流程、数据库表结构、异常处理逻辑、界面交互细节。我整理了一张对比表方便你一眼看明白区别。对比维度概要设计详细设计回答的问题系统由哪些模块组成、模块间怎么协作模块内部怎么实现、逻辑怎么编排主要读者架构师、研发负责人、产品、测试本模块的开发人员、测试人员交付物形态架构图、模块划分、接口清单、部署方案类图、时序图、伪代码、建表SQL、接口字段表细致程度到接口级、表级不涉及具体实现到方法级、字段级、算法级评审关注点边界是否清晰、依赖是否合理、方案是否可行逻辑是否完备、异常能否兜住、性能是否达标常见载体《概要设计说明书》《详细设计说明书》、代码注释、接口文档最近热搜里有个词叫“项目验收系统概要设计说明书”这个场景我太熟了。很多项目平时不写文档到了验收前突击补材料结果概要设计说明书写得跟需求说明书似的全是“系统支持用户登录、系统支持订单管理”这种描述评审老师一眼就能看出来是凑数的。概要设计说明书在验收时是硬性交付物之一它要证明的是你的系统在架构层面是合理、可靠、可维护的不是功能列表的复述。2. 概要设计怎么落笔模块怎么切、接口怎么对、边界怎么定概要设计最核心的技能是判断力——你要能站在整体视角把系统切成几个高内聚低耦合的模块并且给每个模块画出清晰的职责边界。这活儿看起来抽象其实有章法可循。2.1 概要设计说明书的标准章节结构我现在写概要设计基本固定用一套章节模板既能保证评审老师想看的东西都有也能提醒自己不遗漏关键决策。引言写清楚文档目的、术语定义、参考资料。需求概述用一两页提炼核心业务流程和功能性需求不展开细节。总体架构系统架构图、技术栈选择、关键设计原则。模块划分每个模块的名称、职责说明、依赖关系。接口设计模块间接口的清单和关键接口定义含通讯方式。数据设计核心数据实体清单、逻辑模型、库表规划原则。部署与运行单机还是集群、中间件选型、环境要求。非功能需求落地高可用、安全性、性能指标在设计层面的处理方式。这套结构不是我发明的但它是在很多公司内部评审中被反复检验过的版本。要点在于“引用需求但不复述需求”评审人要看到的是你为了满足需求做了哪些技术决策。2.2 模块划分的三条硬标准第一单一职责。一个模块只解决一个业务域的完整闭环。比如订单模块就应该覆盖从创建订单到支付回调再到订单状态流转的整个生命周期而不是把“下单”丢给订单模块把“支付状态更新”丢给财务模块——那样一个完整的业务事务就被切碎了。第二依赖方向要清晰。模块之间允许依赖但依赖链路上不能形成环。A依赖B、B依赖C、C又依赖A这种循环依赖在代码层面迟早变成一团乱麻。尽量让依赖方向靠向长期稳定、通用性强的底层模块比如基础用户服务、消息组件、公共工具层。第三接口数量要克制。两个模块之间的接口最好不要超过五六个。如果你发现两个模块之间互相调用的方法多到数不过来那说明模块边界切错了该合并的合并该拆出来的要拆出来。接口过多是模块划分不干净的最典型信号。拿我之前做过的一个订单系统举例一开始有人把“优惠券计算”放在订单模块内部后来营销那边要频繁调整规则每次改动都要重新发订单服务牵一发动全身。我们把优惠券拆成独立的营销模块订单模块只通过一个“计算优惠”接口调用它耦合度一下就降下来了。这就是概要设计阶段一个很小的决策但带来的维护成本差异非常大。2.3 接口和数据设计写到什么粒度概要设计里的接口不需要写出每个字段但要明确接口的归属、方向、通讯协议、大致的入参出参概念。比如“用户模块提供一个按用户ID查询用户基础信息的REST接口供订单模块在展示订单列表时调用”这个粒度就够了。到字段级别是详细设计的事。数据设计同理。概要设计阶段只需要给出核心实体的清单和它们之间的关系比如“订单表、订单明细表、支付流水表三者是1对N关系”再加上主键策略、分表分库的规划原则。不用把每个字段的长度和索引都写出来那是详细设计阶段的职责。还有个容易踩的坑部署方案在概要设计里必须有。我见过太多文档把架构图画得漂漂亮亮一到部署就写“后端数据库Redis”五个字完全没有环境规划。评审时被问“这个系统要跑在什么配置的机器上、几个实例、数据库主从怎么配、Redis挂了会怎样”答不上来。部署方案不是运维才关心的事它直接决定了项目的可靠性和成本验收评审里也是重点问询对象。3. 详细设计怎么落笔类怎么设计、流程怎么走、异常怎么兜详细设计是给开发人员看的“施工图”它的目标是让一个对模块没有预先了解的程序员照着文档就能写出代码而且写出来的代码结构和文档描述一致。这比看起来难得多。文档里一个分支条件没写清楚代码里就可能漏处理一种业务场景。3.1 详细设计的核心内容清单我不建议用“模板套模板”的方式写详细设计因为不同模块的复杂度差异极大。但核心内容离不开下面这六项类设计与职责核心类的职责说明、类之间的关系、关键属性。核心流程设计用泳道图或时序图表达一个完整业务场景的参与者交互。接口级定义方法名、参数列表、返回值、业务规则说明。存储设计每张表的字段、类型、索引、约束、初始数据。异常与边界分支条件、异常场景、幂等性保证、补偿逻辑。依赖与配置依赖的外部服务、配置项说明、开关设计。写的时候要记住一个原则详细设计不是把代码翻译成中文而是把代码背后的思考逻辑展示出来。你真正要交付的是“为什么这么实现”的决策过程而不只是“实现了什么”的结果描述。3.2 用一个下单流程把详细设计串起来我拿一个稍作抽象的下单流程来演示你就能体会到详细设计和概要设计在视角上的差异。概要设计里描述的是用户模块负责身份识别订单模块负责订单创建库存模块负责库存扣减——到这一步就停了。详细设计会把“下单”这一个动作拆成一条完整的链路用户调起提交订单接口入参带用户ID、商品SKU列表、地址ID。订单模块先调用用户模块接口校验用户状态是否正常。依次调用库存模块接口预扣每个SKU的库存任何一个SKU库存不足全部预扣回滚。生成订单主记录状态为“待支付”明细逐条写入订单明细表。调用营销模块接口计算优惠和实付金额回写到订单。返回支付参数前端调起支付。每一个步骤都要落在一张时序图里。时序图的好处是它强制你把消息调用的顺序、同步异步、超时时间、失败走向都画出来。我见过很多开发画的时序图只有正常路径没有异常路径这在实际评审中是最容易被挑出毛病的。库存不够走哪条分支支付超时算不算成功优惠计算失败这个单还让不让用户下这些都要在时序图的分支里画出来。3.3 接口级定义和存储设计的实操细节接口级定义看起来简单就是把方法签名列出来但要注意把业务规则写上去。比如“查询订单详情仅允许订单所属用户本人或管理员调用返回的详情中包含优惠明细不包含支付流水中的卡号信息”。类似这种业务规则是代码里最容易遗漏的部分写清楚它详细设计的价值就体现出来了。存储设计这块我建议直接写到表结构级别字段名、字段类型、是否为空、默认值、索引设计都要给出来。举例来说订单明细表一定会有这些字段订单明细ID主键订单ID外键索引SKU ID商品名称快照商品单价快照购买数量实付小计创建时间注意一个细节商品名称、单价为什么要做“快照”因为商品信息在商品中心是会变的如果用户下单半年后拉订单详情发现商品名称变成了新品名那就闹出线上事故了。这种设计决策在详细设计阶段就要明确写出来而不是等开发在写代码时自己去琢磨。边界条件也是详细设计躲不开的部分。还是用下单场景举例库存预扣成功但生成订单主记录失败怎么办合理方案是订单表先落状态为“创建中”库存预扣后如果订单生成失败由定时任务对“创建中”状态的超时订单做补偿取消并回补库存。这种处理路径必须写进设计文档属于业务正确性的关键保障不能靠开发临场发挥。4. 从交付到落地的衔接评审怎么开、变更怎么管、代码漂移怎么防光会写文档还不够更关键的是让设计文档在项目生命周期里真正发挥约束作用。我见过不少项目设计文档写得漂漂亮亮评审一过就进了网盘吃灰代码最后实现的和文档是两套东西。这种情况比不写文档更坑因为后来接手的人还得花大量精力去辨别到底以哪个为准。4.1 评审会应该怎么开才不流于形式概要设计评审和详细设计评审的目标不一样参会人也要有区分。概要设计评审参加的人应该是研发负责人、架构师、相关模块的技术负责人、产品和测试。评审的重点是方案的整体合理性。我会建议评审会上只看三类问题第一模块边界是否清晰有没有谁在干不属于自己的活第二接口依赖是否合理有没有循环依赖或过度耦合第三关键技术选型是否站得住脚比如为什么用Redis做缓存而不是本地缓存为什么有的接口用同步调用而有的用异步消息。详细设计评审就是本模块的开发人员外加测试。评审的重点是逻辑完备性。我每次都会强调测试在评审时最重要的工作是“挑刺”把所有能想到的异常场景都提出来问——用户并发重复提交怎么办、上游超时返回但实际处理成功怎么办、中间状态的数据在页面上怎么展示。这些问题能在评审阶段暴露出来相当于省了后续无数线上故障排查的时间。评审会要有一个明确的产出评审结论。通过、有条件通过、打回重做三选一。有条件通过要列出制约条件督办落实。不然会开了等于没开每个人回去都按自己的想法继续做。4.2 变更控制设计文档不是一次定稿就完事设计文档的最大敌人是“漂移”——代码在发展文档停在原地。解决这个问题靠的不是自觉是流程约定。我的经验是两条第一如果代码实现和设计文档发生偏差超过一定工作量比如改动涉及接口签名、新增表、改变业务流程就必须先更新设计文档再改代码第二每次里程碑结束比如提测前、上线前要花半小时把文档和代码对一遍更新的地方打上修订标记。这个习惯坚持下来文档的可信度会维持在一个比较健康的水平。实际操作中我强烈建议在详细设计中增加一个“变更记录”表记录每次修改的日期、修改人、修改原因、影响范围。这件事投入极小但后期追查问题的时候价值巨大。4.3 画图工具的选择与绘图习惯现在画设计图的工具太多了我用下来觉得不需要追求特别复杂的工具关键是团队能协作、能点评、能保存历史。我自己的排位是Confluence draw.io适合公司内部协作天然关联需求文档。ProcessOn上手快模板丰富适合画思维导图和架构图。PlantUML适合喜欢用代码表达图的人文字描述即图版本管理友好。手绘/白板口头评审和方案讨论阶段最好用的形式方便快速迭代。画图最大的建议是保持统一规范。一套系统里组件框用什么形状、箭头代表依赖还是数据流、虚线代表异步还是定时任务要在文档里约定一致。不然每张图换一套画法读者每次都要重新学习非常影响评审效率。5. 项目验收场景下设计文档怎么准备才能顺利过关最后讲讲验收这个特定场景。很多人觉得验收就是把系统跑通、功能点完设计文档不过是走个形式的附件。但我在项目验收系统相关的工作里踩过不少跟头可以明确告诉你设计文档恰恰是验收评审时最容易被挑出问题的材料因为它最能反映项目过程是不是规范。5.1 评审老师最爱问的问题清单验收评审的设计文档审查通常不会没事找事但下面这些问题几乎必问你需要提前准备好答案。“你说系统分成了几个模块能不能现场讲一下模块间的一次完整数据流转”——这是最经典的提问考察你对自己架构图是否真正理解。“如果数据量增长十倍、并发翻倍你的部署方案还成立吗”——考察非功能设计是否考虑过扩展性。“模块间是用REST还是消息为什么这么选消息丢失怎么办”——考察技术选型的依据和容错设计。“数据库表之间的数据一致性怎么保证跨表事务怎么处理的”——考察存储设计的严谨度。“详细设计里核心业务的异常分支有哪些幂等性是怎么保证的”——考察对线上真实场景的理解。这些问题没有一个问的是功能实现全问的是设计决策。所以文档里不能只写“是什么”必须把“为什么”写出来。我自己写设计文档的时候会故意在关键决策下加一个“方案选型说明”小节文字不多一两段话把这个决策的背景、备选方案、为什么选它说清楚。这一招在验收评审时特别好用相当于主动把答案交上去了。5.2 验收前自查清单别等到验收前一周才来突击文档。平时每完成一个阶段就顺手把对应章节更新掉。验收前我只做两件事一是全面核对一遍文档与代码的对应关系二是对着下面这张自查表逐项打钩。概要设计说明书版本号、审批记录完整架构图版本与当前系统一致模块清单覆盖所有业务功能接口清单中最少有三方对接的明确说明部署方案有明确的环境配置和资源需求。详细设计说明书核心业务模块都有对应文档每个核心流程有时序图核心接口有字段级定义数据库每个表有关键索引说明异常场景有专门篇幅描述。文档之间的协同关系概要设计里定义的模块在详细设计里都能找到对应章节字段命名风格统一术语一致没有“用户ID”“用户编号”“用户主键”混用的情况。可追溯性每个需求条目能找到对应的模块和设计说明关键设计决策有记录变更记录表有内容。其中“可追溯性”是验收评审最喜欢看的。能做到需求到模块到设计一一对应文档的完整度和可信度一下子就立起来了。5.3 头歌这类实训平台上的详细设计作业有什么不同顺手再提一个场景因为我的读者里也有不少是在校同学他们会用到一些实训平台比如头歌上的“软件详细设计-2、软件工程导论实验”这类内容。实训平台上的设计文档作业核心目标和真实项目不太一样前者更侧重考察你是否把软件工程的基本方法论落实到文档里。所以我建议同学们在做这类实验作业时不要追求把文档堆得多长而是要把“需求分析—概要设计—详细设计”这条主线讲清楚。哪怕系统很小也要画出模块图、画出核心流程时序图、给出类图或数据库表结构。评分看重的往往是这些“过程产物”的真实可读性而不是篇幅。有一点要特别注意实训平台的作业往往对文档格式有严格的模版要求比如章节编号、图表编号、参考文献格式。这些看起来无关紧要的细节在评分标准里往往占比不小。做实验前先下载模板认真读一遍比闷头写三版再改都有效。最后分享一点个人体会写设计文档这件事本质上是把脑中的思维过程外显化。大多数人不爱写是因为觉得“代码都写出来了文档还重要吗”我的感受恰恰相反——代码只能告诉你系统做了什么只有设计文档能告诉你系统为什么这么做。一个项目经过几个人、几次迭代之后当年的“为什么”就是最宝贵的资产它能让后来的人少走无数弯路。 我现在每接一个维护项目第一件事永远是找概要设计和详细设计文档然后对着代码核对。文档清晰的团队我上手速度极快文档缺失的团队我每看一段代码都要反推当时的决策场景效率天差地别。所以与其说写文档是为了应付评审和验收不如说是在为未来的自己攒一份清晰的工作地图。这个习惯越早养越好。