All Stories

深受MS毒害的代码民工

  昨天下班为止,也没把预定的版本发出去,因为预定的需求没有完全实现,一个大的特性不能正常工作。所以今天上午就跑去公司捣腾了一把,两个小时就搞定了,比较安慰的是架构没有错,只是几处很细微的细节上犯了迷糊,尽管调试到解决了花了近一个半小时。  我有点怀疑的是有人说TDD的最高境界是不用调试,但之前的经历已经证实,我尽管有单元测试,但单元不通过时,我还是需要调试来查找原因!难道就因为我TDD没到最高境界?我想狡辩,不全是我的原因,肯定是他们的业务逻辑太简单了。这样又扯到另外一个问题,为什么我的业务逻辑会复杂,照Martin Fowler大叔的说法,如果一处代码太复杂了就,就要分解成几个简单的。可是以我现在的水平和智商看来,这是个悖论,分解后还不是要再组合在一起,仍然是复杂的,仍然逃不过调试的命运。但我又怕万一有不幸的人看到这篇文字,会提出另一个观点是,如果组合在一起仍然是复杂,那是架构有问题。那刚好把问题的责任转移到另一处,哈,我争辩不过。不过还好,我一点都不排斥调试,因为不得不赞美几句MS,他们做的VS里的调试器太好用了,或者说他们已经做出了世界上最好的调试器,别拿那些啥gdb之类来的扯淡。  在公司的时候突然想起来,我要用MinGW+wxWidgets写GUI程序,是否可以用Eclipse+CDT呢,从此可以摆脱MS的诱惑了。下午回到家整蛊了一个小时,不得不说,我还是继续用VS+VA吧,我想到的也就是个自动补全、智能提示功能而已,可惜Eclipse+CDT还做不到那样。  总之,我是个深受MS毒害的代码民工。

rdoc流程

  今天听同事讲了rdoc的处理流程,他完全是通过阅读rdoc的源代码来理解的,而且似乎他根本没有多少编译原理的基础的,汗!  总的说来,通过他的讲解,我了解到,rdoc的处理流程基本也是分为词法分析和语法分析阶段。首先,应该说有一个词法分析器生成器,叫SLex,然后由RubyLex提供规则,其实是一组正则表达式,SLex可以说是有一个正则表达式引擎,根据这些规则,生成token,提供给RubyParser使用,基本上是lex/flex做的事情。然后RubyParser根据这些token解析出class和model,建立起相关的实例,解析出相关的注释信息,通过yaml写到文件中。这里有点虎头蛇尾了,不过大体上也能表达清楚想要的意思了。  比较佩服的就是同事仅凭这些ruby源代码,就看到流程来,我怀疑要我上的话,如果没有这些编译原理的知识作铺垫,应该达不到他这样的程度吧!

SVNLabel

  今天把CruiseControl上的label改成svn的revision号了,在公司发现个问题,有一个项目里总是不能正确取到svn的revision号,虽然构建了,但从web上看不到结果,没有日志,晕!回到家,也改了一下,又发现另外一个限制,其实这个可能要算是svn的限制,当时我把源代码从vss迁移到svn时,所有项目都是放在一个目录下的,所以现在svn里各个项目的源代码commit后revision号是累加的,并不是各个项目独立的,于是在CruiseControl上显示的就是几个项目用了相同的revision号了,晕!不过第二个问题应该影响不大,因为照我现在的应用场景,一个时刻只会对某个项目的源代码修改,只要CruiseControl是一直开着的,出现这种冲突的机会也不多。

穿越东西涌

  这次是从西涌到东涌这样的路线。以前听很多人说过,就是自己没去过,这次可是切身体会了一把。  本来自己的负重差不多,不会让自己太累到,结果出发前有2个mm把一些水和水果放到我包里了,结果真的重了好多。  今天才知道,原来东涌和西涌也就是两处海滩游泳场,穿越就是沿着海岸线从一端走到另一端。  沿着海岸线很不好走,大半的是礁石,剩下小半的路程是在山上爬,真的是爬哦,我还带了跟登山杖去,没用上,太难走了。中途一mm要虚脱了,于是我发扬不怕苦不怕累乐于肋于舍已为人的国际共产主义绅士风度骑士精神,帮忙背上她的包,果然又重了很多!  非常不幸的是,在从一高处跳到低处时,左脚踩到一块不平的石头上,于是扭伤了。不幸中的大幸是,已经离终点并不远了,咬咬牙总算也坚持下来了。  拍了一些照片,总的说来,海景很不错,怪不得总会有拍婚纱照的要去海边,今天就碰到两对,呵呵。

