如何写好技术方案

2022-08-31 11:10:04 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

本文将介绍写技术方案的意义,如何评判技术方案的好坏,如何写好技术方案。

写技术方案的意义

写技术方案根本目的是提高研发效率和质量,具体体现在以下方面:

1、提高沟通效率

对于整个团队,通过技术方案文档和评审对齐提高沟通效率:

  • 产品经理可以审查技术方案是否与产品设计有偏差,是否满足当前产品需求和后续产品设计规划;
  • 开发leader可以把控方案是否满足技术要求,包括技术规范,性能要求,实现复杂度,可拓展性等;
  • 测试同学可以掌握需求技术实现原理,改动点,影响点,再做针对性测试用例设计;
  • 后续接手项目的同学可以通过技术方案文档熟悉系统。

2、提高开发效率和质量

对于开发同学,通过写技术方案,把需求和实现提前梳理一遍,减少等到编码阶段才发现前期考虑不全导致返工的情况;并且写好技术方案再编码,使得编码时思维更加清晰,提高编码效率和质量。

怎么样才是好的技术方案

怎么样才算是好的技术方案,至少需要满足下面3个条件:

1 思路清晰

在讲技术需求时,常见的问题是一上来直接给出解决方案,导致受众不能理解为什么要这样设计。其实相比解决方案,更重要的是怎么思考的,思考的过程非常重要。思路就是思考的线索,思路清晰的方案,层次分明,让受众快速理解清楚。

整个技术方案思考的线索可以用5W2H分析法串起来:Why、Who、When、Where、What、How 和 How much(如下图所示),从七个方面去分析思考:

整个技术方案需要先基于需求背景,定义清楚要解决的问题,明确目标,搞清楚 Why。定义清楚问题之后,再从When,What,Where,How等不同的角度,对问题进行分析和解决,先讲整体架构,再细化流程,先主线,再分支,先正常链路,再异常链路。

2 满足需求

技术方案满足的需求包括功能需求和质量需求。功能需求不仅是当前产品提出的功能需求,还要对未来需求的扩展有一定的规划,预留好扩展点,这就要求开发在规划设计前,对现状和需求进行充分的收集和分析。

除了功能需求,更考验开发同学技术实力的是质量需求,包括异常处理,降级方案,灰度方案,运维方案,高可用设计。设计时要结合具体业务场景,当前项目阶段,做合理的权衡,避免陷入极端:或面面俱到,过度设计;或方案过粗,考虑不周。

3 可实施

可以这样评估一个技术方案是否可实施:技术方案完成之后,其他人能否照着技术方案按时按质完成开发并上线?有的技术方案看似高大上,高瞻远瞩,开发实施起来却困难重重,常见原因如下:

  • 不够细:涉及改动的字段,报文,异常情况,边界情况,历史数据兼容等处理没说明清楚
  • 做不完:方案做的调整过大,虽然能解决问题,但是实施起来时间不够

在写技术方案时,方案需要足够完善详细,把开发涉及的关键点考虑完善,这些点没有先界定清楚的话,开发的时候容易才发现跟系统当前现状有冲突,或者开发出来偏离方案设计。

方案的设计也要考虑时间,开发成本,是否符合系统现状、团队可调配的资源,有些方案从技术的角度是最佳,但是从实施的角度并非最佳,例如会额外引入上下游系统相应的改动,带来一定的沟通协作成本。所以方案设计在考虑产品和技术等限制的同时,也需要考虑当前现状,要求的上线时间等其他因素,选择最合适的技术方案。可以在方案中写不同的实现的评估对比,进行取舍权衡,或者方案拆成不同的开发实施阶段。

方案的组成

做技术方案设计的前提条件是,定义清晰的业务流程,明确的期望拿到的预期结果。技术方案的各个组成部分围绕整个产品的研发周期,用一张图总结如下:

1 需求说明

为什么产品文档介绍过需求,技术方案里面还要写需求说明?主要原因如下:

  • 介绍需求:通过在技术方案里面简明扼要介绍产品需求,有利于其他看技术方案的人快速理解需求,后面具体技术实现的出发点。
  • 对齐需求:需求说明部分体现了开发同学对产品需求的理解,在技术评审阶段进一步与产品同学检查对齐一遍,减少理解出现偏差。

需求说明包括需求背景和需求拆解:

(1) 需求背景

说明为什么需要做这个需求,需求的价值意义是什么。

(2) 需求拆解

从需求实现的维度对需求拆解成相对各自独立子需求,并概要地说明每个子需求要做哪些内容,可以依据实际情况按照不同的角度来拆解,常见拆解的角度有:

  • 实现的步骤流程
  • 功能模块、业务领域
  • 对外提供的接口、服务

2 概要设计

思路不清晰的技术方案有一个常见的问题:在交代完需求背景之后,就直接开始介绍每个子需求的具体实现。这种技术方案各个部分比较分散细碎,没有统一成整体,阅读起来并不好把握,这些设计背后的思路是什么,为什么要这样设计。

