为需求变化和维护早作准备

  在系统设计的时候,要考虑到未来可能的需求变化,做好面向变化的架构设计。但不要过度设计。(这需要深入理解商业需求)

  为维护早作准备,意思是说,在编码阶段,要考虑到系统的可维护性,设想你自己是将来维护这个系统和这段代码的人,这种意识很重要。有的程序员以为系统提交了上线了没他的事情了,结果到头来上线了出现问题,系统又没有很好的log和trace,导致问题极难线上调试,而线下又不能模拟真实的环境,这种情况下必须为维护而设计,提升系统的可维护性、可追溯性、可管理性。

  不要过度设计和过早优化

  过度设计是敏捷开发应该避免的,很多工程师都有过度设计的冲动。例如,在一个web系统还没有看到被大规模使用的曙光以前,设计了系统规模化,什么集群、负载均衡、读写分离、分布式缓存系统……说真的,这些东西确实是好东西,但也很贵。在系统还没有被大规模的用户接受和喜爱之前,这样做是否会抵消了我们把专注点放在核心功能和简练和简单的努力呢?时间是有限的,投资也是有限的。我们必须把有限的时间和有限的金钱用在当前核心的功能和体验上。有时候系统初期,可能一两台服务器足够了。只有在看到产品有被大规模使用和用户喜爱的曙光之后,才来增加功能和规模量。当然,你的网站功能,在你只有 10 万用户的时候,可能和你有 1 亿用户的时候会很不一样。所有太多太早太频繁的架构上的大动作可能会适得其反。这一点上,你要小心判断。系统架构需要及早规划,但不要提前实施和过早优化。

  关注非功能性需求

  也许大多数客户和咨询师也会听说过神马TDD、迭代、原型、持续集成和持续部署、Agile等时髦的词语,这些也让管理者很兴奋,以为软件产品是可以在很短的时间内高质量的完成的,即使完不成也可以在后面用TDD,快速迭代,不断重构,持续集成直至持续部署的方法在进行软件开发。这听起来好像很美好。但其中有个很大的陷阱,那是客户和咨询师,还有原型、TDD大都只关注功能性需求,而忽略了非功能性需求,比如性能问题,高可用性问题,系统维护问题(模块的耦合问题),等等。客户和咨询师在项目前期闭口不提这些或很少提及,但一旦功能性需求都做完了他们会抱怨这些隐藏的非功能性需求。而像性能问题,高可用性问题,系统维护问题(模块的耦合问题)等并不是很容易重构,往往涉及到Re-design, re-architect;因此这些问题往往都在后期会成为重构噩梦,甚至可以让你的软件设计重新来过!更加糟糕的是,大多数客户不愿意为这些隐藏的功能重构而付钱。笔者曾经遇到过前期只注重功能性需求而后期发现性能不好而进行re-design, re-architect,这对项目管理来说有很大的挑战,因为不单单是程序和架构重构的困难,还要面对时间和人力成本的增加,难的是你还要面对的是团队士气因为不断的rework而逐渐低落并产生厌倦和懈怠情绪。这是一个很大的陷阱。

  所以,前期要关注非功能性需求,不要急于动手,如果你能有多一些时间去和客户讨论一下需求和未来可能的变化,去调查一下实现的技术难点和细节,去和其他有经验的人讨论并推敲一下架构和设计,去思考设计上的缺陷,那么,你的coding会变得非常地直,直到你一眼看到尽头,你的测试案例也会写得非常地好,你会几乎不需要重构,于是,你会在未来少写很多代码,从而你的软件开发会越来越轻松,直到技术开始换代。这好像我们修路造桥一样,我们需要花大量的时间勘测地形地质,分析数据,思考可能出现的各种问题(各种自然灾害),评估不同的设计方案,而不是先尽快建好再说。(:磨刀不误砍柴工) 说到这里,有些反敏捷(反Scrum),没错,好的程序员要会做权衡/平衡,好的架构师要会做平衡,好的项目经理也要会做平衡,这非常重要。

  再补充一点,有经验的工程师/架构师对非功能性需求的设计和平衡很有经验,这些经验对系统设计和项目成功至关重要。如果你很不幸,手头没有这些有经验有价值的人,而只有一堆码农,那么恭喜你,你可以在一张白纸上画画了。开发他们的潜力吧,做好这个项目给他们积累经验的心理准备吧,量力而行吧,小马过河吧……实在不行你自己上吧,毕竟公司要求用少的钱在短的时间内出来的东西;如果你有话语权,那把你的困难及早让上层知晓。

  严格控制需求和范围,和进度权衡,不出现资源空闲

  领导一般会给项目经理压力,要求在什么时间提交一个版本赶进度等,这时候项目经理要么能调整一些需求和范围(Scope),要么把可能出现的问题进行报忧,因为现在如果不这样做,你等着现在报喜,后期报忧吧。所以项目经理一定要严格控制需求和范围(scope),和进度,和质量权衡。同时要合理调配资源,不要出现项目进行中资源空闲的情况(这个在Project工具中可以看出)。