硕大的汤姆

硕大的汤姆

The official website of Minhua Chen

02 Aug 2018

需求变更的一致性

最近在工作中遇到一次重大需求变更,对业务模型的设计也产生了非常大的影响。基本上就是在地基上挖个洞的那种变更。目前迭代还在进行中,但是我觉得是时候进行一些回顾,来思考这次大型迭代中我们做对和做错了哪些事情了。

产品一致性的重要性

复杂软件通常都会由几个不同模块组成。比如一个做包装功能的产品经理,突然改了一个需求,原本一个包装内只能装一种东西,现在要改成可以装不同的东西。当这个变更发生的时候,另一个可能使用包装的产品经理和相应的程序员都应该被告知,并修改相应的逻辑,并配合其一起上线。可是有时候,做底层功能的这个产品经理和程序员并不足够了解谁在依赖他们,可能就这么稀里糊涂开始写了,写着写着发现这个变更会影响到上层模块。而这时候上层模块正在经历属于它自己的迭代,一切就都搅和在一起了。

这种重新打地基式的迭代是非常糟糕的,你的团队会失去可用的共同语言,失去对产品的一致理解,失去相互间的信任。

所以,在项目建设的前期,做好需求调研和设计规划是最重要的。这能帮我们打好基础,让大家达成一定的共识。并且能够在产品方向出现分歧的时候作为一个指引。

但是,有些时候你很难在早期弄清楚用户到底需要什么,有时候避免不了会出现大的一些需求变更,甚至你会发现自己的模型根本就是错的。这时候你可能会做出一个产品迭代的决定,将现有的模型换掉。而这时候问题就来了。

你决定从底层的服务开始改起来,上层服务依赖着底层服务,所以上层服务也要改。而上层服务同时还有其他需求正在做,一切就都乱了套了。更可怕的是,你的服务已经上线了,这意味着已经有用户在使用你的软件。所以你要考虑 migration,你要考虑兼容性。于是你要在这段时间内需要搞定太多太多的事情了,或许模型本身并不复杂,但是因为这些问题,这样的迭代会非常困难。

这种不必要的复杂往往来源于产品的不一致性。当产品从一个合理的模型演变为另一个合理的模型的过程中,为了避免迭代周期过长,敏捷开发会将其拆分为一个一个细粒度的迭代。绝大多数情况下,敏捷开发都是好的。但是如果拆分不当,敏捷也会很危险。比如你把一个底层模块的变更安排在了一个迭代中,而上层模块先去写一些代码兼容它,code base 中会出现很多临时代码,如果这些代码由一些不熟悉这些业务的程序员来编写,或者由一些责任心不强的程序员来编写,就等于挖了一个坑。在这中情况下,应该尽可能让整个系统的功能保持一致性,宁可将底层模块的变更拆分到不同的迭代,也不要出现上下游服务不一致的情况。这需要团队内部充分的沟通,千万不能形成“安分守己”的团队文化。

程序员的责任到底是什么

程序员最重要的职责就是维护代码。这里的维护有两个含义,一方面是指让你的代码能够稳定正确地运行。更重要的一点在于,程序员应该为自己代码的整洁性和可维护性战斗。产品经理不会知道这个功能有多难做,你必须不停的告诉他,你必须习惯于不停地 challenge 产品经理,让他只做最重要最合理的需求。

一个好的技术团队,必须要相互挑战,产品经理站在用户的立场说话,程序员则必须为自己的代码战斗。如果程序员也站到了用户那边,代码就很可能越写越多越写越烂。很多时候,产品经理跑来跟你说一个需求,你乍一听挺合理,但是实现起来非常的困难,你一定不能直接答应下来。先推,让产品明白这东西很难做。再问产品为什么要这个功能,有没有其他方法满足他。产品经理往往会直接给你一个解决方案,但是优秀的程序员要去找到根上的那个问题。

总之,程序员的工作并不是完成产品经理的需求,而是开发并维护你的代码。这两者,从来都不是一回事。