敏捷开发“松结对编程”系列之十五:L型代码结构(编程篇之一)
本文是“松结对编程”系列的第十五篇。(松结对编程栏目目录)
之前的L型代码结构的前三篇提到过,L型代码结构的微观计划和估算过程会与一般的编程方法不同,今天正好要编写一些新代码,边写边记录整个过程。如果中间卡壳了,我也会尽量记录下来。
业务需求这是《火星人》中的一个功能,以往用户故事是使用故事树来展示的(就是有父子关系的用户故事),故事树隶属于一个产品Product。但是最近要发版了,感觉一个以前认为暂时用不上的功能,现在变得很急迫,那就是在当前这个版别Edition(比如“在线版”)的当前版本Version(比如“简化试用版”)的下一个发布Release(比如“R20120331A”)中,到底有哪些功能?如果某些功能在这个发布中,就要通过自动化测试(某些功能现在有自动化测试用例,但如果运行可能不通过,因为这些功能暂时不发布)和人工测试。看起来功能条目化一下大约如此:1. 先在版别Edition上做与用户故事的对应2. 然后在版本Version上做(受到版别的约束)3. 然后在发布Release上做(受到版本的约束)一般实现的做法大约包括这些工作:1. 三张数据库表做对应链接(如果是一张表,则会多一个字段,表明是版别、版本还是发布),按7或21功能点估算,需要7或21人天(在OA类项目开发中,1功能点大约需要7~9小时,产品研发应该略长)。2. (展示对应关系,加入一个故事,挪出一个故事)×3,按12功能点估算,大约需要4×3=12人天这里的人天包括了从需求分析到测试、发布(含维护一段时间至稳定)的总工时,实际开发大约占50%,也就是大约10~15人天左右。L型代码结构的做法步骤1:找到相似的业务这里的相似,指业务逻辑相似,比如都是“二叉树”或都是“查询”之类的。我们之前做过一个“团队与产品的对应关系”功能,即安排哪些团队可以访问哪些产品(反之亦然)。界面如下(很丑啊呵呵,以后有机会再改,现在整个界面风格都在修改):
return View(ItemTree.ViewPath);通向一个可复用的View,它的结构就是左边一个Pad,右边一个首级目录横置的树(也可以不是),它会在当前目录下寻找一个叫做"_[Action]LeftPad.cshtml"的View来显示左边的Pad和"_[Action]TreeNode.cshtml"的文件来显示右边的每一个节点,这是刚才拷贝粘贴和重命名View的原因。Partial View和函数一样,都可以视为底层,能复用就复用。总结一些没讲到的地方1. 数据库表哪去了?因为LinkItem2Items这个表早就有了,所以不用建表。残留问题不过到此为止,还有点问题:1. 业务需求中,应该是如果一个用户故事没有被加入到版本Edition中,就不能加入到下面的发布Release中;或反之,若被加入了发布中Release中,则应该自动被加入到版本Version。这个需求还没有实现。
1. 代码减少
这些功能大约有20~30个功能点(取决于建几个数据库表),按QTM上的国际数据,C#每个功能点需要59行,所以59×(20~30)=1200~1500行,但如果有L型代码结构,就只需要20多行代码。
2. 工作量下降刚才的工作从13:30开始,到现在16:12,扣除写博客实际花费了大约1小时不到,再加上残留问题修修补补的时间也就1天。所以1天能干10~15天的活。
这个甚至不需要个人能力,即使是新手,熟悉了这个架构,速度也差不多。
3. 质量上升
每次底层都被多次调用,只要一次失败就会被发现;而每次底层改动都会帮助多个功能优化,修改Bug也是如此。
4. 新手上手快
一般“代码减少”“代码优化”常常面临的问题就是:新手能看懂和维护吗?
其实,别看这个体系好像挺复杂的,但新手看这20行代码的速度,还是比摆弄1200~1500行快多了。
例子中的所有代码,除了步骤3里边的新函数,其他的比如被我重构的LInkItem2ItemViewModel和几个Action,外加拷贝粘贴重命名的LeftPad/TreeNode等代码,其实都是另外一个人编写的。他在编写这些代码的时候编程经验只有半年(之前作为技术支持工作过4年,大学学过C++,之后从来没动过代码),实际编写的代码行数估计只有1000行(我们一共只有11000行代码)。当然,他编写这些代码的时候,又是参考了我之前的另外一个“迭代计划”页面的设计。