项目设计的核心
项目设计最起码要占整个项目的一半时间以上。在软件领域,因为软件设计失误导致的代价相对较低——就是改代码——从而导致在做软件项目时,多数人对设计都不重视,更没有理清软件设计步骤及要领。软件设计处于需求分析与实现之间,当完成了需求分析,也就知道用户目前存在什么样的问题,而要解决这些问题就需要仔细考虑用户问题的核心是什么,怎么去解决核心问题,在技术上能否解决等问题,这就是设计所做的事情。当设计完成之后,对于用户的问题如何解决及技术上是否可行都了如指掌,这样,实现就是很简单的事情了。
项目设计的核心就是,协调需求(问题)与实现(解决)之间的关系,得到最佳的解决方案。特别是对于团队开发的项目,设计更为重要。良好的设计可以让实现的过程变得简单快捷,不好的设计导致实现的过程异常困难,时间不可控。
这就要注意,设计不仅仅是考虑用户的问题是否能够解决,还要考虑实现是否很高效。不仅仅要考虑实现的效率,性能等技术问题,还要考虑用户最核心的问题是否得到解决。在做项目时,大多数情况下,参与设计的人要么很注重用户的功能是否能完成,导致实现的时候,开发人员做了很多无用的工作;要么很在意技术上的效率问题,而忽略了用户在核心问题上的体验。这样做,最终的结果都对整个项目带来损害。在这在做设计之前就要注意并加以避免的。
项目设计能够带来的益处
目标
项目设计,当协调好用户与开发之间的关系之后。应形成一个《规格说明》。借用《人月神化》里面提到的,规格说明应该是:
手册、或者书面规格说明,是一个非常必要的工具,尽管光有文档是不够的。手册是产品的外部规格说明,它描述和规定了用户所见的每一个细节;同样的,它也是结构师主要的工作产物。
随着用户和实现人员反馈的增加,规格说明中难以使用和难以构建实现的地方不断被指出,规格说明也不断地被重复准备和修改。然而对实现人员而言,修改的阶段化是很重要的——在进度表上应该有带日期的版本信息。
手册不但要描述包括所有界面在内的用户可见的一切,它同时还要避免描述用户看不见的事物。后者是编程实现人员的工作范畴,而实现人员的设计和创造是不应该被限制的。体系结构设计人员必须为自己描述的任何特性准备一种实现方法,但是他不应该试图支配具体的实现过程。
规格说明的风格必须清晰、完整和准确。用户常常会单独提到某个定义,所以每条说明都必须重复所有的基本要素,所以所有文字都要相互一致。这往往使手册读起来枯燥乏味,但是精确比生动更加重要。
总结起来,《规格说明》应该是这样的一种文档:
- 描述用户所见的一切,包括用户界面
- 避免描述用户不可见的东西,这是实现的东西
- 规格说明必须清晰、完整和准确
- 规格说明会随着用户和实现人员的反馈而改变
这就是设计的目标——《规格说明》。因为描述了用户可见的一切,从而可以作为用户手册来使用,同时也使得开发人员能够完整地了解整个项目各个功能之间的相互关联。在产出《规格说明》的同时,作为设计人员要特别注意一点—— 为每一个功能特性准备一种实现方法,但不要用这样的实现方法来支配实现过程。 ——因而,在某些比较难的技术方面,可以写一个文档来描述该功能可以如何用技术来实现,以供开发人员参考。就本博的经验,一般情况下,这样的技术说明文档都可以不产生,因为开发人员都了解功能如何去实现。
在这里,可以看到,设计的目标,是对用户需求提供一种解决方案,并确保每个解决方案能够在技术上被实现。简而言之:协调用户与实现。
益处
有了设计的结果即《规格说明》,实际上就在概念上,在大脑中将用户问题解决了。这意味着:用户的所有问题都被解决,并且在实现上都没有问题。这就解决了目前大多数开发的问题:
- 在开发过程中,开发人员发现某功能改了会影响其它功能
- 在开发过程中,多个开发人员重复写相同功能的代码
- 在测试过程中,测试人员没有任何依据去测试,只凭自己的喜好
- 在跟用户沟通时,用户直到项目完成还不知道项目将会是什么样子
类似于以上的各类问题,都被《规格说明》这一文档给消除了。这一文档的问世,就宣告:所有的问题都将在本文档中得到描述,所有的目标都由本文档而产生。任何人发生分歧,都从本文档中去对照。
如果没有《规格说明》,任何人都认为自己所想的就是对的,并且在经过一翻激烈的讨论之后,时间浪费了很多,还不得不有人要去返工。或者动不动一个问题,就要把很多人召集在一起讨论。这实际上产生了大量带有敌意的沟通,最终结果是,开发人员相互之间各干各的,互不沟通,本身有公共的模块,也不会共享出来。测试人员跟开发人员就是互相较劲,测试人员根据自己的喜好可以测出很多 BUG,如果遇到开发人员强势,测试人员就只能测试出一点点 BUG 了……
尤如造一座建筑,任何人都不知道建筑是什么样子,就开始造了,造的过程中发现这里考虑欠适,那里根本就不应该建成那个样子。然后参与建筑的人一起互争互吵,建筑就此宣告失败。
因而,设计的产出——《规格说明》就是建筑的蓝图,并且是一份可以实施的建筑蓝图。它能带来的益处就是将所有的力量汇集在一处,让每个力量都能够为这个巨型建筑作为贡献。
项目设计过程
原则
项目设计的基本原则是: 站在一个中立的角度去考虑需求与实现之间的平衡。
一个做技术的人来做项目设计,会为实现人员考虑,宁可让用户体验差,也要开发人员做的事情简单。一个做客户销售的人来做项目设计,会为用户的需求考虑,宁可以让开发人员复杂,也不愿意重新考虑用户需求的合理性。这都失去了中立的角度。
集中 – 发散 – 集中
设计的过程,是由集中到发散,再由发散到集中的过程。也是由问题域到解决域的一个映射变换的过程。用一个简单的公式来表示:
y = f(x)
其中,x 就是问题域,y 就是解决问题之后最终的解决域。对于设计而言,要承担的就是将这个 f 做好。
而一个函数 f (也就是设计),总是要对给定的问题进行分解细化,然后汇总整理最后得到一个统一解决方案。这就形成了 集中-发散-集中 式的解决问题的方案。
比如,一个客户提到,在公司里面,没有办法知道员工目前在做什么,想时刻了解员工在做什么。这是用户的问题,要把这个问题详细分析下来,就会问:为什么要知道员工目前在做什么,强制性要知道员工做什么,会不会让员工感觉不爽……此时,就将问题给发散了。然后经过研究发现,公司是一个小型团队,本身就在一个办公室内,不存在相互不了解的情况,客户的目的是想将每个人做的事情记录下来,供团队其他成员了解整个项目的进度。进而可以知道要给一个事件记录系统。并且详细定义这个事件记录系统。这就是具体的 集中-发散-集中 的设计过程。
体验
作为设计关注的一方面,即用户体验,是设计的重要部分。比如,一个定餐系统,在显示菜单的时候,可以有两种方式来显示:
虽然两者都将所有的菜单显示出来,但后者要优于前者。因为用户在打开这个界面看到菜单的时候,可以通过竖直的方向将所有相同价位的菜单快速扫描完。而前者,用户需要以横向去扫描整个菜单,无法快速定位相同价位的菜所在的区域。
以上内容,是在设计时需要加强考虑的,并不是将一个功能实现,就完成了任务,而是要在设计的过程中充分考虑用户的体验。
在一个系统的设计过程中,用户界面(UI)要相互支撑,形成一个完整的方案。在设计每一个界面的时候,都要想想,用户为什么要打开这个界面,用户希望通过这个界面得到什么信息,从而来决定做什么操作。当用户想要做这样的操作的时候,是否恰好就有那么一个按钮在那里,用户可以直接了当地点那个按钮,而不是到处去找那个操作按钮。把做设计说成——设计是在精心地在做一个圈套,让落入圈套的人不断地被诱导从而实现设计者的目标——一点都不为过。
那么,要设计出来一个好的解决方案,就要做到整个系统各个模块之间相互支撑,互不矛盾,给用户一种完整没有破绽的感觉。
技术
在考虑一个好的设计方案的时候,同时还要考虑这样的设计方案代价是否非常巨大。或者进一步,这样的设计是否根本就不可能实现。
从而,在设计的过程中,设计者要对所有的功能特性都有一套实现的方案。这一套方案可以作为一种保留的方案,不在实施的时候强制采用这一套方案。保留这一套方案,是为了确保所进行的设计是可以被实现的;不强制,是确保实现者可以采用最加有效的技术手段来实现这样的设计。
对于功能特性的实现比较复杂的情况,可以考虑用另外一个技术说明文档予以说明。来给开发人员提供一定的参考。
在设计的同时,需要对某些技术进行验证。比如,要进行大数据量的操作,可能要将数据库进行拆分,则在设计的时候就要采用一定的技术手段验证对应的拆分是否合理,是否能够达到预期的效果。
在设计的同时,可以将某些基础的组件开发出来。比如说,将数据库访问层封装起来,这些组件一般都与设计相关性不大,但在实现的过程中会用到。
项目设计者
项目的设计者是一个中立的角色,这样的角色既要充分为用户考虑,解决用户的问题并增强用户体验,又要了解技术实现细节,能够对每个设计的特性提供实现的方案。