概要设计包括系统现状,总体思路和系统架构。

(1) 系统现状

为什么需要写系统现状?一方面是有些产品需求文档涉及系统现状这块并不清晰,例如需求文档写成“在系统当前实现逻辑的基础上,进行xxx调整”,因此需要在技术方案对系统现状进行补充说明。另一方面,介绍系统现状能方便理解后续设计的出发点,在技术评审时方便评估当前设计的合理性以及是否有遗漏的点。

系统现状可以针对需求的内容,需求影响点来介绍,常见的内容可以介绍系统当前处理逻辑,历史数据的数据量,请求量,数据增长量等情况。写系统现状时,不需要面面俱到,而是结合当前需求,针对性地重点介绍与需求相关系统的情况,为接下来介绍总体思路,系统架构做铺垫,其他不太相关的现状可以简单带过或者不介绍。

(2) 总体思路

写总体思路可以为后面介绍整个详细解决方案奠定基础:对方案进行信息压缩,后面的详细方案介绍都是围绕着总体思路进行展开,使得整个方案阅读起来方向明确,思路清晰。总体思路的内容是概括性介绍需求实现涉及关键问题的解决方案。

(3) 系统架构

概要设计中的系统架构是总体思路进一步补充,说明系统总体上的架构设计,画系统架构图是介绍清楚系统架构的有效手段。在概要设计中的架构与详细设计中的架构的关键区别在于,前者关注系统整体处理,后者关注子需求的具体实现。在概要设计中介绍的架构图常见的归类有:

  • 按照系统模块和处理流程介绍,介绍各个模块处理的步骤,系统间的交互。
  • 按层级介绍,把具有相同属性或特征的信息块归为同一个层级,例如系统MVC分层架构。

画图时,注意不要想在一张图里面做到面面俱到,画之前要想清楚这张图要表达什么内容,传递什么信息,再针对性来画,不同的类型的图不要合在一起。例如想说明系统的部署结构用部署图,说明业务的主要流程用流程图;如果图里面,既有系统部署涉及的基础组件,又有业务处理流程,图表现出来的信息就比较混乱。

3 详细设计

详细设计可分成开发约定,功能实现,可维护性设计,可靠性设计,方案选择。

(1) 开发约定

开发约定部分常见介绍的内容如下:

  • 方案新引入的名词,概念的解释,方便后面的内容引用。
  • 前期上下游对接达成一致的约定/协议。

(2) 功能实现

软件系统工作的核心功能是对数据的处理。因此在技术方案介绍具体功能实现时,重点关注的点是数据链路,包括:

  • 数据源:系统的流量来源、业务在何时何地触发,例如对外提供的接口,定时任务,MQ消费等
  • 计算转换:数据如何做转换运算,加工处理的流程
  • 存储:数据存储设计

为了介绍整个数据处理流程,体现在以下方面:

  • 接口设计:提供接口设计文档,包括入参出参字段定义,接口参数校验逻辑,异常情况的处理和返回的错误码。
  • 系统间交互流程:结合系统间流程图说明整笔业务请求涉及哪些系统组成部分,业务的发起来源,系统间交互调用了具体哪个接口,请求处理基本步骤和数据落地存储逻辑。
  • 系统内处理流程:结合业务处理流程图说明请求如何加工计算数据,处理的具体步骤,最终处理完成之后结果如何保存,或者传输到什么地方。
  • 存储设计,包括存储结构(包括MySQL、ES、Redis、OSS等)设计,包括表和字段的概念定义,各个表之间的关联,业务系统如何使用这些库表。

(3) 可维护性设计

可维护性设计关注的是后续系统的迭代升级,需求变更,系统怎么维护的问题。这块的关键点主要是代码复杂度问题,不好维护的系统,会因为系统引入一个新需求,整个系统需要做大量改动。因此系统需要考虑通过提前做一些可拓展设计方便后续维护,体现在以下方面:

  • 拓展点分析:结合产品需求分析后续扩展带来的变化点,为了支持这些变化系统需要预留哪些扩展点。
  • 系统建模:针对变化点,对系统对象进行建模,主要关注:模块(职责明确的模块或者组件)、关系(组件间明确的关联关系)、边界(约束和指导原则)。
  • 设计模式:使用设计模式时,要注意设计模式的底层逻辑是“找到变化,封装变化”,将变化封装在可控范围内,具体介绍设计模式涉及的类图,以及拓展新需求时,系统需要做的变动。
  • 配置项:包括配置项的具体定义,使用注意事项。

(4) 可靠性设计

可靠性设计包括以下要点:

灰度方案

如果是新系统初步上线用于替代老系统,新系统还需要经过进一步线上验证,这时需要考虑灰度方案,包括灰度的周期计划,灰度的范围/维度,灰度配置策略。

容量评估