软件工程大会

  今天上午去听了软件工程大会的几个议题,发现挺没意思的,没有多少收获。大部分都是炒冷饭,没有激情,没有让人耳目一新的感觉。全是敏捷来敏捷去,持续集成来持续集成去,TDD来TDD去的。  于是下午就没去了,写了几行代码,把log4cxx加到工程中了,用xml格式的配置文件,看起来比较统一,所有的配置文件都是用xml的,哈哈,不过我的配置文件也太多了点。发现还是不能直接在代码中用unicode,编译时没问题,但是链接不通过,不知道什么原因,难道是哪里设置的问题。不过中文倒是可以了,在家里编译的不行,输出全是乱码,而且同事也一直说是乱码,不知道是编译的时候用的操作系统影响的,还是编译器影响的。

感觉像是一种耻辱

  不分还好,一分就郁闷了,感觉像是一种耻辱。

软件可测试性设计

  可测试性设计,即所谓的DFT,今天又一次重重地感觉了一次它的重要性。  系统中有一个权限管理模块,同一个物理用户可以不同的逻辑角色登录系统,系统中以各个逻辑角色为最小管理单元进行权限管理。一般情况下,用户可选择的逻辑角色范围是极有限的,绝大多数用户应该有只一个逻辑角色,当然在测试情况下,情况刚好反过了,基本上每个物理用户会有几个逻辑角色,容易暴露出问题。主要集中在,角色拥有的权限不正常,比如看到了不该看的,看不到该看的,可以做不该做的,做不到该做的。  一直以来,对这块的调试/测试都是很困扰我的问题,主要就是DFT没做好。最开始,把所有业务逻辑和界面绑定在一起,差不多每一条规则都要在界面上点来点去,构造很多与真实环境类似的数据去测试,非常麻烦,不容易遍历到各种情况。  后来将这模块重构了,把业务逻辑和界面分离,用单元测试来保障逻辑的正确性。从DFT的角度讲,这种代码架构方式,就是一种改进,对DFT的改进。  有了单元测试,还不能保证程序能完全正确地运作,因为除了逻辑正确,还有可能其他地方出错,比如输入数据就有问题。在前些天他们测试的一个版本中,依然发现了一些权限相关的问题,让我觉得比较郁闷,因为我一直以为应该是万无一失了的。不过事实摆在眼前,也逃不掉,今天老老实实地在那里定位,不过开始的时候还是异常困难,因为测试场景的千奇百怪,我的开发环境下,有些场景很难模拟。  后来突然灵光一闪,我应该为了方便测试,多写一点代码,多加点功能,比如当前这个问题,我可以加一个特性,能在某种特定条件下,使我可以以任意角色登录系统。说干就干,果然很容易地定位到了测试发现的几个问题的原因。  今天的经历告诉我,在软件可测试性设计方面,有很多值得研究的东西的,天呐!

炒冷饭

  说话那天还在抱怨嵌入Python真辛苦,后来突然灵光一闪,马上解决了那个执行外部脚本文件的问题!既然现在已经能做到这一步了,接下来就应该考虑,能利用这个能力做些什么事呢?  总的说来,现在我已经有了嵌入4个不同风格各有千秋的脚本语言解释器的经验:Lua、TCL、Ruby、Python。以后如果有需求,我估计TCL是不会再使用了,总觉得它的语法太枯燥了点。剩下三者,对Lua和Ruby的了解稍微多一点点,但也还没达到能用来做独立应用的程度。相比之下,Ruby的那种怪异变态的语法,还是比较吸引人的,还有就是它带了那么多稀奇古怪的库,可以大大减少重复劳动,这比Lua来说,省事不少。但Lua的轻巧,却一直让我觉得是嵌入的最佳语言。实在让人难以取舍呀!  想了想,WIND就只用Lua嵌入了,因为这是一个相对比较追求性能的应用。而WallpaperHelper其实用什么似乎没多少影响,而且照现在的趋势,WallpaperHelper的体积已经不成为主要关心的问题了,功能才是最重要的。另外还想过要写打谱程序的,也要嵌入扩展。StoneBase的功能让人比较满意,但从写代码的角度看,它的架构不行,可扩展已经成了继续发展的必经之路了。但我还没想好,是用MFC,还是WTL,或者wxWidgets来写呢?

让SMTP支持中文

  项目里要有发送邮件的功能,想法非常简单,公司有个SMTP服务器,通过它直接就可以发送到notes中了。网上SMTP的源代码也是一堆一堆的,找了一个CodeProject上的,加上base64编解码也只有4个文件,接口非常简单,于是稍微改了一下,base64本来我就有,就只需要加入2个文件就可以了,附件也能正常发送,很是满意。不过上周五的时候突然发现,主题和内容中的所有中文都变成乱码了,有点气馁,随便又找了几个其他的代码,也是一样。  今天闲起无事,就想改一下。只知道在哪里看到过说要用base64,就能解决这个问题。尝试着先把主题编码了,发现收到后就是编码后的字符串了,这也是预料之中的。上公司的论坛发了个帖,没人回复。后来自己忍不住了,用Outlook Express写了个邮件,主题和内容都是中文,然后打开Wireshark,抓包,比较了一下CodeProject上那个代码发送的,看出区别了,原来也就是加上个charset="gb2312",再base64,就搞定啦!