设计的载体是什么

本贴最后更新于 2824 天前,其中的信息可能已经斗转星移

也是一篇发在公司内刊上的文章。

从参加工作开始,我就一直困惑于如何写设计文档。公司的各种规定和规范看起来很美,但真的执行起来却总让我头痛不已;同时,我也觉得自己喜欢的方式有些自由散漫,满足不了商业化开发的要求。直到前不久,偶然在网上看到了一篇题为《源代码就是设计》的文章后,我终于感觉自己把这个问题想得清楚些了,所以写了本文,与大家交流。这也许是篇偏激的文章,但我相信它提到的很多问题是我们难以回避的。

公司一直把文档作为设计的主要部分,并且,我认为,公司对这份文档的要求至少包含以下几点:

  1. 能够指导程序员编码。最好是设计师可以完全脱离编码,完成设计后能立即投入下一个项目。
  2. 提供评审和 QA 监督的依据,以便尽早发现不合格项,尽早纠正。
  3. 作为项目维护的依据。

但仔细想想会发现,文档并非做到这几点的必要条件。换句话说,有了文档不见得能做到,没有文档也不见得做不到。

首先,只要设计没有细化到本身就是代码的程度,程序员就不可能仅参照设计编码。这是因为,文档——即使是写作过程中使用了很多软件设计工具的文档——也是一种更接近自然语言的东西,而自然语言有一个天生的弊端——二意性。所以,不论它写的有多好,程序员理解起来也不会与设计师所想的完全一致。而让设计师完全脱离编码也是一个不太现实的想法,一个设计师或许能在一个项目中这样做,但如果每个项目是都是如此的话,他日后肯定会眼高手低,那时他的设计就根本没法用了。我们也许听到过一些新闻,说国外某项目的主设计师根本没写过代码。我不否认这些新闻,但我认为我们绝不能照搬这种模式,因为那些设计师往往是某方面的世界级权威,而人比人是要死的。

其次,评审和 QA 方面的目标也基本没有可能达到。因为大多数情况下这两个过程是“外行监督内行”。我这里并不是说参加评审的同事和项目组的 QA 水平不足,只是说相对于项目组成员,他们对项目的投入要少的多,对项目细节的了解也少的多。这种情况下还想让他们提出评审问题或监督项目执行,要求未免高了一些。以 XYZ 产品为例,评审阶段发现的问题数一般不多,到了 Y 项目更是可怜,只有组织级要求的几分之一了。而如果再仔细观察一下这些问题,还会发现其中绝大部分无关紧要,真正价值较大的往往只有一两个。至于 QA,由于其监督的主要是过程,所以更容易糊弄,并且极有可能是项目组的故意糊弄(评审上的一般是无意的)。我相信这种糊弄在各个公司都不罕见,前一段时间来培训单元测试的讲师就讲到过他们从前(应该是在华为)在项目中糊弄 QA 的事例。作为反例,公司的统计数据已经表明,代码走查这个内行监督外行的过程发现问题的效率是最高的。

第三,已有的经验也说明设计文档在项目维护过程中没多大用。从公司内部看,到目前为止我还不知道哪个项目是主要靠设计文档维护的。项目出问题后,我们首先想到的一般是找参与过项目的人,然后才是文档和其它的东西。我想这个过程应该能说明:人,而不是文档,才是项目维护中最重要的因素。当然,我们也可以说这是因为文档写的不够完美,不过我希望你读完本文后能同意“完美的文档是不可能的”这个观点。再者,从我接触过的开源项目看,项目的维护也不需要文档,开源项目一般没有太好的设计文档,但人们还是能仅仅通过源码和注释等就参与进去。另外微软的文档应该是非常好了,可开发时我还是要经常去看看 MFC、ATL 的源代码,因为那才是最准确的第一手资料,MSDN 上描述的不太清楚的东西,看看源码就一目了然了。

其实,我觉得,把文档看成设计不光满足不了公司的要求,还会带来其他的一些弊端,比如工作效率和一致性等。

