《产品研发过程时间》(20)设计人员

对于一个15-20人左右的开发团队来说,设计人员在项目中,主要完成项目的总体框架设计工作和设计工作,一般的来说,由于他们会承担一些Code Review,以及一些系统级的工作(比如集成发布等等),并且承担一些核心模块的开发工作。在这个环节,我们主要把精力放在设计环节上。

首先做一个定义,我同样不清楚书上是如何说的,说设计是什么。在实际操作环节中,总体设计的产出的标志,一般是package能够确立,并且package之间的协议(如果有的话),协议确立一个0.1版本,设计的一个中间阶段的产出是(常说的概要设计,但是我现在倾向于这两者不做那么严格的分离,实际上,也很难做什么太多的分离)文件目录确立,比如对于WEB开发来说,一般采用Frame结构,以及Frame结构内的页面名称基本上已经确立,并且很清楚,在每个页面中所需要完成的工作是什么,更严格一些的要求,需要把Class也确立出来,接口函数定义等等基本产出,空Project基本上确立起来就可以了。当然这个目标是比较难以达到的,但是如果能够做到,能够为后面的工作,减少很多随意性。

OK,定义说完了,接下去,我们先讨论一个问题,如何看待设计和编码之间的结合,一般来说,15-20人的团队,其中只有一个设计人员可以不延续到编码阶段,因为在研发过程中的种种调整工作,会消耗他的很多精力,对于更小的团队来说,独立设置设计人员,强制分离设计人员和编码人员,实在是意义不大的,理由很简单,你的沟通成本太高了,在过程中,可能产生的误解也太多了(当然,这通过统一设计语境平台等等,可以减少这些误解的机会,但是没有一种方法,可以避免这一点,而且就现在来看,这种方式也是执行成本比较高昂的方式)。

请大家明了一个事实,不要被误导了,很细的分工会使得工作整体提高效率的一个前提是这个工作相互之间的交流不多,比如流水线上的工人,事实上,他们并不需要在工作中进行太多的交流(你看见工厂工人,经常会离开办公位,到另外一个工人那里,说我觉得这个地方应该这样干,而不是现在这样的吗?我从来没有看见过,嘿嘿,这是我大学的2个月的学工生涯中,看不见的和听不见的);另外一个情况是,由于我们的Project的原因,前期我们无法进入到编码阶段,于是使得我们可以在很长时间中,来充分利用这段时间,进行事无巨细的设计过程,但是,我们在编码阶段需要在短期内构造出大量的代码,在这种情况下,迫于时间压力,我们不得不采用早期疯狂的完美设计,编码阶段才可能加入大量的人员来进行编码工作。但是,以上提到两种方式,在目前我们开发的项目中,存在得并不多,我相信总不会有人说,我们的研发不需要相互之间的沟通吧?而且对于我们的项目来说,我们早一天开始或者晚一天开始整体的工作,实际上并没有严格的约束条件。所以,该早一点开始的还是早一点开始吧。我推荐的一种方式是:人员逐步投入,高级开发工程师最早进入到项目中,开始一些技术难点的预研工作,并且承担框架设计工作,建立一个良好的可扩展的框架以后,中级工程师开始介入进来,进行后面相对Detail的一些设计工作,包括类结构的设计等等,最后,在进入非常Detail设计的时候(事实上,这个阶段,我们基本上已经开始了编码,更详细的,比如如何从数据库中取出某种数据的方法等等,一般来说,是不独立去做设计的,至少我还没有这种自信,认为自己在这方面能够想的如此周全,这么Detail的工作,还是谁具体操作,谁具体来做吧,只要建立起来一个Review的制度,由中级工程师或者高级工程师把把关就是了,我们总不能把每一个函数的每一个处理逻辑都列出来的,如果真的那么自信,也许你主持开发一个自动化代码生成工具,会很挣钱的,相信不少坚信蓝领程序员是解决软件问题的公司,对此一定会花大价钱购买的,呵呵,糊弄一些自以为专家的人的空谈者,这种事情我比较喜欢),初级一些的开发工程师,在中级工程师的指导下锲入项目,进行项目的细节设计和编码工作。

写到这里,我突然感觉,软件行业实际上就象一个混沌系统,我们企图不断明晰这个系统,但是这个系统是无法无限制明晰下去的,因为外界的扰动,使得这个系统会不断陷入混沌。就象我们对待需求一样,你不可能限制需求的变更,我们所做的就是,在风险容忍的情况下,使得需求的变更尽量有序化一些而已。类似的,在软件行业中,我们只是在风险允许的情况下,设置一个混沌上限;在成本和操作性允许的情况下,设置一个混沌下限,然后在其中研发软件,仅此而已。在我看来,这至少是在目前来说,相对实际一些的想法。

