zoukankan      html  css  js  c++  java
  • 为什么要写设计文档

    日趋一日,程序员能够在更少的时间内完成更多的事情。使用今日的高级编程语言,开发环境,工具和“快速应用开发”思想,程序员和经理都已经习惯于急速的开发周期。今日的程序员更倾向于直接跳入到编码之中,害怕花费在非编码工作中的每一小时,都会导致项目截止日期前的周末多加一个小时班。

      编码之前做设计这一过程已经变得过时了,将设计文档化就更罕见了。很多程序员从来没有写过设计文档,面对要写设计文档这一想法都畏缩不前。即使被要求写,通常来说也只是产出了一大堆的交互图和类图,这些图表大多没有表达程序员在设计阶段的思考过程。本文将简明扼要地讨论如何不用特殊工具写出有效的设计文档,同时无需了解UML。文中也会谈到为什么一个好的设计文档是在开始一个新项目时,程序员可以拥有的最有价值的工具之一。

    为什么要写设计文档?

      一篇设计文档是一个你同他人交流的工具,来阐明你的设计决策是什么以及为什么你的决策是好的。不要担心你的设计不符合UML标准,也不要担心你没有使用特殊的建模工具来创建它。决定你的设计文档优劣的最大因素,是它是否清晰的解释了你的意图。

      然而这引出了一个问题,为了传达设计决策,你需要去考虑听众是谁。一个程序员同行会理解为什么一个精心设计的类抽象是一个好的设计,然而你的经理可能不会。因为你的程序员同行和你的经理对于什么是好设计有不同的概念,所以需要有两份设计文档;一份给同行,一份给经理。当你开始你的项目时,每份文档为了不一样但有同等价值的目标服务。

      这看起来是过多的工作,但它实际上不是。本文将向你展示如何通过文档的重用来完成它。

    哪些因素造就了一个好的设计?

      通常,如果一个设计通过有意义的方式实现了需求,它就被认为是好的。如果设计的任意一个方面拿不出正当理由,那么它可能就需要被重新评估。很多程序员试图在他们的设计中包含进设计模式,这常常只会增加不必要的复杂性。你需要能列举出至少一个令人信服的与需求相关的理由,去解释为什么要做出这样的设计决策。然后这些理由也需要被文档化。如果你面对一个设计决策无法拿出一个清晰的理由,那么它可能没有给你的设计增加任何价值。

      图表是将你的设计可视化的伟大工具,但它们无法传达你的设计决定背后的动机。这就是为什么关键的是,让你的图表补充你的设计文档,而不是充当设计文档。

      另外一个关键点是,要记录你的设计决策带来的好处。通过这样做,其它阅读你的文档的人将能理解他们所能获得的价值。同理,任何关联的风险也要被记录下来。多数情况下,其它程序员可能面对过相同的风险,可能会有你没有想过的有用的观点或者方法。通过列出这些条目,你也让他人去思考潜在的风险。组员常常能看到当你在设计时无法觉察到的陷阱。重组织图表中的框图是很简单的,但如果编码过程中发现假定不成立,或者踩中了一个没有预见到的陷阱而需要重写几百行代码,则要困难得多。一个好的设计文档最小化了意料之外的混乱,因为它在编码前就将这些困难点定位出来了。

      最后,文档给你,你的经理和你的团队提供通用的语汇,来讨论这个项目。设计文档对于经理来说是有用的工具,因为它提供了一个深入项目之中的视野,而通常来说他们没有专门的技术知识去看到这些。通过列出好处,你给你的经理提供了切实的条目来描述为什么你的设计是可靠的。通过在开发之前记录你设计的风险,你将那些风险的责任传递给你的经理了,而那是他们应该承担的。

      还有,设计文档是一份你,你的经理和你的团队之间的契约。当你记录下你的假定,决策,风险等等时,你给其它人一个机会去说:“是的,这就是我所期待的。”一旦你的文档经过了设计阶段,它就是一个基线,用来在项目范围内控制变化。显然,需求将会时不时地改变,但有一个基线文档,你就有权力说项目内的所有变动都不是由于对需求的误解造成的。

    写给程序员同行的文档

      开发者设计文档的目标是确保你的想法是有效的,你的方法可以和别人正在做的工作相互配合。如果开发者之间不交流他们的计划,那么在不同的模块或者类开始交互时,灾难一定会爆发。以下条目描述了写这一类型文档的通用指南:

      第一节 - 陈述你的项目/子系统的目标: 在这一节中,写几个段落来描述你的项目或者子系统做了什么。它试图解决的问题是什么?为什么它需要存在?谁将会使用它?通过回答这些问题,你建立起设计的范围。如果你发现在这一节中要写出几个段落很困难,那你可能还没有将问题域理解到你需要的程度。如果你不能将你的描述在几个段落之内表达出来,那可能这个设计的范围太大了。将这一章节作为一个工具,来验证你的设计范围是合理的。

      第二节 - 定义你的设计中的高层实体: 高层实体是组成了你的主要设计结构的对象,或者一组对象。一个好的实体案例是一个数据访问层,一个控制对象,一组业务对象,等等。图一显示了一个例子:

    图一

      在这一节中,用几个句子解释每个实体会干什么。这些描述不必要太繁琐,只要足够能描述每一块的目的就行。确保描述你在图中定义这一实体的理由,以及它们的角色是什么。

      第三节 - 针对每一个实体,定义底层的设计: 这一节是定义你的对象和对象关系的地方。对每一个对象(或者对象集),要定义以下的内容:

    • 用法

      在一个段落中描述对象是如何使用的,它服务于什么功能。如果一个对象将会同外部对象或系统交互,那么展示对象的接口是个好主意。最重要的是,你必须再次描述你定义这一对象的思考过程。列出好处和风险。如果一个对象提供了封装,用一个句子描述为什么封装增加了价值。用你的描述赋予图表内涵。你不需要说得很繁琐,只需要讲清楚就行。

    • 配置

      如果你的对象需要特殊的配置或者初始化,这是个好地方去说明。如果没有,这一节可以省略。

    • 模型

      图二展示了一个例子,增补图一中的系统安全实体。这不是完美的UML图,但包含某些方面的UML元素。最重要的是,它描述了设计思路。

    图二

      不要担心你的模型是不完美的,但要确保描述清楚图表中发生了什么。此处,两个具体的安全对象继承自一个安全对象基类,一个安全工厂类会根据系统安全模型创建特定的安全对象。

    • 交互

      这一节也很适合画交互图。一个交互图会展示对象或实体集在完成一个复杂任务时如何相互交流。图三显示了一个用户如何登陆的例子。它用到了图一中的不同实体。

    图三

      再次强调,此图不是完美的UML,但它解释了完成复杂任务时的交流顺序。在你想用图表展示你系统中的一个对象如何同其它子系统中的对象交流,交互图是最有用的。这一类图表可以让其它开发者核实交互是否正确。

      第四节 - 好处,假定,风险/问题: 在这一节中,做一个列表列举此种设计的5至6个最重要的好处,一个列表列举所有已知的风险/问题,还有一个列表列举所有假定。其中一些可能只是重复你在之前章节中已经写过的。重要的是要将这些条目都放在一个章节中,这样如果读者想了解有哪些好处,风险和假定,就不需要去阅读整个文档。

      永远不要移除此章节中的任何内容!如果风险变成非风险,记录下它们现在不再是风险以及变化原因。不要简单地擦除它们。同样的原则也适用于假定。你应该能够一看本章节就立刻了解当前设计中的风险。

    写给经理的文档

      给经理的设计文档的目标,是要保证你的经理能理解系统主要的实体有哪些,有哪些好处,以及最重要的,有哪些风险,文档是你显示自己理解需求并给出了一个计划来实现这些需求的好机会。

      如果你写好了给程序员同行的文档,那么写给经理的文档是简单的,因为它仅由1,2和4章节构成。通过用上文描述的方法来划分文档,通常来说对经理没有太大意义的部分会包含在一个章节中,可以直接移除。

    结论

      写一篇文档最困难的部分跟“写作”没什么关系。难的是你要在开始编码之前完成一个符合逻辑的设计。一旦你能洞见对象和实体的组织方式,书写细节是简单的。另外,完成这一任务应该不需要除字处理程序和一个简单的绘图软件外的其它工具。在这一任务上花费一周时间所带来的积极效应,会在项目结束时带来难以想象的回报。正如格言所说:“如果你在做计划上失败了,那么你就是在计划着去失败”。

  • 相关阅读:
    同步、异步 与 阻塞、非阻塞
    【转】综合对比 Kafka、RabbitMQ、RocketMQ、ActiveMQ 四个分布式消息队列
    Kafka总结笔记
    SpringBoot笔记
    过滤器(Filter)和拦截器(Interceptor)的执行顺序和区别
    Java Lambda表达式
    腾讯云博客同步声明(非技术文)
    SpringBoot学习笔记(十七:异步调用)
    设计模式—— 十七:装饰器模式
    Java初级开发0608面试
  • 原文地址:https://www.cnblogs.com/zourui4271/p/4982961.html
Copyright © 2011-2022 走看看