作为开发人员,我想没有几个人喜欢写文档,我们常说“兴趣就是动力”,那没了兴趣肯定也就没动力了,所以写文档的效率也就可想而知了。以我自己做例子,我认为自己写文档的效率比写代码低的多。即使抛开主观因素,由于中英文输入效率的差别和画图与打字的效率差别,写文档的也要写代码慢不少。所以,一份“完美的设计文档”可能会大幅增加项目成本,以至于不能公司不会接受。

再进一步,就算能写出来一份“完美的设计文档”,我们也不可能一劳永逸,因为设计会变更。大家往往非常关注需求变更,但设计变更发生的更频繁,道理很简单:需求变更会导致设计变更,需求不变更设计也可能变更。设计发生变更的时候,代码或许已经完成了,加上工期的要求等,开发人员很有可能会先改代码后改文档,这时问题就出现了:开发人员会“忘了”改文档。或者即使他没忘,由于这份文档的初稿很“完美”,他要修改的地方会很多,工作量会很大,甚至要花数倍于他改代码所用的时间才行,再考虑上人的惰性、其他工作的压力等因素,他敷衍了事应该是再正常不过的了。而我们前面已经分析过,这种敷衍是很难被发现的。反正不管是因为什么原因,经过变更后,我们的“完美”文档就和代码对不上了。

XYZ 是一个以数据处理为主要功能的项目,所以我在刚开始时考虑了很长时间“在不能保证数据的正确性时应该怎么办”这个问题,最后的决定是把这些数据扔掉,因为我认为“错误的数据不如没有数据”。把这个原则应用到项目上来应该就是:错误的文档不如没有文档,即使这份文档看起来很“完美”。

回到《源代码就是设计》这篇文章上来。实际上,仅仅是它的标题就让我眼前一亮了。从上学时的《软件工程》教科书,到工作后的实际项目,先入为主的“设计是文档”让我一直没有仔细想过设计应该是什么。这篇文章给了我一个思考的机会,并且经过仔细比较后我发现:代码是比文档更好的设计载体,甚至是天生的设计载体。

我们经常把做软件和盖房子做对比,并把程序员比作建筑工人,这也带来了所谓“软件蓝领”的称呼。但我要说这个对比把程序员和建筑工人放在一块是不恰当的,最简单的理由是建筑工人把砖块磊整齐了非常重要,程序员把代码排整齐了则没那么重要(虽然也很有用)。我认为:程序员应该对应建筑设计师,编码应该对应画图纸。你也许会问:这个对比中,磊砖块对应什么?别着急,软件开发中还有一个大家已经见的太多以至于被忽视了的过程——编译,它对应着磊砖块,也就是把设计变成现实的这个过程,只不过由于软件开发的自动化程度太高,它完全被计算机完成了而已。如果我们把盖房子换成加工机器零件,这个对比的正确性就更明显了,现在自控机床已经能自动加工零件了,而以前,这个工作是要很多人工的。或许未来会有一种机器能根据图纸自动盖房子。我们发现了编译这个之前一直被忽视了的过程之后,应该会注意到,在把文档看成设计的那个对比中,盖房子没有与编译对应的过程,这也说明它是不恰当的。

把代码看成设计的一个显而易见的好处是消除了设计和实现的不一致性,编译代码速度很快,时间成本极低并且基本不需要人工,所以保证这二者的一致是非常容易的。另外它也提高了工作效率,因为主观方面开发人员更喜欢写代码,客观方面英文输入速度比中文快得多。

虽然有不少好处,但从文档到代码的这个转变有点太大,恐怕大家会非常怀疑它是否真的可行。下面我就来分析一下大家可能的疑问。

