《大话重构》中提到“大布局你伤不起”,如果企图重构一个陈旧的大型系统是有非常大的风险,重构不是想象中那么简单。我目前所在公司正好对产品做了一次“大布局重构”,下面我就分享这个“大布局”项目经验给大家。
- 背景
公司专注于企业级管理产品软件,企业有大中小之分,在2000年初公司用JSP/Servlet开发了一套针对中小企业的A产品,2007年左右又基于spring、Hibernate开发了一套针对中大型企业的B产品。两套产品面向的客户群不一样、采用的技术和数据结构不一样,但是核心功能都一样,经过多年的沉淀调整,AB产品都非常稳定,客户肯定度非常高。但是两个产品线的开发团队没有技术上的沟通交流,各自闭门造车,一个新的功能都必须在A、B产品上用两种实现方式完成。
种种问题给团队维护、项目管理、功能扩展带来了很大成本负担,最后公司决定做一套全新的系统(命名为C),这套系统能支撑低中高不同用户的需求量,同时扩展性更好,AB团队都参与进来,如果做成功非常有意义。
- 过程
公司计划通过3个月的封闭对产品需求设计进行全方位的梳理,结果只完成了50%,原因众多:不是每个产品经理都是产品经理(你懂的)、旧产品文档缺失、高层对产品战略思路还不清晰。需求在开发期一变再变,我记得最严重的是离开发期结束还有1个月的时候还有一个大的任务需求发出。
开发期好像是5个月,采用scrum敏捷开发,一个月一个sprint,我们组有坚持每天站会,通过这种开发模式确实提高了团队作战能力。因为产品功能模块多,高层以模块为基准,将研发团队分为多个小组,每个小组专注维护开发一个功能模块。我们产品、开发和测试的进度模式是这样的:开发和测试必须按照需求文档要求来做事,产品经理在sprint启动前就完成本次sprint的所有任务需求。在本次sprint过程中产品经理专注开发结果验收、下个sprint的需求设计;开发人员专注本迭代的功能开发,开发完成任务后要对照测试用例自测最后给产品经理验收,再交给测试;测试人员初期专注本迭代任务的测试用例,中期和后期对功能进行黑盒测试。
系统测试期也很长,测试同学必须做多数据库测试、联调、压力测试,期间检测出很多多数据库问题、访问安全问题和性能问题。开发还有一项重要任务是---编写B产品升级到C系统的升级程序,这是一个庞大而艰巨的工作,因为C系统很多表采用了新的数据结构,我们得一点一点将数据从B挖掘到C上。
经过一年多终于完成了C系统的基本功能,要说这套系统的稳定性,我只能说“我不会花钱买的”。不是贬低产品,这是很多大项目迁移的大问题:BUG多、功能迁移丢失严重。举一个例子,我们在处理一个使用C系统客户的BUG的时候,客户说它已经给C系统打了几十个补丁包了,目前已经麻木...
为了让产品更加稳定,我们推出了SP版本,但我个人觉得SP版本还是对功能的扩充,产品经理的idea很多,根本不关心我们的功能稳定。然后又经过一年时间,我们将.0版本升级到.5版本,也是在不断做新功能和不断修复BUG。
- 结果
我们有一个强大的基础平台,这个平台支撑所有模块功能,公共组件都在这个平台实现,终于解决了不同模块不同代码风格的问题。
所有功能模块均以插件的形式开发,除了主功能,增值功能都可以由用户决定是否购买,这种设计上的解耦方式给用户更大的选择。比如某公司有自己的人力管理功能,完全可以不选用C系统的人力管理模块,而只购买进销存主功能。
每个插件一个维护团队,让开发人员不用关心其它模块的结构,更加专业化,维护更容易。
- 问题
升级程序是大问题,数据结构、代码接口变动过大会对升级造成影响,特别是细小问题,在.0版本未测试到,直到.5版本有用户发现上报,这时再去弥补升级漏洞的代价就大了去了。
产品一直可变,变来变去,加来加去,最后需求文档都对不上号了,等过一段时间又来扯皮“这个功能跟需求上对不上啊”。反映过这个问题,但上面美其名曰“敏捷开发的精髓就是应变”。
测试驱动不了开发,开发没有单元测试代码,开发与测试同时启动任务,开发看不到测试的用例。
开发人员对功能熟悉度不够高,技术能力有差距,新人只能做简单的工作,而且对“重构”的概念很模糊。
- 改进建议
产品经理应该更有创造性和责任感。在一个只有1/10000使用率的功能上花1个月时间进行功能增强是不可取的,产品经理应该考虑用什么新奇idea来打动用户。然后就是责任感,自己对自己设计的功能都熟悉的产品经理我见过好几个了,明明开发期就能检查出的问题,在系统期产品经理才抱怨“你没按需求说明书的要求来做,肯定是开发和测试没跟我好好沟通”,一句话就能把问题推卸得一干二净。
开发模式应该采用“Test-Driven Development”,在有单元测试的基础上进行开发能够让开发人员对代码思路更加清晰,避免出现严重功能问题,而且还有一个作用:写一次用终生,每完成一个新功能,跑一下项目所有的单元测试,或许会发现一些关联影响的问题。
测试大多数是黑盒功能测试,每一个版本测试必须跑通所有用例,这样的工作量会随着功能加强而越来越严重,所以是时候考虑自动化测试了。
最后是注重代码优化和重构,每一个小版本都在做新功能,很难有时间改造代码质量,每个文件的内容只增不减,这是不好的现象。人家谷歌、亚马逊能在新版本将自己的核心文件大小一降再降,为什么我们就不行呢。
整体来说,这个项目是成功的,毕竟功能那么多,能花这么大的人力物力来做这件事,老板确实是大手笔了。稳定性肯定会随着时间越来越好,因为有一个良好的架构支撑和统一的组件平台,开发可以通过“小步快跑”的模式一点点改进我们的代码,随后很长一段时间才是锻炼开发人员技术能力的时候,但至于能不能实现“小步快跑模式”就得看项目经理和产品经理的决定了。
最后补充一句,我觉得“小步快跑模式”是在对当前系统能容忍的前提下进行,如果你对你的系统架构和技术漏洞完全失望了,再怎么“小步快跑”都很头疼。