好了,在下面,我会来谈谈,我希望设计人员能够具备哪些特制呢?

我一直说一点:设计一个系统,更多的是一种艺术,而不是一种科学。比如我有时候,看一个系统设计,在第一眼,就感觉这个系统设计得让人很难受,但是,具体如何难受,暂时还说不出来,但是随着对系统的更进一步的研究,发现问题原来如此如此。你一定要我说,为什么你第一眼就感觉难受,我真的说不出,我只能说这是一种直觉,仅此而已。我相信,很多做设计的同仁们,一定也有和我一样的感觉,因为我们经常在层次以及复杂度,过度设计和无设计之间不断平衡,而且我们也看见了太多的设计,在后来的系统研发中,到底是如何的经验,也许正式由于此,给我们留下了一种直觉的东西。

举一个简单的例子来说,数据库设计范式,想必在学校学过数据库的同仁们都明白三大范式是什么,比如我们有时候,在後段经常需要进行数据集市,进行BI操作的系统设计的时候,会非常自然和倾向于使用星形的数据库设计,一张主表来记录基干信息,然后其他表象众星拱月一样,记录辅助的各种信息,这种设计从逻辑上来看,非常干净清楚,而且将来的扩展性也比较好一些。但是,这种设计会使得系统频繁地发生跨N个表的查询,这对於大型应用来说,要求性能比较高的系统来说,在一个数量级以后,就将是一场灾难了。另外的,比如我们使用冗余数据来作系统,虽然使得查询效果急剧上升,但是由于冗余数据,使得数据的维护变得很复杂,可能使得系统中存在若干个逻辑中心,这些逻辑中心包含了太多的逻辑,以至于似乎任何更改都必须记住他们。这是一种很难受的设计,而且系统也显得不干不净的。但是,你说不上什么一定对,或者什么一定错。在这个方面进行权衡的一般准则,我是如此来做的,对于一般系统来说,我倾向于采用非冗余的干净数据库,但是当数据量上升到G以上的级别的时候,我会小心一些,当数据急剧上升到更多,比如主表数据在3000万以上,辅助表的数据也同样在1000-3000万之间,那么我会考虑采用发布的技术,在某一个节点进行数据发布,采用冗余数据的方式来做。但是对于绝大多数系统来说,这是不必要的。采用冗余数据,纯粹给自己找麻烦。你可以通过数据库Housekeeping的工作或者历史数据和业务数据进行业务上或者逻辑上的拆分来做这件事情。

这就是我所说的,平衡感,这对於一个良好的设计人员来说,是非常重要的。

第二,设计人员需要具备一个开阔的技术视野,这样对你的设计来说,将变得更有益处。比如系统级别的HA解决方案,比如各种常用的中间件技术或者某一些解决方案,还是需要知道的。不然,你将不得不自己去做很多问题的解决,从前大家犯过的错误将再次重犯一次。比如SSO(单点登录技术),在很多公司都有成熟的解决方案,相对的来说,对系统资源消耗较少,而且对应用程序修改较少,但是我至少2次听说过有人用自己的解决方案来处理SSO问题,结果可想而知。做为一个软件设计人员,你必须明白,我们的工作不是从头开始自己做一个系统,而是在一个平台上来构造一个系统就可以了。所以,如果有MVC框架,为什么不使用呢?

我记得在一次BEA的内部培训中(那是2004年1月份),那是一个昏昏沉沉的下午,我偷偷睡了一个小时,醒来的时候,发现讲师还在无聊地讲着BEA Weblogic platform中的Portal技术,一通猛吹,让我感觉比较不爽,本来就是一个内部讲解,没有必要讲得云里雾里的,于是问了讲师一个问题:“你觉得BEA Weblogic platform到底为我们带来了什么?你是否意味着现在Platform中所附带的一些开发工具等,能够应付我们将来的开发?”。讲师很诡异地笑了笑,沉思了5秒钟,说:“Platform给你带来的最大的价值在于,他建立了一个良好的框架,在这个框架中构建你的应用,将使得你的应用在系统结构层面上比较好,而且扩展性比较好,仅此而已”。这一点让我记忆到现在,当然我不清楚Protal现在是否比去年要好了很多,但是这个观点,使我受益不浅。