第一个问题是设计师和程序员如何协作,也就是说设计师怎么让程序员按照自己的想法去做事情。我们先来看设计到底是怎么进行的,乍一看大家可能认为设计是“想”出来的,但实际上它更多的是“试”出来的。任何一个项目都会有一些设计师之前没遇到过的问题,区别只是多少而已。对这些问题,设计师可能会在脑子里想一些方法,然后他就要去试验这些方法是否真的可行,而试验成功之时,也是针对这些问题的设计完成之时,并且,往往也是相关代码写完之时。基于这一点,我认为设计师在一个项目中的工作是完成系统框架和技术难点的开发,程序员则去做具体细节的开发。细节中的一些问题可能是程序员没有遇到过的,解决这些问题的过程,不管是完全靠自己还是求助于设计师,对程序员来说也是一个做“设计”的过程。所以,这种模式下,是不必严格区分设计师和程序员的,大家都是设计师也都是程序员,而这也正好符合“源代码是设计”这一观点。

第二个问题是如何审查监督。我的看法是把这项工作交给项目经理或主设计师,而不做严格的外部审查和监督。自己监督自己也许听起来不那么可行,但我相信大多数人,尤其是项目经理和主设计师,对项目是负责的,所以这样做效果不一定就不好。用人不疑,疑人不用,这句老话用在这里应该很合适。而且,我们前面已经分析过,如果项目组成员成心欺骗,外部监督机制也不见得有多大效果。

第三个问题是项目的风险会不会增大。设计做的不好一直被认为是项目拖期的主要原因之一,现在这个(按原来的观点)看起来根本没有设计的模式会不会加大这个风险呢?我觉得不会,因为它把编码提前了,而编码阶段是最容易发现问题的阶段,所以设计上的问题会被更早的发现,更早的修正,从而降低项目风险。另外,代码重构(在这个模式中相当于设计变更)的代价可能也没有想象的那么大,我自己经常重构大量代码,我觉得花的时间并不多。最后说句实话,XYZ 相关的项目一直都是先编码后文档,但它并没有因此发生过拖期,而且从公司的统计数字看,它的生产率也一直是高于组织级标准。

第四个问题是项目如何维护。前面我已经论证了文档不可能作为项目维护的依据,或者至少是主要依据,所以没有文档也不会让这个情况再变坏多少。另外,不做开发的人可能会觉得文档更易读,但开发人员就不是这样了,他们受过专业训练,对代码的条件反射更强烈,就像音乐家看到 123 会首先想到哆来咪一样。因此,项目维护是可以基于代码进行的,而且,稍后我会说明这种新的开发模式也并非没有任何文档。

前面的文字应该已经基本证明了“源代码就是设计”的可行性,但一个项目如果只有代码肯定也不行,因为代码的组织很松散,开发人员很难通过它们形成对系统的总体认识。所以,一些文档是必须的。下面我就对“应该有哪些文档”和“这些文档应该怎么写”发表一下看法。

第一份应该有的文档是需求,虽然它是需求阶段的输出,但我也要在这里强调它。我认为需求是一个项目中最重要的文档,它规定了系统开发出来后应该是什么样的,必须全面而详细。有经验的开发人员往往看到需求就知道“应该如何实现这个系统”或者“这个系统应该是怎么实现的”了。

第二份文档是系统的总体结构图和一些简要说明,它应该在系统框架开发完成后输出,以便指导项目的后续开发。这份文档可能只要很少的几页就够了。

第三份文档是通讯协议格式和文件格式等,这些内容是结构性的,而不是逻辑性的,所以文档能更清晰的把它们描述出来。数据库格式也可以写,但考虑到可以在大多数 DBMS 中直接看到数据库结构,它的必要性并不大。这些文档可以在相关部分开发完毕后输出,也可以等整个项目开发完了再输出。

第四份文档一些描述系统关键点实现方法的论文。由于针对单个问题,所以它们的主题很明确,不大可能因为太松散而失去价值。这些论文可以等项目结束后再写。