容量评估需要根据请求量,评估要预留给程序多少相应的运行资源。包括内存,磁盘,CPU,存储服务等。评估的点包括:接口平均QPS、峰值QPS、接口请求和返回报文大小,消息队列的平均消息数、峰值消息数、报文大小。这一部分如果是改动的业务,可以参考以前的监控,如果是新业务或者新活动可以跟运营、产品确定业务量。若预估峰值会很高,需要进行压测。

监控报警

当方案不确定性比较大,容易出错,一旦出错造成的影响较大,需要加监控告警,说明的信息包括:模块,监控指标,监控阈值,报警方式等。

(5) 方案选择

当我们设计了一个方案之后,评估这个方案是不是最优方案最简单的办法,就是看看还有没有更优的方案。不同方案如何做评估选择?可以做360度全面评估对比,具体的操作方式为:列出我们需要关注的质量属性点,然后分别从这些质量属性的维度去评估每个方案,再综合挑选适合当时情况的最优方案

常见的方案质量属性点有:性能、可用性、硬件成本、项目投入、复杂度、安全性、可扩展性等。在评估这些质量属性时,需要遵循架构设计的原则:“合适原则”和 “简单原则”,避免贪大求全,基本上某个质量属性能够满足一定时期内业务发展就可以了。

4 测试方案

良好的测试用例设计能有效提高开发质量,技术方案中不仅需要考虑开发自测,为了进一步提高研发质量,还需要考虑如何提高测试同学的测试质量和效率。技术方案在测试这块需要考虑的点包括:影响点,自测用例,测试注意点。

(1) 影响点

影响点可以用清单的形式列出本次开发影响了哪块功能,哪些接口,接口url,改动的内容是什么。这样测试同学在设计测试用例时可以做对照参考,减少功能遗漏测试的情况。

(2) 自测用例

自测用例是介绍说明需求自测的用例设计,可以用清单的形式列出,一般包括涉及场景,测试步骤,测试输入,期望输出等信息。

(3) 测试注意点

有些隐藏的异常情况处理,边界条件,特殊处理逻辑,如果没有特别说明,测试同学测试的时候很容易遗漏这块,而线上bug往往出现在这一块。所以可以在方案里面特殊指出这块,让测试同学在测试的时候特别注意一下。

5 上线部署

不想需求上线后各种问题,疲于应对,那就有必要在技术方案阶段考虑上线部署的问题,在技术方案设计中先提前准备好,等到上线阶段对着技术方案写的注意事项,步骤进行一步步检查和执行,减少上线事项遗漏或者处理出错的情况。

上线部署部分涉及的点包括环境准备,系统准备,发布顺序,线上验证;

(1) 环境准备

系统依赖环境的准备包括MySQL、Redis、MQ、ES和Nginx等服务搭建和初始化,机器资源等。

(2) 系统准备

系统准备常见主要如下:

  • 依赖的服务配置,数据更新,例如数据库表创建,SQL初始化脚本,Nginx配置更新,MQ的topic创建,网络端口打通,监控配置,IP白名单申请,定时任务创建。
  • 引用服务项目配置更新,代码检查,分支merge。

(3) 发布顺序

发布部署的服务之前有业务依赖关系,被依赖的服务需要先发布部署,如果这种依赖关系,在技术方案中应当标明。

(4) 线上验证

线上验证的部分,需要说明服务部署之后,怎么验证服务是否正常,需要做哪些检查验证项。例如telnet检查端口是否通,日志是否有报错,通过线上测试账号走一笔业务看看是否正常,监控面板要看哪些指标。

在开发和测试阶段,当配置项,脚本,配置出现更新调整,需要更新保存在技术方案文档里面,上线时照着文档操作,不容易遗漏。

总结

想成为优秀的开发人员,不能只局限在开发领域,而是必须要有跨界的意识,包括产品意识,测试意识、项管意识和运维意识:

  • 产品意识:理解产品的具体业务流程是什么,产品为何这样设计,目前业务规划的发展方向,主动沟通产品方案中的不合理之处,提供参考解决办法。
  • 测试意识:技术方案中要考虑测试同学如何测试,提供必要的细节信息支撑测试,例如数据更新存储流程。开发提测前对涉及的影响点做必要的自测,主动沟通测试同学的测试方案的不合理或遗漏的点之处,提供参考解决办法。
  • 项管意识:对任务进行合理分解,在开发、测试、上线流程中,要及时发现影响整体进度的问题点,主动协调解决或者上报反馈,按照计划主动推进项目保障最终按时按质上线。
  • 运维意识:对系统的日常运维、容量和系统瓶颈、系统流量增大扩容方案要有一定的认识和解决方案,保障业务正常使用。

工具推荐

  • 思维工具:结构化分析法、5W2H分析法
  • 脑图软件:Xmind、百度脑图
  • 画图软件:ProcessOn、PPT、PlantUML

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/143486.html原文链接:https://javaforall.cn

0 人点赞