第三,明确的价值观。知道什么是一个好的设计,什么不是。有时候,看上去能够上课程书的设计,并不一定是个好设计。这个理由很简单,课程书上的设计最重要考虑的是设计的优美性,但是在实际项目中,我们面对的是客户的需求,在能够满足客户需求,并且略考虑一些将来的扩展性的考虑,就足够了,你没有太大的必要来做非常复杂的设计。

设计人员和开发人员分离,导致的另外一个后果就是,设计人员企图做一个框架上完美的设计,但是这种设计实际上意义并不是很大。我举一个现实的例子,在我们做权限,角色,人员对应关系的设计时候(当然,有时候我们也会加入组织结构这个因子),我们往往会考虑很多的东西,比如为了SSO,使得我们必须把一个服务做成需要接口验证,密码通过MD5加密,来使得访问能够安全一些,为了使得灵活性更高,我们往往会内置一些逻辑,生成一些根据组织结构的缺省的角色,为了使得各种数据结构可以在后期方便更新,我们需要采用Profile技术来运行期定义数据结构等等,我曾经给一个朋友做过这样的设计(这是在2003年左右),仅仅是概念级考虑的框架设计文档,已经达到8页Word文档,考虑得非常周到,当时我对于这个设计,感觉还是比较不错的,但是现在看起来,有点让我脸红了,这个设计如果真的需要实现出来,基本上需要5-6个工程师的Team,工作3-4个月的时间(这还是比较保守的估算),那么在一般项目中,用这种设计方式进行设计,几乎是必定不实用的。所以,不要说什么设计一定是好的设计,什么设计一定是不好的设计,判断的唯一标准就是是否满足了客户的需求?并且在将来的时候尽可能方便得进行修改(当然,上面两点是冲突的,在出现严重冲突的时候,我建议你以第一个准则为主,因为将来方便进行修改是主观的,也许你今天考虑的很多东西,根本不可能出现,你为此白白做了太多的事情,不值得),开发成本是否能够接受?

第四、要明确,一个好的设计,来源于对业务系统的良好理解,设计不是脱离业务存在的,比如你做一个BI系统和做一个业务系统,在包括数据库设计、框架设计方面,几乎是不相同的。而且,我们在具体的工作过程中,也能经常得发现,一个没有很多开发背景,但是思路清晰的业务人员,在进行框架设计的时候,也能提出很多好的想法,甚至组织这种设计工作。原因很简单,他很清晰客户的需求,并且能够自觉地把客户的概念融入到设计中,由于此设计和客户的概念是相互融合的,所以在将来发生实际的变更的时候,他的修改也相对更容易进行。我举一个例子来说明这个问题,比如我们在设计工作流的时候,大家都知道WFMC模型,我们按照WFMC模型进行各种节点的定义,流向的定义,在后面半年的开发中,我总是发现,根据这套模型走,加入一个新的功能,没有对我们原先的设计产生非常严重的冲击,这一点让我很佩服,这是源自于对业务的良好理解和切分。缺少对业务系统的良好理解,就企图能够做好High Level Design的工作,这一点实在有点过于自以为是了。

第五、不要轻易地决定去做一些系统级的东西,因为这些东西往往在严厉的环境中很容易出错。比如除非万不得已,我绝对不企图自己去撰写DB的ConnectionPool这种东西,首先看起来他很容易。OK,建立一个缓冲区,在启动的时候,建立和数据库之间的连接,然后在应用程序访问的时候,分配一个Connection出去,然后在程序访问完毕以后,把这个Connection回收,以备于将来访问。但是,这种东西,真的在实际应用中,出现的问题极其恶心,比如我们发现Connection Pool里面不知道为什么,为出现几个错误的连接,其他的连接都是好的,就是某几个连接出现问题了,于是应用程序开始呈现一定概率地发生访问数据库问题,一直到现在,我也不明白为什么会发生这样的情况;当然为了解决这个问题,最简单的一种处理是周期性地进行Connection的扫描,来发现其中是否有Connection失效,如果发现失效,那么就重新建立一次连接等等;但是你想想,这种程序将会显得多么庞大啊。于是除非我走投无路了,我一般不进行类似工作。至于有一些无知而可笑的设计人员认为,这些系统级的工作很容易做,Connection Pool可以自己来干,甚至撰写一个Java容器也很容易,甚至我们可以通过20-30行代码的方式提供一种HA方案,但是在实际使用的过程中,我从来没有感觉这种HA方案能够为客户提供什么价值,他充其量是一种学术上可行的方案,但是问题是,我们不知道在什么情况下他会出现问题,而这种软件就是要在错误中进行系统的维持工作的,如果缺乏系统级别的理解,我们很难进行这些工作。所以,不要轻易去做系统级的东西,因为我们没有能力做好。这不是你的能力的问题,我们绝大多数设计人员和开发人员的优势在理解客户的需求,然后快速实现客户的需求,我们没有太多机会进行这种系统级工作,因为绝大多数这部分工作,我们可以找到相关的产品使用。

