二零一四年春,我接受了一个也是很大的咨询公司的聘用,叫它Cap吧。我所工作的项目的客户在佛罗里达靠近迈阿密的一个小城市。客户是一家私营企业,它垄断了美国东南部五个州的丰田车的批发业务。项目的经济目标是在同样的车行分部的情况下能多卖10%的车,每辆车的销售业绩增长12%。其主要业务流程优化的原理是根据车行的销售业绩分配车辆配额,这样避免有的车行有车卖不掉,有的车行没有车子卖。二是在车辆配额方面给予车行更多的参与权,具体地可到年份系列、发动机、颜色等等其它的车辆属性。其宗旨就是为车行提供更为适合于其市场需求的车辆同时减少供不应求的现象。三是用追加付件选项销售从而增加每辆车的赢利。从商业角度上讲这是一个很有趣的项目。
我的一个技术以外的挑战就是缺乏对业务流的了解,在这一方面女业务分析员丹给了我很大的帮助。我开始工作时没有见到她,后来听说有个叫丹的人要来,开始以为丹(Dan)是一个男的,见面才知道是个女的而且也是中国同胞,丹是她的中文名字。经介绍后了解到丹是这个项目的元老级的业务分析员,是一位这个行业的资深人士。我刚刚参加项目那段时间她休产假在家生孩子。在极不情愿的情况下又一次出差来佛罗里达帮助项目赶进度。
虽然不情不愿丹一旦到了当地工作非常认真,有效。在知道我对业务不太了解又是同胞的份上,她专门为我开一对一讲座帮我增加业务知识。有趣的是同是中国同胞的X架构师并不热心参与。关于X丹说了这样的话“X开始并不在这个项目,他是以帮助前任架构师做文档开始的,后来他们把前任架构师请走了,X就成了架构师。他的业务知识都是我教的。” 丹还告诉我很多项目中的人事关系和重要的人和事,在后来困难的日子里提供了有力的支持和温暖的同情。为此我心存感激至今。谢谢了,丹!有朋友再困难的日子都能过!
技术上这是一个典型的微软平台的方案。ASP.Net 前台,SQL/Server 后台。都是我的专长。可是问题就像人们常说的在于“键盘和椅子之间”。与大多数咨询公司一样, Cap为了降低成本有一个在印度的离岸公司。这种离岸模式在纸面上看起来很吸引人,可是真实的情况却是另一回事。首先因为是在地球的不同区域,为了有效管理在,不同的区域的部门要有各自一套管理班子。多出来的管理班子就是多出来的费用。第二,既然有各自的管理班子那就一定有各自的财务指标。所以就算是同出一门也是各自维护自己部门的利益。与客户和商家的关系一样的,绝无合作无间的可能。
但是因为是同出一门就有了一般客商关系没有的复杂人事关系。可能你今天与印度的同事说他做的需要修改而且对方很认真地说他会去改,明天做好。然后你回家睡觉了。第二天醒来一看你的上司转发了印度同事上司的电邮。并加上一句:为了项目进度,为了他们的赢利就不改了。
再有一个是这种离岸的合作关系由于层层压支出,真正有水平的印度工程师他们也雇不起,可能有一两个有水平的,其他就滥芋充数了。毎次项目开始时从印度分公司来的人都个个了得,你充满信心地准备工作了,可是当项目真地开始了与你一起工作的人很可能不是你见过的人了。底层的工程师为了生存什么都做没有底线。再有就是沟通质量非常之差。但你讲了半个小时后问道“有问题吗?”95%的机会你会得到“没有问题”的答案。可是你不知道对方是满脸茫然,根本没听懂,更无法发问还是真的懂了。你所了解的是一个声音和一个名字。他是有十几年资历的老手还是刚刚毕业的新手,你也无法知道。
在我工作过的离岸伙伴中有中国,墨西哥,印度,菲律宾。大多数情况下离岸伙伴做的事情我们大多需要重新做过,至少需要部分重做。
除此之外还有一个典型的软件开发项目的问题。那就是关于方法论(Methodology )的决定。
早在七十年代开始,软件产业一直沿用建筑业的方法论和工作流程。用一个词来描述就是流水线(waterfall ). 各大公司都有自己的流程和名称。如微软有Microsoft solution framework. Avanade 有Avanade Method. 业界较为标准的有Rational Unified Process, (RUP)和软件标准组织的CMMI process.
这些流程的共性在于忽视了软件生产和硬件生产的不同,软件的生产可以返工而且不会有原材料的浪费。举一个例子,你若建一个房子,开始只设计了一个门,建好后想把后面窗户改成后门。你要把窗户拆下扔了,再买一个门装上。这里有原材料的浪费。你若有一个软件系统,在一个屏幕上原本有一个按键,你若想再加一个,或者改变原有按键的处理逻辑。你所需要的是修改源程序并进行有效的测试。这个过程没有原材料的费用。有的就是人工的费用。
由于软件工程的特性使得沿用建筑工程的工作流程在大多数情况下造成项目失败或超资金预算或延后工期或就算是按期完成了但是已经不适应用户的市场需求了。
这里有许多原因,我在这里举例列出一些。
由于这种需求,批准,设计,批准,开发的工作流程,一但批准了就不让改或者改就要多付钱,影响进度。所以用户会在需求,设计阶段迟迟不批准,常常造成用了三分之二的时间和预算在这些文档上,真正用于软件开发的时间和资金为由只剩下三分之一不到。
由于软件开发的工具平台相对建筑工业的工具平台非常的不稳定。几乎两年一换。每一个项目可能都有没有用过的工具或产品,所以设计文档说的很可能不能实现甚至完全不适用。所以花了三分之二的资源做的需求和设计在实际中的价值大大折扣了。在八十年代时的软件项目失败率高达百分之八十以上。
在八十年代业界开始探索不同的工作流程。总的来说就是趋向敏捷(Agile)
有代表性的有两个不同流派,一个叫极端编程(extreme programming ) 另一个叫scrum , 我都找不到合适的中文翻译。总体上它们有如下共性:
不同于传统流程注重文档,新的流程注重能够工作的软件产品。
不同于传统流程注重控制变更,新的流程欢迎变更。
不同于传统流程分块开发最后整合,新的流程一直整合中进行。
不同于传统流程强调设计一次到位,新流程强调渐近设计。
不同于传统流程不注重测试效率,新流程强调测试自动化。
不同于传统流程按模块分部开发,新流程按功能分部开发。
不同于传统流程需要在设计文档向帮助下阅读程序和修改程序,新流程注重程序可读性,(要求在不用文档不看注解的情况下读懂并能正确地修改程序)。
不同于传统流程由资深人士估计工作量,新流程由程序员自己估计工作量,极端编程让编程人员自己估计工作量。
不同于传统流程在开始时就决定最终的系统是如何的系统,新流程边做边决定系统将有什么功能。
新的流程的好处是不花太多的精力在文档上,及时调整开发内容,在任何时候项目可以停止而且已经开发的功能都将可以进入生产运行。
可是对于大多数不太真正懂行的人来说他们理解的敏捷流程就是不进行设计直接进入编程,自动测试是费时费工会增加开发费用。
渐近设计是返工行为,会增加开发费用不太现实。
敏捷流程对开发人员的技术要求很高,一般开发人员的水平不够。
其实这些都是对敏捷流程的误解。
正如Ken Beck, XP 的创始人描述极端编程时说的那样:其实我们所推崇的流程是更加符合人的自然本性,没有什么极端的地方,她之所以被命名为极端编程是因为我们把编程中的重要环节做到极致同时省略掉不重要的环节:
大家都说设计重要我们就不停地设计;(渐近式设计)
大家都说源程序检查重要我们就不停地做源程序检查(配对编程)
大家都说测试重要,我们不停地测试(测试自动化);
大家都说整合重要我们就不停地整合(不间断整合)
可是由于项目管理人员对不同工作流程的一知半解往往会选择性地理解和选择性的应用,大多数情况下弄出个两不像,其结果比两种流程中的任何一种都差。具体地说来有如下几点:
以固定时间,固定资金的项目为理由,就不实行敏捷流程中的不停调整开发内容也不允许编程人员自己估算时间。
以客户要求从项目开始时定期演示功能为理由就省略了系统架构设计。
以节约时间和费用为理由不进行自动测试和渐近式设计改进。
其结果是汇集了两种工作流程的所有缺点,就像驾着一辆打足了气但是轮胎有漏洞的车,你可以驾出一会儿但是很快就走不动了。
这个项目也不例外,上述的所有问题它都有。还有一个问题就是它的本项目组成员。这个团队以前是做整合的从未做过真正的开发工作。他们对微软技术了解甚少。没有办法与客户沟通,没有办法对离岸团队进行有效的监控。在这种情况下他们找到了我。但是原来项目的架构师继续做他的架构师。尽管对他来说数据库设计就是弄一些表,每个表里加一些栏目,然后放一些数据进去。对数据库的数据正确性,和数据库设计原则一无所知。在编程方面他只有Java的编程经验,“这个如果在Java 我们会如此这般”是他的口头禅。
在原程序版本控制方面 是完全空白。可是他既然在这个位子上总要说这个位子上的人应该说的话。所以他就每天把大家召集起来说一些空话大话废话,别人问他问题时故作姿态,然后做一些似是而非的答复。离岸部门为了自己的利益一直在胡弄他。这么一个架构师在对客户和对离岸的交往方面都显得不够真效。这其实就是他们招我的原因。在面试时不论是在岸或离岸的技术人员都无法评价我的技术水平。出乎我的预料的是这位架构师是一位男同胞。在我开始工作时期我邀他一块吃晚饭。席间我与他说道:在美国工作十多年,这是我第一次与中国工程师一块工作。希望我们亲密合作,做出一个成功的项目。在需求方面我对这行的商业运作不够了解,在人事方面也不知道谁是谁,还望你多多关照。在技术上我一定全力以赴。我俩加起来,一定能把事情搞定。在后来的日子里,为了保护他的面子我尽量不在客户或离岸团队当面指出他的错误,但私底下与他沟通。
第一天参加技术人员会议时就发现项目的数据库设计管理特差,同一个数据库居然有十几个版本,谁也不知道,它们之间有什么不同,哪个是对的。整个一团糟。会上我没有说话,连问题都没有问几个。会后我私下与他沟通问他对这个问题的态度。他说他不会SQLServer也不知道有什么更好的办法,问我有什么办法。我说我以前也有过类似问题后来我找到一个方法,用起来还不错,如果不介意我可以试试。根据他的要求我写了个PPT,给他看,他看了后让我给离岸技术人员作一个讲座然后实行。
讲座时离岸的首席工程师因故未到(天知道他除了这个项目还在几个别的项目上挂名了)其他人不知道有几个真正地听懂了,X懂了多少也是一个大问号。会后我开始与离岸数据库工程师实施我的方案。可是一旦实施了,离岸首席工程师强烈反对,我努力与他沟通也找不到他,只是电邮来来去去,这时的X反倒装做好人,总是以高高在上的姿态提出一个一个的折中方案来。可是就像驾车一样,交通规则一定要大家都遵守才有效率,如果有人这样做有人那样做,就会乱套了。没有中间方案可行的。从管理角度上看这也是X唯一能采取的立场,可是他的位置是架构师,缺乏基本的技术知识盲目地走中间线路就沒有什实际意义了。
解决了数据库的开发应用问题我继续前进向系统的纵深进军。没费多少事就发现了一个更为严重的问题。根据安全需求系统应该设计成面句服务的三层结构,前端网站与服务层交互,服务层与后台的数据库交互。前端网站不与后台数据库直接交互。这主要是因为一般面向大众的网站大多设置在安全区,不能直接访问网络核心的数据库。可是我所看到的系统是直接由前端网站访问后台数据库。这是一个重大错误,如果没有发现并改正将会造成项目失败。我提出后,离岸架构师一再抵赖,最后在事实面前不得不承认;X架构师的反应是这个设计是客户架构师推荐并批准的,有问题应由客户负责。客户架构师说我们花大价钱用你们的专业人员,设计把关应由你们负责。最后的安排是由我给出改进的架构设计然后与一位印度来的离岸部门的工程师利用周末对系统重组。这个问题至少造成一到两个星期的日程推迟。但总的来说救了项目避免了失败。经过这两件事,客户的高层对我另眼相看,对X架构师就不那么重视了。
客户中的数据库专家公开表示他不愿意与别人浪费时间只愿意与我一道做有意义的工作。就这样我拯救了项目,在客户上到副总下到数据库设计和系统架构师中建立了良好声誉。可是我得罪了X架构师和离岸架构师。由于我坚持软件质量也让项目经理不快。特别是X架构师,慢慢地对我的态度从友好变成傲慢,没有礼貌了。到了后来达到了语言暴力的程度。我忍无可忍向公司的人事部门投诉。有朋友告诉我项目经理与X架构师是二十年的朋友我告不赢的。果然我确实是告不赢他。调查结果是没有发现我所投诉的语言暴力证据,要求我继续配合工作。为了维护自己做为一个人的尊严我提出退出项目。与上层交涉的结果是我继续做两个星期并向接手的架构师E做好交接,条件是X不再对我无礼。客户方面知道我即将离开从上到下纷纷表示惋惜,开发副总和应用副总分别找我谈话希望我能留下做完项目并表示他们愿意越过 Cap 直接雇用我。
我对他表示了深切的谢意,不过我知道 Cap一定会动用法律手段阻止我在客户那里任职的,再说出差还行,我可没打算长期在佛罗里达工作呀。为了维护我的专业形象我认真地与接手的E架构师解释了现行的架构设计和编程质量问题和工作流程问题。其实我所指出的问题都是用Visual Studio 生成的程序分析报告能看到的,任何一个合格的.Net 架构师都能看到的,客户方面有这样的技术能力的。谁曾想就是因为我的尽职让我后来失去了在Cap 的职务。容我下集再叙。
经过两周的艰苦努力我完成了交接。我觉得我维护了自己的尊严也维护了自己的职业声誉。虽然困难但我心存宽慰。在与E一道去机场的路上E使劲地向我保证会把项目做好不枉费我的心血。并极力推荐我参加新的项目。在机场的餐馆里我们一道用晚餐。在看到我的微软认证证书后,E说了这样的话“你的证书加上我的证书,多过Cap .Net 部门的所有其他人的证书的总和。你是名符其实的.Net 软件开发专家!”
就这样我结束了三个多月的飞人生活。重回地面。请看下集许若之地
文字编辑:Ellen
specifically there is a intranet site for internal user to conduct its operation. it is even more important to encapsulate the business logic in app server. and let the app server provide services to both internet and intranet sites. thank you, very much for your reading and commenting, it is like a professional meets another. very pleasured to have you as a friend.
我说做个试验,打web.config 的connection string 拿掉运行给我看。他这才认了
致于X那就是一窍不通了。他都不知道我们讲的是什么。