加餐 结束语
加餐 软件设计文档示例模板
在[第9篇文章]中,我讲了每种UML模型图的画法,以及这些画法分别适用于什么样的设计阶段,我们也可以将不同阶段输出的模型图放在一个文档中,对每张模型图配以适当的文字说明,构成一篇设计文档。
对于规模不太大的软件系统,我们可以将概要设计文档和详细设计文档合并成一个设计文档。这一篇文章中,我会展现一个设计文档示例模板,你可以参考这个模板编写你的设计文档。
文档开头是设计概述,简单描述业务场景要解决的核心问题领域是什么。至于业务场景,应该在专门的需求文档中描述,但是在设计文档中,必须要再简单描述一下,以保证设计文档的完整性,这样,即使脱离需求文档,阅读者也能理解主要的设计。
此外,在设计概述中,还需要描述设计的非功能约束,比如关于性能、可用性、维护性、安全性,甚至开发和部署成本方面的设计目标。
然后就是具体的设计了,第一张设计图应该是部署图,通过部署图描述系统整个物理模型蓝图,包括未来系统长什么样。
如果系统中包含几个子系统,那么还需要描述子系统间的关系,可以通过子系统序列图,子系统活动图进行描述。
子系统内部的最顶层设计就是组件图,描述子系统由哪些组件组成,不同场景中,组件之间的调用序列图是什么样的。
每个组件内部,需要用类图进行建模描述,对于不同场景,用时序图描述类之间的动态调用关系,对于有复杂状态的类,用状态图描述其状态转换。
具体示例模板如下:
1 设计概述
……系统是一个……的系统,是公司……战略的核心系统,承担着公司……的目标任务。
1.1 功能概述
系统主要功能包括……,使用者包括……。
1.2 非功能约束
……系统未来预计一年用户量达到……,日订单量达到……,日PV达到……,图片数量达到 ……。
- 查询性能目标:平均响应时间<300ms,95%响应时间<500ms,单机TPS>100;
- 下单性能目标:平均响应时间<800ms,95%响应时间<1000ms,单机TPS>30;
- ……性能目标:平均响应时间<800ms,95%响应时间<1000ms,单机TPS>30;
- 系统核心功能可用性目标:>99.97%;
- 系统安全性目标:系统可拦截…… 、……、……攻击,密码数据散列加密,客户端数据HTTPS加密,外部系统间通信对称加密;
- 数据持久化目标:>99.99999%。
2 系统部署图与整体设计
系统上线时预计部署……台物理机,……个子系统,和公司……系统交互,和外部第三方……个系统交互。
2.1 系统部署图
子系统1的功能职责为……,部署……台服务器,依赖……和……子系统,实现 ……功能。
子系统2参照子系统1来写。
2.2 下单场景子系统序列图
- 下单时,子系统先发送……消息到子系统3,子系统3需要执行……完成……处理,然后发送……消息到财务系统,消息中包含……数据。
- 收到……的处理结果……后,子系统1发送……消息到……子系统2……。
2.3 退款场景子系统序列图
- 退款子系统先发送……消息到子系统3,子系统3需要执行……完成……处理,然后发送……消息到财务系统,消息中包含……数据。
- 收到……的处理结果……后,子系统1发送……消息到……子系统2……。
2.4 退款场景子系统活动图
如图所示:
- 退款开始时,子系统1处理XXX,然后判断m的状态,如果m为真,请求子系统3处理ZZZ,如果m为假,子系统继续处理ZZZ并结束。
- 子系统3处理ZZZ后,一方面继续处理XYZ,一方面将……消息发送给财务通进行AAA处理。
- 子系统在处理完XYZ后,返回子系统继续梳理YYY,然后退款处理结束。
3 子系统1设计
子系统1的主要功能职责是……,其中主要包含了……组件。
3.1 子系统1组件图
子系统1包含6个组件:
组件1的功能主要是……,需要依赖组件2完成……,是子系统1的核心组件,用户……请求主要通过组件1完成。
同样的,组件2也可以参照组件1来这样写。
3.1.1 场景A组件序列图
对于场景A,首先组件1收到用户消息CCC,然后组件1调用组件2的XXX方法……。
3.1.2 场景B组件活动图
在场景B中,首先组件收到……消息,开始处理……,然后判断……,如果为true,那么……,如果为false,那么……。
3.2 组件1设计
组件1的主要功能职责是……,其中主要包含了……类。
3.2.1 组件1 类图
Class1实现接口Interface1,主要功能是……,Class1聚合了Class2和Class3,共同对外提供……服务,Class1依赖Class4实现……功能,Class4……。
3.2.2 场景A 类序列图
在场景A中,当外部应用调用类1的create方法时,类1……。
3.2.3 对象1状态图
对象1运行时有4种状态,初始状态是状态1,当条件1满足是,状态1转换为状态2,当条件3满足时,状态2转换为状态4……。
3.3 组件2设计
重复上面的格式。
4 子系统2设计
重复上面的格式。
结束语 期待未来的你,成为优秀的软件架构师
软件编程似乎是一件没有门槛的工作,任何接受过义务教育的人经过一些基本的编程培训就能够写一些可以执行的代码。但是,想要设计一个架构良好、易于维护、富有弹性的系统,却是一件非常困难的事。就我所见,很多项目团队压根没有“系统架构设计”这样一个软件开发阶段,也没有一个对整个系统技术架构掌控的人,项目管理者往往只是关注内外部的各种沟通,和人员、进度的管理,任由系统架构在日趋一日的开发过程中逐渐腐烂。
我怀疑很多软件工程师从来没有体会过良好架构设计带来的好处:系统模块、层次边界清晰,团队每个人的工作都很少耦合;需求变更不需要在一大堆代码中改来改去,只要扩展几个类就轻松实现;用户量快速增加时,只需要变更部署方案就可以应对,甚至不需要改动代码。而得到最大好处的则是老板,他不必因为急剧膨胀的技术人员招聘预算而愁眉不展,也不必在公司年会上宣布996加班而被整个业界的唾沫星淹死。
一个优秀的软件架构师应该能够设计一个良好架构的系统,并在它漫长的生命周期中保持架构持续演进、清晰合理。一个优秀的软件架构师应该能够写漂亮的技术PPT,也能写漂亮的代码,让自己开发的核心代码支撑起系统的核心架构,又让自己的架构方案得到大多数人的拥护。一个优秀的软件架构师应该有宏观的技术视角,能够用更广阔的愿景去诠释当前项目的技术、架构和未来的演化趋势。一个优秀的软件架构师应该拥有某种技术影响力和领导力,无需职位上的权力就可以让其他工程师听信于他。一个优秀的软件架构师还应该掌握一些特别的管理、谈判技能,让自己的技术构想被其他工程师、项目经理、老板和用户接纳。
如何才能拥有这些能力,成为一个技术团队中值得信赖的优秀软件架构师?这就是我的专栏想要为你呈现的答案。但是受专栏篇幅,以及个人的能力、精力所限,我只能尽力将相关的内容进行有组织、自洽地呈现,为你展现出这些内容的核心思想以及其内在的关联性。而要想真正将这些内容融会贯通,内化为自己的知识和技能,还需要你在工作中更多地思考和实践。
电影《百万美元宝贝》中说:“拳击是一种不自然的运动。因为拳击中的每样东西都和本能是相反的。你想向左移动,不是向左迈步,而是右脚用力。向右移动的时候左脚用力。想打出一记重拳,你需要后退一步。面对打击,你要迎着疼痛而上,而不是像有理智的人那样躲避。”
我们在职业技能进阶的道路上也是如此,你如果依着本能,跟着潮流,除非你极有天分,否则很难超越自己和环境。架构师的成长之路是一条攀登之路,你需要有意识地训练自己,不断挑战自己。架构师的成长之路是一条修行之路,你要和自己的本能做对,不断审视自己,让自己从舒适区跳出来,针对自己的不足和缺陷为自己设计有困难的任务和目标。
这条路注定艰辛,但是走在这样的人生之路上,你会充分体验到超越自我的愉悦,理解到生而为人的自由意志,也许这也是人生的某种意义吧。
对我而言,这是我在极客时间开设的第二个专栏,第一个专栏是[《从0开始学大数据》]。在这两个专栏的筹备、更新过程中,留言、互动让我受益良多,感谢一路以来的支持与陪伴。