软件工程, 唯一不变的是变化. -- p41, <移山之道>
"永远在变化"让回答"如何界定过度设计"这一问题变得非常困难, 因为在真正的需求来临前, 你无法确信这是否一定是过度的设计. 但是避免"过度设计"还是可以做到的, 根据我在"移山公司"中有限的软件开发经验, 首先, 我们在需求阶段会进行更精确客观的预估计. 在前期需求分析和设计阶段, 软件采用何种技术, 什么架构, 具有哪些feature, feature都要怎么实现, 开发schedule制订, 都必须综合考虑开发团队的真实水平, 过往的经验和教训, 项目实际需求等客观条件进行比较精确的预估计, 而不是主观地过分追求新潮技术, 以老板或客户开心为目的制订时间表, 对客户不精确的需求描述想当然地制订feature, 对每个feature事无巨细地连函数和变量名都设计好…虽然这些一开始看上去会让大家都感觉到很美好, 但是项目蜜月期一过, 这些立刻会成为大家无穷无尽的烦恼源泉. 其次, 我们必须对可能的需求变更这一风险做好准备. 不要奢望用户一开始就会把需求讲清楚, 而且你真正理解了他们的需求. 如果一开始就意识到需求变更的风险是必然存在的, 那么在设计阶段就应该做出某些应对的策略. 特别是在架构和工作流逻辑的设计时, 就应该令其能够应对某种程度的变更. 制订schedule时留好buffer, 对含混不清的需求不做想当然的设计. 甚至, 在过去项目中”过度设计”的教训, 也能够成为避免再次犯错的绝佳参考.
但是正所谓”人算不如天算”, 之前提到的两种应对”过度设计”的策略也是被动的”兵来将挡, 水来土掩”. 所以我们的领导阿超最常说的一句话是: “既然软件开发中的’变数’是永远存在的, 那么何必寄奢望于一开始就能够将所有的可能性都考虑在内呢? 还不如轻装上阵, 随机应变.”
MSF原则之(6): 保持敏捷, 预期变化. (Stay agile, expect change) -- p30, <移山之道>
不要让所谓”制订好”的开发计划, 设计文档, 技术架构等成为束缚, 而要根据不断变更的需求对其作出持续的改进. 项目管理者的职责不是说在项目前期就把一切都谋划好, 然后接下来就是持续不断地赶着开发人员按照”规定”的进度完成任务而已. 在开发过程中, 管理者要审时度势不断作出一些决策, 这些决策往往需要很痛苦地改变我们已经”制订好”的设计和进度计划(换句话说, 既然改变这么痛苦, 何必一开始就做得事无巨细呢?). 同时, 他要在”质量”和”不断变化的需求”间做出”折衷”的决定, 既要适应用户”不断变化的需求”又必须保证不能太低的”质量”. 为了保证这两点, 所谓的开发进度/实现细节也许每天都会在变, 我们常常要根据当前团队的能力和变化的需求, 合理地裁减feature, 重新安排工作项的优先级, 从而赢得更为合理的时间安排, 让团队把注意力集中在关键功能的质量上. 同时, 在对用户的变更需求说yes之前, 也要好好考虑一下这是否一定是必要的, 及时澄清双方的误解, 让每一次变更都是合理的, 避免绕了一圈回到原地, 做无用功.
对当前项目开发的源起和目的永远保持清醒的认识, 所有的变更都围绕它来做决定. 阿超就常常教导我们在做开发时不妨时常想一想: “我们究竟要做什么? 我们为什么要这么做?”. 软件开发就好比是将一车货物(features)从A点运到B点, 在途中, 我们有时会卸下一些货物, 同时换上更有价值的货物, 或者重新包装已有的货物, 从而腾出更多的空闲空间来装载更多货物. 在行进过程中, 我们会遇到不同的路况, 不同的天气, 不同的麻烦, 车子会抛锚, 轮子会爆胎, 路面会有障碍, 有时为了过一条河, 我们甚至得立刻把车改造成潜水艇或者在上面架一座桥. 当最终到达B点时, 车上的货物和出发时比起来已经大不相同了, 但是我们的目的始终只有一个, 那就是能在这一趟运输过程中, 为B点及时运去他们最需要, 而且价值尽可能高的货物. 这肯定不是一趟轻松的旅程, 在出发时, 我们无法预知即将面临的困难, 但是我们会准备两名司机轮流驾驶来防止疲劳(人力), 制订一个粗略的行程计划, 带够前往下一个补给点的水和食物(资源), 准备好备用胎和零件(风险), 盘算好一些B点当前最需要货物(其中一些货物在运到B点之前就会变得一文不值), 把货物捆得结实又容易装卸(这样的架构的确不简单), 并在上面盖好一顶遮雨棚. 然后我们就上路了…在行进过程中, 我们要根据不同的路况采用不同的驾驶策略, 根据手中的食物和水调整行程计划, 根据货物的易碎程度调整它的包装方式和行进速度. 时刻为爆胎和零件修理做好准备. 当发现前面的道路不允许当前车辆通过时, 我们要立刻卸下货物换上另一辆合适的车(工具), 或者, 为什么不抄一条边上的近路呢? 最后, 这会成为一趟长久的旅行, 也是一趟有趣的冒险之旅, 我们饱览了一路的盛景, 也经历了凶险的磨难, 当我们重新启程把货物从B点运到C点时, 我们会变得更加轻车熟路(也许吧).