运用敏捷实践解析bt种子文件

来源:互联网 发布:江一燕义卖是在淘宝吗 编辑:程序博客网 时间:2024/04/28 22:54

  出于某种"卑劣"念头,我产生了自己动手做个bt下载工具的想法。同事洪俞也十分有兴趣,于是我们组成pair,利用下班后的时间开始重新发明轮子。

  简单看了看bt的相关资料,第一步要做的肯定是解析bt种子文件-torrent文件。格式譬如见这里(http://www.blogjava.net/huyi2006/articles/241632.html?opt=admin)。包含了字符串,数字, 字典,列表4种数据类型, 这是一种递归的数据格式,列表或字典可以包含四种数据类型的任意多种,譬如列表里包含一个列表,这个列表内部又包含一个字典等等。

   结对编程:

  pair编程的一些好处我认为是:

      1. 可以与pair讨论设计,从而找出相对更好一些的设计

      2. 编码时由于有pair的监督参与,脆弱的代码会少一些

      3.  双方都能熟悉这块代码,双方以后都有能力改代码

      4.  激发双发的热情,同时也可以防止pair偷懒 :)

  至于开发效率,我觉得仁者见仁,智障者见智障。大多数软件开发比的是质量而不是速度。

  虽然文章标题写着"运用敏捷实践",但是我们两个从来没参与过使用敏捷的项目,因此权当伪敏捷一把,挨挨刀体验体验。

敏捷的第一个实践便是pair编程,两个人坐在一起,一台机器,边讨论边开发。洪俞首先谈到了做另外一个项目时解析过ajax的jason格式,我们比较了一下两种格式,都是递归的数据格式。于是我们hack了一下解析jason使用的开源C++类,仿照写法,设计了bt种子文件的格式的处理类,边设计边写伪码。

  但由于两人设计的算法没有理清,自认为该算法ok的情况下便开始匆匆编码,结果耗了两个晚上总是遇到了一些和设计的算法冲突的情况,迭代过程中也十分不成功。

  测试驱动开发:

  周末自己又思考了这个问题,迭代不太成功的原因显然和测试用例有关。我们早期有几个简单情况的测试用例,但是当调试成功后,嫌麻烦便丢弃掉了。等代码膨胀,测试复杂应用出现问题时,由于基本的测试用例已经被我们丢弃,到底在迭代的过程中什么时候出现了问题,也只能硬着头皮一次一次的调试了。

  敏捷开发要的是测试而不是调试。我真的很讨厌调试,我决心从头来过。

  照着Bob大叔的名著《敏捷软件开发:原则、模式与实践》里的TDD方式,于是我在基本设计做完后,在编写代码之前,首先写了一个简单的解析数字的测试用例 ,

// int value test
TEST(BValueTest, SingleIntParse)
{
      IBValue_t value;
      bool bResult = Parse("i123e", value);

      ASSERT_TRUE(bResult);
      ASSERT_TRUE(NULL != value);
      BType bType = value->GetType();
      ASSERT_EQ(INT_TYPE, bType);
      EXPECT_EQ(123, boost::static_pointer_cast<IntBValue>(value)->GetInt());
 }

 

这个用例解析字符串"i123e",判断是否正确输出123以及结果类型是否是整型。由于还没有写代码,编译没有通过。

接着我才开始写代码, 如果是数字格式,解析出来。编译成功后,运行一下,绿条显示,通过了!我有点不放心,准备多增加了一个用例,这次字符串的格式是"i123abce",由于torrent规范里要求i和e之间只能有数字(如果是负数,第一个字符可以是负号-),但运行后,显示红条, 没有通过!于是我便修改了一下代码,再次运行,通过了!

 按照上面的方式,我解析字符串,字典,列表格式前都预先写好对应的测试用例,然后才去写代码,并且每次迭代重构时,我都跑了一下以前设计的用例,确保迭代不会让以前的设计退化, 这样每个过程都十分顺利,最终在花了12个小时后(万事开头难,成本总是高一点儿的),我终于完成了解析bt种子格式的代码!

  那一刻,我的心情是复杂以及愉快的,我似乎有点儿明白了所谓的TDD。之所以自己在编码迭代和重构过程中信心十足,也是源于有了这些test case,我不再焦头烂额,而是底气十足,开发过程中十分愉快。

  当然不光是做test case, 在开发过程中, 调试,printf大法, __asm{int 3};以及各种手段我都统统派上了场。任何一种方式都不能解决所有问题,包括所谓的敏捷方法,找到适合自己的才是王道。

   虽然很早以前我就知道过TDD和敏捷,但是到今天我才去实践, 只有去做过了才能明白这些道理。现在开了个头,以后再继续去体现。

   我推荐大家也去尝试尝试这种方式,特别是C++程序员!

后记:

我使用的unittest框架是googletest,  是google推出的开源C++单元测试框架,项目地址在这里:http://code.google.com/p/googletest/ 。可以参看右边的 Featured Wiki Pages 栏里的GoogleTestDevGuide文档配合download下来的source以及example来上手。

特别要注意:

如果是在visual studio下使用的,请注意它的项目配置的多线程环境和你的项目的配置的多线程环境是否相同,这点上吃了苦头。

 

  

 

 

   

 

 

   

 

原创粉丝点击