设计人员需要培养一种设计美感,有的设计让你看起来,越来越觉得清晰和流畅,你几乎不用翻过来,看前面的设计,这是因为他的设计元素安排和一个业务系统丝丝入扣;有的设计,简直就是一堆概念的综合体,仿佛仅仅为了设计而进行的设计,概念被杂乱地堆放在各个角落,看起来让人觉得头疼。

以上,是我对设计的一些基本的观点,当然,具体的做法还有很多,这里就不展开了。

最后,我想说一下,如果做为一个开发人员,那么你如何提升你自己的设计能力呢?我想这个话题是我以前的一些同仁们,很多次问起的一个话题,也是很多初进入软件行业的开发人员所好奇的东西。我也能够理解,因为当年我也是如此一步一步走过来,也面临同样的困惑。一般来说,我是如此增强自己的设计感受的:

首先,我会挑选一个项目,我自己认为做得不错或者做得不好的项目,然后使用半天时间,试图在一张PPT上,用各种图形把这个系统关系搭建出来,并且画上数据流向图,以及相互引用关系图等等,而且层面应该比较高,因为在一张PPT中,你实在没有精力去做出太多的东西。这是强制让你放弃某些更细节的设计,把注意力放在和你的产品(或者模块)的最上层的设计本身,然后,你可以修改这张PPT,我的概念是,一般来说,这张PPT需要进行5-6次修改,才能让你自己满意,他的各个箭头都是正确的,他的各个模块的层次结构(是平行的,还是从属的?是相互依赖的吗?你需要挑选一种方式,把这些关系表达出来)。如果你第一次着手进行这方面工作,我建议你参考一下别的产品的PPT,比如你可以看看BEA Weblogic Platform的一个简单的图,看看他是如何把各个产品放在合适的位置上位置的。就这张图,我和我太太曾经讨论了一个上午,因为我太太认为BEA的一个产品在产品线图上放错了位置,因为感觉逻辑上怪怪的。结果我们讨论了一个上午,发现这个位置没有放错,而且放得很巧妙。通过这些工作,主要培养的是2个能力:清晰的逻辑判断能力和整体思维能力;通过这种方式的锻炼,你对于各个不同模块之间的关系,以及层次的合理性等等方面会比较敏感一些。

其次,如果可能的话,找N个朋友(N<5),其中至少有一个设计方面比较有经验者,然后你们挑选一个小,而且大家能够很容易理解的方向(比如说一个简单的用户进入超市,购买商品,然后付款的流程),提出一个简单的,最Base的需求,大家分头去准备设计文档(不一定要用Rose等等,挑选任何你能够完全表达你意思的工具,我觉得白纸就不错,在跟随思路方面,至少我还没有发现更好的工具是什么),经过1周的时间,设计准备完毕了。你们找一个周末,准备至少半天的时间,每个人告诉别人,自己的设计是什么,为什么这样设计,实现这种设计,如果你来完成的话,需要多少时间?然后,大家把自己的设计图给挂起来。下面就是现场的变化了,牵头者不断提出:客户需要如此变化,客户需要那样变化,你的设计该如何来尽可能容纳这些变化,在容纳这些变化的时候,你的开发时间将如何变化?最后总是有人的设计崩盘了,没有关系,这表示我们的设计在某个点上是不能够容纳这样层面的变化的,看看其他人如何做?最后,我们挑选出一个设计,他能够最大限度容纳变化,而且研发的成本也相对比较低,把所有后面加上去的那些设计变化去掉,在原型本身,让这个人说说,他是如何考虑的?也许仅仅是运气好,也许是考虑比较深远,最后大家做一个总结,散会,找个地方去放松放松脑子好了。一般来说,这半天的工作,是比较累的,而且收获是比较大的。唯一需要注意的是:不要把设计水平相差太大的人合并为一个组,这会使得有一部分时间,一部分人觉得难以明白,有点类似空谈;另外一些人觉得多少有点嘲笑他智力的感觉。同时,请牵头的人员,在准备案例的时候,请尽量用一个现实的例子,不要使用虚幻中的例子,过多虚幻的例子,会使得大家的设计偏向于过度设计,这不是我们希望看见的,而且请至少用半天时间精心准备整个案例,不然可能大家都是在浪费时间。这种方法是比较有效的,而且还顺带着进行了一些Team Building的工作,而且,如果是一个团队进行的话,也会使得设计经验最大限度进行交流;最后一点,由于设计的不确定性和主观性,将使得一个即使经验比较缺少的团队成员,也能有一种感觉,自己在某一方面是强项,从而使得在将来实际设计中,敢于和愿意去说话,这不是很好吗?这种做法,我觉得还是值得推荐的,在1-2个月内做一次,效果还是比较明显的,能够看见设计团队的能力在得到提升,并且大家能够相对比较容易建立一个共同的语境平台,并且熟悉相互之间的设计思路和理念。