总之,我认为设计相关的文档应该等代码完成之后再写,这样最大程度的避免了文档和代码的不一致。这些文档的篇幅也不宜过大,把一些框架性的东西说清即可,描述具体细节是代码的事。另外我觉得公司也可以考虑为项目组或个人建立内部 BLOG,并鼓励大家发表相关文章,以促进交流。

  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:SymSoloVditor思源笔记

    1062 引用 • 3456 回帖 • 124 关注
  • 软件工程
    31 引用 • 81 回帖
  • 文档
    56 引用 • 1289 回帖 • 2 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Ubuntu

    Ubuntu(友帮拓、优般图、乌班图)是一个以桌面应用为主的 Linux 操作系统,其名称来自非洲南部祖鲁语或豪萨语的“ubuntu”一词,意思是“人性”、“我的存在是因为大家的存在”,是非洲传统的一种价值观,类似华人社会的“仁爱”思想。Ubuntu 的目标在于为一般用户提供一个最新的、同时又相当稳定的主要由自由软件构建而成的操作系统。

    127 引用 • 169 回帖
  • Git

    Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

    215 引用 • 358 回帖
  • Sym

    Sym 是一款用 Java 实现的现代化社区(论坛/BBS/社交网络/博客)系统平台。

    下一代的社区系统,为未来而构建

    524 引用 • 4602 回帖 • 731 关注
  • 电影

    这是一个不能说的秘密。

    125 引用 • 610 回帖
  • MySQL

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一。

    695 引用 • 538 回帖 • 1 关注
  • 微软

    微软是一家美国跨国科技公司,也是世界 PC 软件开发的先导,由比尔·盖茨与保罗·艾伦创办于 1975 年,公司总部设立在华盛顿州的雷德蒙德(Redmond,邻近西雅图)。以研发、制造、授权和提供广泛的电脑软件服务业务为主。

    8 引用 • 44 回帖 • 2 关注
  • JRebel

    JRebel 是一款 Java 虚拟机插件,它使得 Java 程序员能在不进行重部署的情况下,即时看到代码的改变对一个应用程序带来的影响。

    26 引用 • 78 回帖 • 693 关注
  • WiFiDog

    WiFiDog 是一套开源的无线热点认证管理工具,主要功能包括:位置相关的内容递送;用户认证和授权;集中式网络监控。

    1 引用 • 7 回帖 • 633 关注
  • Sillot

    Insights(注意当前设置 master 为默认分支)

    汐洛彖夲肜矩阵(Sillot T☳Converbenk Matrix),致力于服务智慧新彖乄,具有彖乄驱动、极致优雅、开发者友好的特点。其中汐洛绞架(Sillot-Gibbet)基于自思源笔记(siyuan-note),前身是思源笔记汐洛版(更早是思源笔记汐洛分支),是智慧新录乄终端(多端融合,移动端优先)。

    主仓库地址:Hi-Windom/Sillot

    文档地址:sillot.db.sc.cn

    注意事项:

    1. ⚠️ 汐洛仍在早期开发阶段,尚不稳定
    2. ⚠️ 汐洛并非面向普通用户设计,使用前请了解风险
    3. ⚠️ 汐洛绞架基于思源笔记,开发者尽最大努力与思源笔记保持兼容,但无法实现 100% 兼容
    29 引用 • 25 回帖 • 152 关注
  • Facebook

    Facebook 是一个联系朋友的社交工具。大家可以通过它和朋友、同事、同学以及周围的人保持互动交流,分享无限上传的图片,发布链接和视频,更可以增进对朋友的了解。

    4 引用 • 15 回帖 • 443 关注
  • 开源中国

    开源中国是目前中国最大的开源技术社区。传播开源的理念,推广开源项目,为 IT 开发者提供了一个发现、使用、并交流开源技术的平台。目前开源中国社区已收录超过两万款开源软件。

    7 引用 • 86 回帖
  • BAE

    百度应用引擎(Baidu App Engine)提供了 PHP、Java、Python 的执行环境,以及云存储、消息服务、云数据库等全面的云服务。它可以让开发者实现自动地部署和管理应用,并且提供动态扩容和负载均衡的运行环境,让开发者不用考虑高成本的运维工作,只需专注于业务逻辑,大大降低了开发者学习和迁移的成本。

    19 引用 • 75 回帖 • 702 关注
  • 千千插件

    千千块(自定义块 css 和 js)
    可以用 ai 提示词来无限创作思源笔记

    32 引用 • 69 回帖
  • Bootstrap

    Bootstrap 是 Twitter 推出的一个用于前端开发的开源工具包。它由 Twitter 的设计师 Mark Otto 和 Jacob Thornton 合作开发,是一个 CSS / HTML 框架。

    18 引用 • 33 回帖 • 646 关注
  • 博客

    记录并分享人生的经历。

    274 引用 • 2393 回帖 • 1 关注
  • PHP

    PHP(Hypertext Preprocessor)是一种开源脚本语言。语法吸收了 C 语言、 Java 和 Perl 的特点,主要适用于 Web 开发领域,据说是世界上最好的编程语言。

    167 引用 • 408 回帖 • 494 关注
  • Typecho

    Typecho 是一款博客程序,它在 GPLv2 许可证下发行,基于 PHP 构建,可以运行在各种平台上,支持多种数据库(MySQL、PostgreSQL、SQLite)。

    12 引用 • 67 回帖 • 436 关注
  • 互联网

    互联网(Internet),又称网际网络,或音译因特网、英特网。互联网始于 1969 年美国的阿帕网,是网络与网络之间所串连成的庞大网络,这些网络以一组通用的协议相连,形成逻辑上的单一巨大国际网络。

    99 引用 • 367 回帖 • 1 关注
  • 又拍云

    又拍云是国内领先的 CDN 服务提供商,国家工信部认证通过的“可信云”,乌云众测平台认证的“安全云”,为移动时代的创业者提供新一代的 CDN 加速服务。

    20 引用 • 37 回帖 • 577 关注
  • 百度

    百度(Nasdaq:BIDU)是全球最大的中文搜索引擎、最大的中文网站。2000 年 1 月由李彦宏创立于北京中关村,致力于向人们提供“简单,可依赖”的信息获取方式。“百度”二字源于中国宋朝词人辛弃疾的《青玉案·元夕》词句“众里寻他千百度”,象征着百度对中文信息检索技术的执著追求。

    63 引用 • 785 回帖 • 46 关注
  • 尊园地产

    昆明尊园房地产经纪有限公司,即:Kunming Zunyuan Property Agency Company Limited(简称“尊园地产”)于 2007 年 6 月开始筹备,2007 年 8 月 18 日正式成立,注册资本 200 万元,公司性质为股份经纪有限公司,主营业务为:代租、代售、代办产权过户、办理银行按揭、担保、抵押、评估等。

    1 引用 • 22 回帖 • 838 关注
  • Tomcat

    Tomcat 最早是由 Sun Microsystems 开发的一个 Servlet 容器,在 1999 年被捐献给 ASF(Apache Software Foundation),隶属于 Jakarta 项目,现在已经独立为一个顶级项目。Tomcat 主要实现了 JavaEE 中的 Servlet、JSP 规范,同时也提供 HTTP 服务,是市场上非常流行的 Java Web 容器。

    162 引用 • 529 回帖 • 3 关注
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    950 引用 • 1460 回帖 • 2 关注
  • SQLite

    SQLite 是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是全世界使用最为广泛的数据库引擎。

    4 引用 • 7 回帖
  • 小薇

    小薇是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动。

    由于 Smart QQ 从 2019 年 1 月 1 日起停止服务,所以该项目也已经停止维护了!

    35 引用 • 468 回帖 • 768 关注
  • 脑图

    脑图又叫思维导图,是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具。

    40 引用 • 157 回帖
  • Gitea

    Gitea 是一个开源社区驱动的轻量级代码托管解决方案,后端采用 Go 编写,采用 MIT 许可证。

    5 引用 • 16 回帖 • 3 关注