Morning@Weblog

12/5/2005

出差后的恢复期

Filed under: — site admin @ 10:13 am

我的状态大概开始恢复了,对学习也开始重新焕发了热情。最近在看马大叔的PoEAA。老马不愧是个写作高手,这点不得不佩服。书将近看了一半,虽然是影印版,可前面的内容竟然也能让我看得津津有味,不时有感同身受的体会。

昨天终于把Michael同学的buffalo下载了下来,初步的看了一下,大致领会了精神,当然,对于我这个对JavaScript不甚精通的人而言,初读这样的JS代码还是有些别扭。不过之前粗粗的补过一点基本功,对于JS这个动态脚本语言的神奇之处也着实有了认识。我还找来了“JavaScript 2.0 Complete Reference”的电子版,打算过一阵有时间了翻上一翻。

前一阵在网上碰见孟岩,他问我现在是不是也也rubilized了,当时我纳闷于不知何意。后来他的解释才让我恍然大悟:现在搞Java,又做Web,还喜欢Agile的人,还有几个能置身Rails大潮之外?看来我是有些落伍了,虽然工作内容所限,不过还是打算将Rails纳入学习计划之列,触类旁通,好歹也能让我这个Agile fans不至于名不副实:D

出差两个月之后的状态恢复期

Filed under: — site admin @ 10:06 am

在外出差两个月,筋疲力尽,如今回到北京已将近一个月了,状态也逐渐开始恢复了。

最近在看马大叔的PoEAA。老马不愧是个写作高手,这点不得不佩服。书将近看了一半,虽然是影印版,可前面的内容竟然也能让我看得津津有味,不时有感同身受的体会。

昨天终于把Michael同学的buffalo下载了下来,初步的看了一下,大致领会了精神,当然,对于我这个对JavaScript不甚精通的人而言,初读这样的JS代码还是有些别扭。不过之前粗粗的补过一点基本功,对于JS这个动态脚本语言的神奇之处也着实有了新的认识。我还从网上找来了“JavaScript 2.0 Complete Reference”,打算过一阵有时间了翻上一翻。BTW:Michael兄对buffalo的宣传力度确实有些不足,今天在写blog时本想引用一下url,可baidu上怎么也搜不到了,真是奇怪我前几天怎么找到buffalo的下载地址的。并且,如果我没记错的话,好像buffalo的PageRank是2,还得加油啊。

前一阵在网上碰见孟岩,他问我现在是不是也rubilized了,当时我纳闷于不知何意。后来他的解释才让我恍然大悟:现在搞Java,又做Web,还喜欢Agile的人,还有几个能置身Rails大潮之外?看来我是有些落伍了,虽然工作内容所限,不过还是打算将Rails纳入学习计划之列,触类旁通,好歹也能让我这个Agile fans不至于名不副实:D

8/21/2005

一个task分配2-4个小时,可以吗?

Filed under: — site admin @ 12:56 pm

近日在BJUG的maillist里听到冰云在感慨“我们做agile的方法还不够细”。其实我感觉,要做到task的细粒度其实也不难,有时候只是大家的惯性思维在作怪。想想把一个任务划分到2小时内,那一定是相对单一而明确,且易于达成的。这也很符合控制理论:当自身控制力不够时,应该想办法通过任务分割的方式,将处理所需的控制成本降低。不过,我觉得这并不代表我们要将一个长周期的安排都细化到小时,原因有二:这本身也是要计入成本的,所谓“计划成本”;情况时常在变化,这么做反而落入了以往传统软工的“陷阱”了,与“over engineering”、“over design”如出一辙。

8/13/2005

如何让新人快速融入团队

Filed under: — site admin @ 11:09 am

如何让新人快速融入已有团队,这是团队发展的必修课。正好,最近部门招了些新同事,实践中,让我也有了些许心得。我以为,如下三点实践是具有普遍性的,同时也是值得采纳的:

mentor制度。团队中身经百战、阅历丰富的老成员应该担当起新员工的mentor来,不求多,一帮一即可。mentor的作用有二:
 @ 对于技术新手,大拿们有义务为其指点迷津,答疑解惑,或者甚而对于己所不能者,起码也可以当作倾听者,不时发表自己的见地,这就是XP中的Pair Programming了;
 @ 对于技术以外,mentor也需要通过言传身教,将团队“积习”传授于新人,比如:开发过程、做事习惯、或者大而话之的“团队文化”;