再次,通过开源代码或者一些类似平台发布程序(比如MS的商务平台程序,他会为一个Project生成很多框架性代码,然后你可以根据这些框架性代码进行修改,以实现你自己的逻辑,但是框架是已经建立起来了)的阅读,来领会一些其他人的设计,这一点也是相对比较有效的。比如我相信很多人阅读过SUN平台上Petstore的程序吧。这个程序的阅读,以及分析,还是能够给人带来很多关于MVC方面的收益的。当然,这需要比较长的时间,在阅读的时候,记得旁边摆一张白纸,把你阅读过程中的感触,写一个小小的提纲,因为也许仅仅15分钟以后,你会忘记某一点收获。

最后,记得给自己一个时间,总结你的自己的设计理念和体系。我们在工作中,最容易积累的是点点滴滴的知识和实践的工作,但是,如果你的知识永远是点点滴滴的,那么你将难以形成一个基本的设计理念和基本的设计价值观,为了这一点,我们有必要在每个项目结束的时候,或者定期(我习惯是每个季度进行一次)总结,我的做法是把整个体系树立起来,比如从数据库设计,框架设计,Detail的设计,性能,稳定性,跨平台性,安全性等等建立起来一个基本的框架,然后把点点滴滴的知识放入到这个框架中,来整理自己的整体思路。经过几次总结,你会发现你对于设计的整体性方面会更强了。这一点我深有感触。

有一次在和一个咨询界的朋友聊天的时候,他说起实践工作者和咨询者的不同,实践工作者拥有大量的实际工作经验,但是不善于进行总结,所以,老是感觉没有一个整体的思路,似乎什么都是零零散散的;咨询者善于总结,但是实际工作经验偏少,其中可能可能充满着想当然和以猜测的源头而来的结论;我想,如果能够把两者结合起来,至少让我们实践工作者,也能有部分时间来从咨询的角度出发考虑问题,也许对于个人来说,会比较有利一些吧。

设计人员要记得一点,在中国绝大多数项目,甚至国外的一些超大型项目中,一个优秀的项目经理能够为项目成功带来15%左右的提升率,而一个好的架构设计人员,将为项目带来30%多的成功提升率。所以,在项目中说出你的观点,为项目建立一个良好的稳定的设计,是项目经理最为关注的。顺便说一句,我们现在之所以觉得在项目中,项目经理更重要,是因为我们的项目大多数来源于技术人员,所以我们对于管理、协调更为关注,但是实际上,不要忘记一点,如果你的团队没有良好的设计者,所有的管理、协调将无从立足。管理是重要的,但是远远不是唯一重要的因素。嘿嘿,我记得2003年在CSDN上,我写过一些东西,有一个很奇怪的现象,就是我经常在CSDN的项目管理论坛中,看见大量技术出身的人,认为自己的管理和协调能力比技术能力出色,而在职业经理人的论坛上,我却又看见不少经理人认为自己在技术(或者专业)全局的把控上,能力出众。这一点不是很奇怪吗?原因何在,大家应该很明白吧,不多说了。

OK,良好的基石由你们来建立。我看过了太多的无设计,随便干了干数据库设计,就开始全面的编码了,结果后期发现项目的结构恶心坏了,后面的程序员不断抱怨前面的设计者的愚蠢,但是同样的事情在不断上演。我也同样看见过太多的例子,设计者扬扬自得得设计出一个超复杂系统(嘿嘿,这一点我也看到很多哦),兄弟们累死累活,但是项目就是老是不稳定,老是觉得有不少问题在其中,一个系统过于复杂,必然问题多,不要把这些问题都放在开发者身上,设计者同样要对这个结果负责。


文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags:
评论: 0 | 引用: 0 | 查看次数: 3869
发表评论
你没有权限发表评论!