IT项目,特别是软件开发项目,都属于“挨踢”项目的范畴。挨踢项目的几大特点:
1.需求不确定。
2.技术不确定。
3.工期限死。
4.预算限死
两大不确定和两大限死,你想不“挨踢”都难!
什么是“漂亮”的设计?
一些关于软件设计的资料提到,咱们的设计需要高效、可靠、易用、安全、可扩展、兼容性强、移植性强……
每次看到这样的文字,我的第一反应就是头晕,这些基本就是废话嘛!
软件设计是为软件服务的,要服从项目的商业目标。一味追求所谓的优雅设计,项目可能会死的很惨。客户购买的是软件而不是你的设计。如果你在客户面前介绍你的设计如何精妙、如何OO、如何依赖注入?那客户只能当你是火星人看了,客户并不会因为你的设计如何精妙而原谅你的推迟交付和增加费用。如果为了节省时间,忽略设计或者粗略设计,项目同样很可能会死得很惨!没有想清楚就动手,就相当于冒着大雾往前走,可能走错方向,可能跌入悬崖……
我认为“漂亮”设计应该是这样的:
1.能命中需求。
2.符合项目的战略。
(什么是战略?请参考《挨踢项目求生法则-战略篇》:http://blog.csdn.net/u010825142/article/details/9026279)
3.做适度的设计。
当然以上内容可能仍然不够清楚,请继续阅读下文。
为什么需要设计?
以前公司过ISO的时候,其中一个我觉得比较厌烦的问题是:软件的实际设计已经和设计文档不符了,ISO内审员要求我去更新设计文档。为了避免这些麻烦,我试图将设计文档写得比较粗和通用,这样就大大降低了需要更新文档的机会。如果将设计进一步抽象化,我完全可以写出一个N层架构的设计出来,这样的设计可以复用到n多项目上,每个项目的设计文档复制这个设计就可以了。但问题是:我们的软件设计就是为了得到一个不用怎样修改的文档吗?况且这样粗的设计对项目实际工作有什么实用价值呢?
在某项目管理培训中我展示了某项目的某模块的详细设计文档,但有学员提出了质疑,从他的经历看来,无法让程序员写出类似这样的文档。写不出文档,是因为没有能想清楚?还是因为不会中文呢?软件设计并不是写文档,而是通过探索和思考,想出解决问题的方案,文档写不出了没有关系,关键是你有没有解决方案?哪怕这个方案存在与你的脑袋当中,你能不能清晰的表达出来?表达的方式不一定是文档,可以是口头表达,可以是通过Demo来展示等等。
现在可以来回答“为什么需要设计?”这个问题了,我的观点如下:
1.需求解决做什么的问题,而设计是解决怎样做的问题。
2.如何更简单、更少工作量地解决怎样做的问题,是设计工作的重点。
3.需求工作决定了软件的价值,而设计决定了软件的成本。
4.写设计文档并不等同于软件设计,软件设计在于探索、思考、实践,摸索出有效的解决方案、具体做法等。
5.Word文档仅是软件设计的其中一种表现形式而已。
6.设计不是一次成型就不变的,而是需要持续优化和改进。
我们需要做什么设计?
设计包括概要设计和详细设计,这是我们惯常的认识,但我将设计分为以下几方面的内容:架构设计、模块设计、数据库设计、用户体验设计。
架构设计可以近似看作是概要设计,架构设计是通盘考虑了所有软件需求后的一个宏观设计,我通常会用UML的部署图、组件图和包图进行架构设计,设计的粒度会达到组件及模块级别。
模块设计是指在架构设计的基础上,在软件系统划分成n个模块,每个模块进行详细设计。我通常会用UML的类图、顺序图来进行模块设计,设计的粒度会达到类、类的方法和属性、类之间的调用关系等。
数据库设计这个不用多解释,粒度要达到最终实现的程度,而用户体验设计可能需要多加解释了。
用户体验是指用户使用软件时的整体感觉,用户体验设计需要考虑清楚软件的整体界面规划、界面先后关系、文字表达、软件与用户如何交互等等。说到用户体验设计,很多人直接反应就是美工的事情,这是不对的,美工仅是用户体验设计的一小部分内容而已。一个软件如果内部实现很烂,但用户体验设计做得很好,那么这个软件仍然会很受欢迎。相反,一个软件的用户体验设计很烂,哪怕软件的内部设计很精妙,客户也不会卖账。从这个角度上看,用户体验设计是相当重要的,但用户体验设计往往是被忽略的。很多软件公司没有专门的用户体验设计职位,往往由程序员自己设计软件与用户的交互,做出来的软件非常不人性化。
我在以前的公司做项目,一个项目一般会有1份架构设计文档,1份或者多份模块设计文档,1份数据库设计文档和1份用户体验设计文档。我想说明的是,以上提到的四种设计并不是非要对号入座,每种设计对应一份或多份文档,而是软件设计应该包含这四方面的内容,至于文档的数量和形式没有规定,你可以一个文档包含四个方面的内容。另外还要说明的是,并不是软件所有的模块都需要写详细的设计文档的,如果该模块的实现方法已经很成熟,成为项目组的“常识”,这些内容没有必要额外再写文档。
法则1:需求驱动设计
以前曾经参加某项目的某设计文档的评审,大家围着一个局部的技术问题进行讨论,但争论的内容仅仅是一些软件设计上的大道理,每个人对这些大道理诠释不同而已。于是我问:大家知道这个项目的需求吗?能不能列出设计中需要重点考虑的需求是哪些?居然没有人能答出来!
我去评审设计文档很简单,就是事先将需求搞清楚,列出设计中需要重点考虑的需求,然后看看设计文档是如何考虑这些需求的实现。设计就是用来满足需求的,用需求来检验设计文档,这是很基本的“常识”,但这个常识往往被我们忽略。编写设计文档的为“节省”时间,不去全面深入理解需求就去写设计文档,参加设计评审的为“节省”时间也不去了解需求,这样设计和设计评审就变成了走形式、浪费时间的事情。
前面提到设计决定了软件的工作量,在设计时间上“节省”时间,你的代价就是将会花数倍甚至数十倍以上的项目工作量。认真地需求驱动地做好设计工作,这是必须的。下面简单介绍一下什么需求驱动什么设计:
1.架构设计是通盘考虑全部需求后设计出来的,所以可以说:全部需求驱动架构设计。
2.模块设计是在架构设计的基础上,针对局部需求的具体实现设计出来的,也就是说:局部需求驱动某模块设计。
3.数据库设计是整理了全部需求当中的业务数据,思考这些业务数据如何在数据库中存取后设计出来的,也就是说:业务数据驱动数据库设计。
4.用户体验设计需要考虑业务流程、业务数据等,为满足客户的业务目标,我们设计出来的系统与用户之间的交互细节等,也就是说:业务流程、业务数据、业务目标等驱动用户体验设计。
“需求驱动设计”这句话还不够具体,还要进一步细化,什么需求驱动什么设计!上述几点是我以往工作的简单总结。
关于需求,请参考《挨踢项目求生法则-需求篇》:
http://blog.csdn.net/u010825142/article/details/9042125
法则2:不要误解“简单设计”
极限编程中提到“简单设计”,有些朋友很兴奋,终于可以用“简单设计”作为不写设计文档的理由了!
什么是“简单设计”呢?以下情况是不是简单设计呢?
1.简单想一下,然后快速做一个设计。
2.没有设计文档的设计,就是简单设计。
3.不设计就是最简单的设计。
4.编码就是设计。
极限编程对“简单设计”的诠释可以总结为两点:
1.不要考虑太长远,仅考虑当前的需求。
2.用最简单的办法来实现。
我基本认同这个观点,但问题一些朋友的理解可能出现了偏差。第2点“用最简单的办法”这是很难做到的,将事情简单化这是难度很高、很考验智慧的事情。“简单想一下”是很难想出“最简单的办法”的,随便想一下想出来的办法,往往是工作量巨大的办法!简单设计的意思是指要让项目工作变得简单,而不是将设计的思考过程简单化。软件设计是一种智力投资,多花一小时想清楚如何让项目工作变得更加简单,会节省你更多的项目时间。
法则3:做高性价比的设计
在符合项目战略的情况下,用尽量少的工作量来实现需求,这基本上就是“高性价比”的意思。
实际上我们不太可能做出一个“最好”的或者说“完美无缺”的设计,因为有以下的条件限制:
1.有限的项目工期。
2.有限的项目预算。
3.项目成员的能力条件限制。
软件设计是高难度的技术活,需要你做出适当的取舍和平衡,做出一个合适的设计。
但高性价比的设计意味着:
1.公司项目的利润更加大,公司赚钱更多了,咱们能分到的钱也就更多了。
2.项目工作更加简单,项目组不需要加班或少加班就能完成工作。
3.高性价比设计是挑战智力的工作,会让你的工作更加有愉悦感和成就感。
所以为了公司好、你好、大家好,向“高性价比设计”的目标进发吧!
法则4:人人都是软件设计师
有这样一种观点:由软件设计师设计出详细的设计,程序员按“图纸施工”便可。
我不喜欢将软件研发工作变成流水线的工作,将研发过程分割为需求、设计、编码、测试等几个环节,每个环节有专职的人员,他们做好本职工作就可以了。这样的工作模式有以下几个问题:
1.人变成了机器,没有创造力可言。
2.每个人对工作职责负责,而不是对项目成功负责。
3.这样的模式不可能产生创意,也意味着不可能完成复杂的、需要创造力的项目。
我认为项目组中每个人都可以是软件设计师,不要剥夺程序员思考的机会,不要将他们变成按图纸施工的机械人。
在我的项目中,我是这样做的:
1.架构设计和数据库设计由富有经验的程序员负责,其他项目成员参与学习和评审该设计。
2.模块设计由将来负责该模块编码的程序员负责,架构设计师来评审该设计。
3.用户体验设计由测试工程师或实施工程师负责,程序员参与。
法则5:设计文档应该先己后人
一些QA通常用这样的理由来说服项目组编写设计文档:
1.为了让将来接手项目的同事搞清楚状况,设计文档是必须的。
2.将来你自己也很可能需要改程序的,现在写下文档对你将来的工作有用。
以上的做法,就好象你对一个正在挨饥荒的人说:现在多存点粮食吧,对你将来有用。听你劝说的人肯定气死了,恨不得吃掉你充饥!
所以以上的理由是不能驱动项目组写设计文档的,设计文档应该达到这样的效果:对项目当前的工作有用,能帮助我立刻解决问题!如果设计文档不能达到这样的效果,就不能驱动项目组写好设计文档。
设计文档必须先保证对自己、对项目组本身的当前工作有用,在这前提下有条件才去考虑对自己的将来有用、对别人有用。也只有立足于这个出发点下,才可能写出有实际价值的文档,文档不是摆设,是要立马在工作中用上的。
法则6:设计文档不一定是Word文档
以前曾经遇到一个挺郁闷的事情:
某项目用SQL Server数据库,我直接在SQL上进行设计,也就是说数据库的设计与实现一起做了。在数据库上做设计的好处有:
1.设计马上得到验证。
2.以利用数据库的特性做很多设计上的探索,让设计做得更好。
3.设计完成了,数据库也建成了,不需要再做一次,节省很多时间。
我很喜欢这样做,但QA认为我没有数据库设计文档,不符合ISO的要求。我觉得很郁闷,数据库这个文档就是数据库设计文档,干嘛非要写一个Word文档?后来迫于要ISO审核,我用复制粘贴大法写了这个数据库设计的Word文档。如果项目使用的数据库只有一种,我觉得直接在该数据库上做设计没有什么不妥,当然如果你的项目需要支持多种数据库时,该做法可能不妥。
通过这个例子我想说明的是:设计的表现形式可以很多,不一定是Word文档,怎样的方式对当前项目工作最有效,就应该采用怎样的方式。当然有人会说,写下Word文档对将来的人有好处,但前面的法则说了,要“先己后人”而不是“先人后己”,如果我现在就饿死了,你让我现在存粮有啥意义?况且Word文档并不一定是所有软件设计的最佳表现形式。
法则7:不是所有地方都需要有设计文档
有这样一种观点:代码没有设计文档是不符合CMMI要求的。
你认为是不是所有代码都应该对应有详细设计文档呢?
数据库四轮马车的操作如果你们公司已经驾轻就熟了,你们项目组闭着眼睛都能做了,你还会写一份详细的设计文档,然后对着该文档编码吗?
并不是所有的地方都需要设计文档,仅在需要的地方才写设计文档,我的做法通常是这样的:
1.架构设计文档一般不可缺。
2.数据库设计文档一般也不可缺。
3.并不是所有模块都要写设计文档的,一般在以下情况下才写该模块的详细设计文档:
1)算法比较复杂;
2)想法不太成熟;
3)负责该模块的程序员是新人等。
4.用户体验设计文档一般也不可缺,但文档的内容一般不会覆盖软件的全部内容,成为“常识”的内容不需要写。
法则8:“编码即设计”是合适的,但烂代码除外
“编码即设计”这个观点我支持,我要进一步修正,应该是“好的编码即设计”。架构设计文档、数据库设计文档或不可缺,但详细设计文档是可以直接通过编码来代替的,但前提条件是该程序员的编程素质足够好才行。
中国计算机教育培养出来的程序员,大多数是编程基本功不过关,在校没有写过多少代码。这是一大问题,而另外一大问题是这些编程基本功很水的人士,大多不会认识到自己的问题所在,还自认为自己水平不错,编程是小菜一碟的事情。遇到不愿意写或者写不出设计文档,又自认为自己编程水平很行但实际很差的项目组成员,就需要项目管理者多花心思来引导了。
有时候遇到一些编程新手,死活写不出设计文档,我会让他直接通过编码来思考。文档可能没有办法让他理清思路,那么直接编码来理清思路吧,你可以通过他的代码来了解他的想法并给出针对性的指导,帮助他提升水平。
作者:张传波