我们理想中的软件工程项目的推进,就应该像电影里盖房子似的:设计师画出蓝图,一期工程,二期工程,三期工程按部就班,建筑按期交付。
然而现实中的项目,小的不算,这里说的是大的,要做半年以上的,往往不会那么事事尽如人意,如果用盖房子来打比方,就是你会发现:你想加下水管道的地方,原来还有个搬不开的石头;盖到烟囱的时候,发现设计不合理,周围邻居有抱怨风向还有高度而不让继续的;盖到第二层的时候,发现工人不够,尤其是需要特殊技能的工人不够;原来想着各种电路走线,因为合作方公司需要符合一些新发布的标准,所有的走线必须重新规划……
类似的,项目中,你也会遇到各种内部外部的变化导致工程受到阻力或者需要变动。尤其到项目拉的时间线很长的时候,可能影响它的因素和问题也会更多。
先说项目的计划。
之前听公司某高管说过的,做项目计划,有时候就像一个近视眼往一个远处的山顶进发。你对你大概怎么登山,方向如何,大概需要多久,最开始有个粗略的估算。然而随着你前行,你能看得清的视野就逐渐推进。你会不断发现你之前没有看到的沼泽、峭壁,甚至拦路虎。所以,有一个大方向不够,你还应该有一个随着需要新问题不断合理调整路线,调整进度的策略。一成不变地试着只按照开始的路线的方案前进,很难行得通。
很多时候,项目也是。你会在后面发现,某个产品特性没有考虑进去;某个基础设施的功能块还不存在;某个你以为可以用的工具原来不能完全适合你的需求…… 那这个时候,大家只能坐下来讨论,如何进行调整。
而对于设计弊端的改进,其实很多时候有个度。比如你发现一个系统某个设计,原先是很好的,但是因为新加入的一个产品需求,突然变得不能支持这个需求。这时候或者做一些小改动,但可能会成为系统长久的一个隐患,也即 tech debt;或者考虑进新需求,重拿一套看似更完美的设计方案。
从道理上讲,tech debt 是每个工程师都极力试图避免的东西。但是重新设计新方案,真的就一定更好么?
首先,取决于项目已经进行到哪个阶段,重新设计可能意味着大量的代码要重写重构,很多相关的子系统设计要重新做相应改动。很多时候可能引起项目的延期。
此外,你当然可以说宁愿延一个月,搞一个更理想的系统更可取。但是事实是,另一个方案只是设计阶段,你是不是能保证沿着新方案做到一半的时候,不会发现其实新方案也有它的弊端呢。还有的时候,虽然说老方案在新特性上确实不那么好用,但是这个新特性会不会不是一个核心需求,否则也不会在一开始完全没有被考虑。即使是真的新增的核心需求,是不是能经得起各种用户测试反馈,而长久地留下来?或者说其实只有很少的时候、很特殊的用户才会用到?
当然,这也不是说,所有的时候,我们都有足够的理由不对设计进行大的改动。如果设计的弊端就好像一栋房子的地基对其安全性可用性造成影响时,无论如何,也必须重新考虑。
那么,怎样才能尽最大可能的避免项目中大的设计改动呢?
一是初期设计的时候,就像近视眼登山,虽然你对远处只能看到一个轮廓,但也要尽可能的去使用所有的工具,比如望远镜和地图,去帮助你设计一个更可靠的路线和进度方案。设计也是,尽可能和产品充分沟通,确保你了解所有现有和未来几年内可能的场景。尽可能了解你需要使用的已有系统和工具,以及正在开发的系统和工具,确保你想要的相关性能都能得到满足。
二是设计在大的框架和细节上的平衡。确保大的框架可以以不变应万变,这个上面花的功夫越多,后面进退两难的窘境就会越少。而一些小的细节,如果能保证是可以把改动相对独立化(decouple),而不会有牵一发而动全身的耦合,哪怕后期要改,也不是什么大问题。
和所有有经验、有决定权的人在大框架上反复沟通,确认再确认。而不是等到工程进行到一半被质疑为什么这样的设计决定没有让该知道的人知道。哪些是可以自己掌握的细节,视情况而定。
三是尽可能的将可验收部分分块,也就是一年的工程,每个季度可以完整交付哪一块。而不是说,所有的部分都是正在进行,只有年底一个验收阶段,分期定交付目标可以把一些大问题控制在一个相对有限的范围内。
四是任何一个系统,随着产品、用户数的进化,都不会是完美的,都持续会有新的可改进空间。知道自己主要要解决的问题是什么,并且时刻谨记。因为有时候在为了某一个原因改设计的时候,可能你无意让另一个之前解决的问题,变成新的痛点。
最后,项目是死的,人是活的。有的时候,同一个问题,换个人来负责,来做,可能就有完全不同的抉择。尽可能制定一些指导规则,确保大家都同意,这样,即使因为人员变动产生分歧,也不会引起太多不必要的争论。
大改动伤筋动骨,要尽力避免。小改动几乎是无可避免,坦然面对就行了。而小改动,虽然说不可避免,且危害不算太大。但有时候,因为各种产品、参与者的关系,也可能会发生 “改回来又改回去” 的情况。不仅费时间,也容易消磨程序员的斗志
---本文摘自滴滴答答