其实,intern的表现对于mentor来讲也会起到督促和鞭策的效果,毕竟身为mentor,如果连自己都还是半桶水,又如何“震得住”intern呢。所以,自认为还有些心虚者就赶紧在私底下补补课吧:)

实战演练。为新人们设计一个有针对性的实战性练习,将必要技能与开发方法融入其中,有专人(老员工)负责监督与跟踪,并在练习结束后给出评价。当然,练习者也要做些总结。期间,结对的mentor也可以适时的做些指导。比如:前阶段在我的提议下,部门给新员工分配了一个JPetStore的改良练习,要求新人们组建起一个虚拟的XP小团队,采用快速迭代的方式,共同协作完成既定任务。从反馈效果来看还算不错。不要认为这样的练习没有必要,相反,为了让新人们快速成长,这样的实验性项目是最好的切入点。你可以大胆的将很多实际工作中需要掌握的技能和工具融入其中,让练习者有切身体会并学有所成。而真正的实际工作,其环境往往不会有如实验练习那么理想,因为要顾及到开发进度和客户压力等诸多外界因素,新工具新技术新方法的引入往往比较谨慎,而人们也往往不能做到时刻专注,长进的效果也就必然会打折扣。作为这一观点的印证,在我前面提到的,部门在给新员工做实战练习的同时,也为另一部门的几位老员工安排了同样的功课,最后从完成的效果来看,则明显差于新员工组建的临时团队。

安排力所能及的独立性任务。在熟识了团队氛围之后,就该给新人安排真正的工作任务了。此时,不必急于将与现有系统耦合较多的任务交给他/她来完成,这样只会让新人一头雾水。比如在产品研发的团队中,可以安排完成一些具有相对独立性的,与既有系统关系不大的Feature。这样,便可以进一步弥补“实战练习”中的缺失与不足,进一步增进团队融合。随着对系统的逐渐深入了解,那时再将复杂任务交于他们也尤未晚矣。此时,新人也便成了老人:)

8/9/2005

团队的Wiki开始真正发挥效用了

Filed under: — site admin @ 11:45 am

团队的Wiki开始真正发挥效用了,这让我感到很欣慰,记得这是我半年多前一手搭建起来的。想来一件新事物从引入到被大家自然而然的认可,并非是很容易的事情。

如今,有的同事会主动想到,要在Wiki上开辟专门的栏目,来统一管理团队交流之用的文档和资料,这是意识上的提升。于是,Wiki就担当起了它本该有的功能和职责——团队的知识文档库。得益于Wiki的“轻量”特点,其实做起来也挺简单的:我使用的是JSPWiki的“改良版”。因为集成了blog,因此所有人都可以将一些日常零散的内容作为个人blog来发布。日后当积累到一定程度,既可在Wiki上单开栏目,并将blog做整理,只要写一个简单的导向链接即可。如果是专门的,正式的文档,则可以直接作为栏目文章,而不是做导向链接。

好的Wiki应该还具备:版本管理、mail通知、RSS订阅、PDF格式导出等诸多功能。这其中,尤以版本管理甚为重要。因为有了它,实际上,Wiki就成了一个SCM系统了,那么基于文档的变更管理就也可以成为Wiki的职责范围了。

8/2/2005

实践TDD&Refactoring的一个典型案例

Filed under: — site admin @ 7:02 pm

前段时间在做部门平台的再工程,其中有一项工作是去除原先核心模块的EJB代码。这实际上是一个典型的重构过程,因为它非常符合重构的定义——在保证外部功能不变的情况下,对现有代码的调整。于是,我在每次修改代码之前,都会先将原有代码所反应出来的外部逻辑用测试用例表达出来,从而保障修改过程是在严格的契约控制之下进行的。这可以说是在我开始实践TDD&Refactoring至今,所遇到的最为典型的一个案例了。

