引言
在日常开发中,软件迭代流程是:需求 → 编码 → 测试 → 灰度 → 上线。这在以前版本高速迭代的时候-一周发布一个版本,通常在需求评审后,就直接进入开发,在开发过程中会一边开发一边修正需求(如果遇到了一个靠谱产品就另说),开发起来特别不顺和难受,有时稍微一不注意,就要需求delay,这个delay的责任是产品该负还是研发该负?产品说已经过了需求评审阶段,此时,研发多半要背负需求delay的责任(充当冤大头)。虽然现在已经过了版本高速迭代的年代,需求没那么着急上线,但有时还是会出现需求dealy,或需求交付前回滚,除非是需求特大变更,否则研发还是要负责任(太难了)。
现如今,无论是做产品需求,还是做技术需求,在需求阶段 → 编码阶段之间,添加了技术方案节点,以此来确保需求的交付。技术方案由研发输出,输出的对象有产品、研发、测试,当然还可以更多。所以,如何输出技术方案,如何编写技术方案文档,对于研发来说,变成了需求迭代中非常重要的一环。
技术方案的目的是什么?
技术方案,对于研发来说,主要做两件事:需求分析和架构设计(技术设计)。这是在编码之前的必要准备,准备是为了降低项目风险。如果能在需求分析或架构设计上就发现项目风险,那么远比在编码、测试、灰度、上线阶段发现项目风险所需要付出的代价小很多。
修复缺陷的平均成本与引入缺陷的时间和检测到该缺陷的时间之间的关系
检测到缺陷的时间
引入缺陷的时 需求 架构 构建 系统测试 发布之后 需求 1 3 5-10 10 10-100 架构 - 1 10 15 25-100 构建 - - 1 10 10-25 例如,假设在创建架构的期间修复某个架构缺陷需要花1 000美元,那么在系统测试期间修复这一缺陷,将要花费 15 000美元。
因此,技术方案的主要目的是:保证需求顺利进行,保证需求准时并高质量交付。
但是,对于参与需求或项目角色的不同,想要从技术方案中得到东西也不同。
对于研发
技术方案对于研发来说,目的在于:
- 明确需求:充分理解需求,对需求一清二楚,包括深层处的需求细节,并从技术侧补全需求遗漏的点,最后研发和产品对需求理解一致
- 设计规划:记录技术架构或技术设计,包含整体架构,模块设计,接口定义,总体逻辑等,为编码时提供清晰的指导
- 风险管理:提前识别需求中可能遇到的风险和挑战,并提出相应的解决方案或缓解措施
- 质量保证:可以作为测试团队编写测试计划和测试用例的依据
- 整体把控:明确技术目标,明确依赖方(上游和下游),明确时间和人力成本,明确开发、测试、上线节奏
总的来说,当研发做完技术方案后,对整个需求明了,能按照步骤有序推进并稳步上线。
另外,如果这次需求开发人员临时变动,改由其他同事开发,那么技术方案对于其他同事来说能无缝接入,只看技术方案文档就知道这次需求该怎么做,并可以顺利完成。
对于产品
技术方案对于产品来说,目的在于:
- 满足产品目标:了解技术方案如何支持产品的短期和长期目标
- 满足用户需求:确认技术方案能够满足用户的需求和体验
- 功能实现:理解功能点的技术实现方式
- 核心技术限制:了解技术上的限制(上限和下限)对产品的影响
- 性能指标:了解功能的性能指标,如加载时间、响应时间等
- 扩展和维护:了解技术方案是否考虑了未来的扩展性和维护性
- 安全性:了解技术方案中如何保护用户数据和隐私
- 风险:识别技术实现过程中可能遇到的风险和挑战,以及解决方案
- 成本和资源:了解技术方案对资源的需求,包括开发、测试、部署和维护的成本
- 合规:了解技术方案是否符合相关法律法规和行业标准
技术方案评审后,产品、研发、测试等对需求的理解是达成一致的,没有偏差。
对于测试
技术方案对于测试来说,目的在于:
- 需求理解:理解需求具体需要做什么
- 业务流程:理解需求业务流程和用户操作路径
- 安全性要求:了解需求的安全要求,如登录、授权、数据加密等
- 性能指标:了解性能测试的目标,如帧率、内存占用、耗时等
- 依赖服务:了解需求依赖的三方服务
- 配置和环境:了解不同环境(测试、预发、生产)的配置差异
- 影响面:了解需求完成后,需要进行的测试面
技术实现对于测试来说,其实是黑盒,但是测试了解技术方案,能够明确需求整体流程,以及需求功能点如何达到产品标准。
对于老板
技术方案对于老板来说,主要是成本评估:时间和人力成本,质量保证:技术可行和考虑周全,资源分配:协调资源以完成需求。总的来说,这个需求根据这个技术方案,可以交给研发人员去执行了。
对于其他
对于其他人,能从技术方案文档了解整体技术思路,如果需要介入迭代,也能直接入手。
小结
综上,输出技术方案,要考虑到输出对象有产品、研发、测试、老板或其他人员,和他们达成一致或得到他们的认同后,技术方案才可以定稿。
技术方案模版
下面,将探讨关于技术方案中需要关心的事项,这些事项包含:
需求分析
- 问题定义
- 需求背景
- 需求目标
- 需求清单(可选)
相关文档
设计目标
技术方案
- 架构图(可选)
- 流程图(可选)
- 类图(可选)
- 时序图(可选)
- 伪代码(可选)
外部依赖(可选)
埋点设计(可选)
开关
负面影响面
估时
测试要点
参考资料(可选)
需求分析
从研发角度,对需求进行剖解。
问题定义
需求需要解决什么问题?例举出问题列表
问题定义示例
问题:
在当前的客户支持系统中,客户会遇到长长的等待时间、查询路由效率低下以及缺乏自助服务选项,导致客户沮丧和不满。
问题陈述:
开发一个新的客户支持系统,该系统显著缩短等待时间,有效地将查询路由到适当的代理,并提供自助服务选项,以使客户能够独立解决问题。
用正确的方式,解决正确的问题。而不是,用正确的方式,解决错误的问题。
需求背景
需求上下文和范围是什么?需求流程以及流程节点包含哪些?从开始输入到结束输出是什么?
需求目标
需求目标是什么?业务需求,目标应该是曝光率、点击率、转换率等相关;技术需求,目标应该是可量化的的指标,如下载成功率,覆盖率等
需求清单(可选)
检查需求是否合格?如果不合格,就应该退回需求,等需求完善后,重新再开始。
可根据需求本身,例举出需求核对表。下面是《代码大全2》提到的需求核对表:
需求核对表
针对功能需求
- 是否详细定义了系统的全部输入,包括其来源、精度、取值范围、出现频率等?
- 是否详细定义了系统的全部输出,包括目的地、精度、取值范围、出现频率、格式等?
- 是否详细定义了所有输出格式(Web页面、报表,等等)?
- 是否详细定义了所有硬件及软件的外部接口?
- 是否详细定义了全部外部通信接口,包括握手协议、纠错协议、通信协议等?
- 是否列出了用户想要的全部事情?
- 是否详细定义了每个任务所用的数据,以及每个任务得到的数据?
针对非功能需求(质量需求)
- 是否为全部必要的操作,从用户的视角,详细描述了期望响应时间?
- 是否详细描述了其他和计时有关的考虑,例如处理时间、数据传输率、系统吞吐量?
- 是否定义了安全级别?
- 是否详细定义了可靠性,高扩软件失灵的后果、发生故障时需要保护的至关重要信息、错误检测与回复的策略等?
- 是否详细定义了机器内存和剩余磁盘空间的最小值?
- 是否详细定义了系统的可维护性,包括适应特定动能的变更、操作环境的变更、与其他软件的接口变更能力?
- 是否包含对“成功”的定义?“失败”的定义呢?
需求的质量
需求是用用户的语言书写的吗?用户也这么认为吗?
每条需求都不与其他需求冲突吗?
是否详细定义了相互竞争的特性之间的权衡——例如,健壮性与正确性之间的权衡?
是否避免在需求中规定设计(方案)?
需求是否在详细程度上保持相当一致的水平?有些需求应该更详细地描述吗?有些需求应该更粗略地描述吗?
需求是否足够清晰,即使转交给一个独立的小组去构建,他们也能理解吗?开发者也这么想吗?
每个条款都与待解决的问题及解决方案相关吗?能从每个条款上溯到它在问题域中对应的根源吗?
是否每条需求都是可测试的?是否可能进行独立的测试,以检验满不满足各项需求?
是否详细描述了所有可能的对需求的改动,包括各项改动的可能性?
需求的完备性
对于在开始开发之前无法获得的信息,是否详细描述了信息不完全的区域?
需求的完备度是否能达到这种程度:如果产品满足所有需求,那么它就是可接受的?
你对全部需求都感到很舒服吗?你是否已经去掉了那些不可能实现的需求——那些只是为了安抚客户和老板的东西?
相关文档
列出相关文档:
- 需求文档链接
- 服务端技术文档(可选)
- 前端技术文档(可选)
- 依赖SDK技术文档(可选)
设计目标
明确此方案将要实现的目标。如:
- 研发角度:新增或修复或优化哪些功能,这些功能的性能指标有哪些:帧率、内存占用、响应时间、下载和上传耗时,并发或串行执行,跨平台提效等
- 产品角度:pv,uv,点击率,转换率等
- Owner角度:上线计划,迭代节奏,里程碑等
明确要实现的目标,方便评估出该需求的ROI:投资回报率。
技术方案
描述技术方案的总体思路和关键技术细节,可以用架构图、流程图、类图、时序图、伪代码等表示,总之,能让人快速对此技术方案了解
架构图(可选)
复杂需求或项目需要提供架构图,画架构可以是使用工具:processon、drawio、plantuml、staruml等
在架构设计时,应该考虑哪些方面,可以参考《代码大全2》:
架构指的是适用于整个系统范围的设计约束
架构的重要组成部分包含:
- 程序组织:定义好模块(构造块,可以是单个类,也可以是许多类组成的一个子系统)
- 主要的类:定义类的责任,如何与其他类交互,类的继承、包含关系,对象持久化等
- 数据设计:定义所用到的数据模型,存储方式:文件,数据库等
- 业务规则:描述依赖的特定业务规则
- 用户界面设计:明确UI/UE
- 资源管理:线程、内存、文件等管理
- 安全性:保护用户秘密数据,使用数据加密,权限设置等提高安全性
- 性能:制定性能目标,帧率、Crash率、ANR率、OOM率,耗时等
- 可伸缩性:是否满足未来的需求
- 互用性:与其他程序共享数据或资源。如一个公司多app,共享登录
- 国际化/本地化:支持多语言,支持网络,支持设备硬件条件等
- 输入输出:模块、接口、方法输入输出
- 错误处理:检测错误,从错误中恢复,如何传播错误,错误处理约定,错误处理机制等
- 容错性:从错误中恢复或不能恢复
- 架构的可行性:在当前环境(项目环境,用户环境,有限资源等)下如何实施。在任何方面都是可行
- 过度工程:按需设计,不过度设计
- 关于“买”还是“造”的决策:使用现成的还是自己创造
- 关于复用的决策:说明符合复用的目标
- 变更策略:说明可预见的变更,以及这些变更的应对策略
架构需要说明,为什么这么做?为什么不那样做?不是向来就这么做。
架构设计完,如何评估该架构是否能满足需求?与上面《需求核对表》一样,这里也有一份架构核对表:
架构核对表
针对各架构主题
- 程序的整体组织结构是否清晰?是否包含一个良好的架构全局观(及其理由)?
- 是否明确定义了主要的构造块/模块(包括每个构造块的职责范围及与其他构造块的接口)?
- 是否明显涵盖了“需求”中列出的所有功能(每个功能对应的构造块不太多也不太少)?
- 是否描述并论证了那些最关键的类?
- 是否描述并论证了数据设计?
- 是否详细定义了数据库的组织结构和内容?
- 是否指出了所有关键的业务规则,并描述其对系统的影响?
- 是否描述了用户界面设计的策略?
- 是否将用户界面模块化,使界面的变更不会影响程序其余部分?
- 是否描述并论证了处理I/O的策略?
- 是否估算了稀缺资源(如线程、数据库连接、句柄、网络带宽等)的使用量,是否描述并论证了资源管理的策略?
- 是否描述了架构的安全需求?
- 架构是否为每个类、每个子系统、或每个功能域(functionalit area)提出空间与时间预算?
- 架构是否描述了如何达到可伸缩性?
- 架构是否关注互操作性?
- 是否描述了国际化/本地化的策略?
- 是否提供了一套内聚的错误处理策略?
- 是否规定了容错的办法(如果需要)?
- 是否证实了系统各个部分的技术可行性?
- 是否详细描述了过度工程(overengineering)的方法?
- 是否包含了必要的“买 vs. 造“的决策?
- 架构是否描述了如何加工被复用的代码,使之符合其他架构目标?
是否将架构设计得能够适应很可能出现的变更?
架构的总体质量
- 架构是否解决了全部需求?
- 有没有哪个部分是“过度架构/overarchitected“或”欠架构/underarchiected“?
- 整个架构是否在概念上协调一致?
- 顶层设计是否独立于用作实现它的机器和语言?
- 是否说明了所有主要的决策动机?
- 你,作为一名实现该系统的程序员,是否对这个架构感觉良好?
流程图(可选)
如果需求中涉及较复杂逻辑,那么需要提供流程图来描述逻辑,关键流程及节点
可以使用processon画流程图。
类图(可选)
如果需求中涉及需要组织成一个模块来开发,那么需要提供类图描述逻辑
可以使用staruml画类图。
时序图(可选)
如果需求中涉及与服务端、前端、其它服务模块交互通信,需要提供时序图。
伪代码(可选)
对于核心功能,关键算法,程序交互等可以使用伪代码描述逻辑
伪代码主要帮助理清逻辑(抽象到具体),第一步、第二步、第三步、第x步应该是怎样的。
外部依赖(可选)
新增或升级三方模块或SDK依赖,需要对依赖项进行描述。比如:依赖项功能点,性能报告(Crash率,OOM等),安全性(用户数据会不会泄漏,有没有隐私权限设置)等
埋点设计(可选)
涉及数据回收,需要说明相关埋点信息
开关
对于不能完全掌控的场景,如
- 修改影响多个业务方
- 横跨多个版本迭代的需求,第一次上线
- 重构代码
- 在不熟悉的业务中新增 Feature
- 产品或数据分析或老板关心的业务更改
在这些场景下,需要添加开关。开关包含灰度,监控,应急开关:
- 灰度:1%,5%,10%,15%等依次放量
- 监控:监控是否健康
应急:止损开关
负面影响面
说明可能带来的负面影响,也就是是否导致劣化。负面影响面类别可以是:
- 业务影响,如:降低转换率,增加耗时等
- 性能影响:帧率降低,可能会OOM等
- 包体积影响:增加包体积
- 流量影响:费流量
- 内存影响:耗内存
- 电量影响;耗电
估时
对该需求进行开发时间估时(单位:人/天),以及明确提测节点,上线节点
测试要点
描述出测试要点及影响范围,给出具体场景,如:
- 修改点:更改了上传文件的压缩方式
- 影响面:对图片(png,jpg,gif格式),音频(m4a),视频(mp4)不同类型和大小的文件,在上传完后是否完整,上传时间是否缩短
参考资料(可选)
列出参考资料链接
总结
为了让需求顺利进行,准时保质保量交付,在需求 → 编码之间添加技术方案节点,技术方案主要做需求分析和架构设计(或技术分析)。在做完技术方案后,应该对该需求是什么,以及如何完成该需求有清晰的认识,并且接下来就能根据技术方案推进需求上线。总之,技术方案目的就是降低风险,有理有据,稳步向前的让需求落地。
文档信息
- 本文作者:Wang Jiang
- 本文链接:https://wjrye.github.io/2024/05/06/Before-Write-Code/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)