不过期间也发现一些问题,比如:既有代码本身的易测性对TDD的施行是至关重要的。一个难于测试的软件系统,会导致编写测试用例异常困难(比如代码中大量的使用Factory或Single模式)。开始阶段,我花费了大量时间在编写测试用例上(实际上,在代码修改上花费的时间所占比重并不大)。其中的一个测试用例,直到最后完工时,才跑通,整个周期非常之长。于是这就很容易导致一种倾向:即使有心实践TDD/Refactoring者,在经历了一段费劲周折而进展甚微的过程之后,就干脆放弃了测试,冒险直接修改代码。

结合TDD,重构遗留系统的过程中遇到的另一个常见问题是,系统的耦合导致测试用例很难写。这一点在我的这次实践中也有所体现。也许针对某一个类的测试会牵涉多方“利益”,此时,最为有效的办法就是借助于mock test。假如只关心系统某个部分的测试,那么就务必要利用mock object来将之隔离。当然mock object的编写也是需要计入成本的。同时,这也教会我们,在编写实现代码时,务必要考虑可测试性,诸如针对接口编程这样的实践是一定要贯彻执行。

7/30/2005

Bad Smell,温故而知新

Filed under: — site admin @ 8:10 pm

前些天借着给新员工内培的机会向同事们推荐了老马的《重构》,今天顺便又重温了一下“Bad Smell”那一章,感觉依然还是很有收获的。重构的时机来源于“见识广博者的直觉”,比如:一个类中有多少实例变量才算太多,一个函数有多少行代码才算太长,而这种直觉是锻炼和培养出来的。想来偶尔在看同事代码时不免皱眉也是蛮有道理的,习惯成自然,看到Bad Smell就算没有“标明”,心里也会觉得不畅,总忍不住要把它改掉。老马《重构》一书的一大特色在于其技法的名称基本都可以“望文生义”,因此即使没有看过每个技法的详细说明,也已经基本能够猜个八九分了。从侯sir网站当下来的中文电子版开放了前六章,封底内页有一张Bad Smell与相应重构技法的对应表,准备将它打印出来贴到我的办公桌旁,作为时时提醒之用:)

[Bad Smell]
- Duplicated Code
- Long Method
- Large Class
- Long Parameter List
- Divergent Change
- Shortgun Surgery
- Feature Envy
- Data Clumps
- Primitive Obsession
- Switch Statements
- Parallel Inheritance Hierarchies
- Lazy Class
- Speculative Generality
- Temporary Field
- Message Chain
- Middle Man
- Inappropriate Intimacy
- Alternative Classes with Different Interfaces
- Incomplete Library Class
- Data Class
- Refused Bequest
- Comments

7/28/2005

重构、设计模式在团队协作中的作用

Filed under: — site admin @ 11:53 am

重构、好的编码习惯、设计模式的合理运用,作为开发者的基本功应该是一个持续修炼的过程,对于一个团队而言,在一定程度的掌握了这些技能之后,建立起了一定的语境,成员间的彼此技术交流就会变得更加畅快和有效率,一些分歧也会变少。大家不会因为争论一个设计或者一段代码是否合理而耗费很多无畏时间,也不会因为不合理的设计和代码而导致日后维护与更新的极度困难。并且,作为开发者来讲,个人也会从不断进步之中体会到工作的乐趣,而不是在重复单调乏味的Copy & Paste过程中逐渐消磨了自我。

7/7/2005

善用JUnit assert*

Filed under: — site admin @ 11:39 am

昨天看到一位同事的unit test是这么写的:

if (…) {
 assertTrue(false);
}
assertTrue(true);

抛开assertTrue(true)这个“无效”语句不说,怎么看怎么觉得别扭。在JUnit中,assert有很多“变体”,灵活使用将会给TestCase的结果验证带来很好的表达能力。它们包括:

assertTrue
assertFalse
assertEquals
assertNotNull
assertNull
assertSame
assertNotSame
fail

其中,每个assert*还有一个带有message的重载方法,比如:

assertEquals(String msg, Object arg1, Object arg2);

这表示,当assert失败时,会附带一段用户友好的说明性文字。

由此,对于上述的unit test,更好的书写方式应该是:

if (…) {
 fail("…");
}

而最好应该直接写成assertTrue(…) 或者assertFalse(…)。

想不到一个小小的assert也会引出问题来。

6/27/2005

爱心拯救程序员王俊

Filed under: — site admin @ 10:09 am

祝福后山,早日康复。这里是本次活动的官方网站。

Powered by WordPress