2007年12月6日
想搬到BlogBus 去
理由如下:
1、BlogBus 速度很快
2、BlogBus 可以提供很好的API 调用,我可以利用JavaScript 整合许多别的应用功能
3、BlogJava 这里的编辑器老出问题,还是我的FireFox 有问题?整得我很不爽
4、我的博客现在不光只有技术了,也不光只关注Java系列的了
新的地址为
http://phoenixtoday.blogbus.com/
看了部电影《钢琴之森》,却被它感动了,触动很大,或许有些话说到心坎里了吧。
故事讲述了两个孩子,一个叫“海”,另一个叫“修”。他们都会弹钢琴,“海”家里穷,却从小与森林里的钢琴一起长大,对他来说钢琴是亲人,是乐趣,是享受,钢琴是给自己弹的,钢琴是存在于他每一个细胞中的;“修”从小练钢琴,从生下来,钢琴对他意味着日本第一,意味着成功,但钢琴就是他的敌人,为了钢琴,他放弃了太多太多,他刻苦练琴只为超越别人,拿得第一,弹钢琴意味着只要不出错,就是完美。森林里的钢琴却只有“海”才能弹响,无论“修”如何努力,森里的钢琴选择的只是“海”。
这个电影,先引发了我的回忆。记得小学我第一次拥有的学习机,大部分时间,我是把它当成游戏机的,可是看着那些动来动去的小人,心里总会犯嘀咕。后来,就照着学习机书本上的,照猫画虎的写了那么几十行还是上百行的类Basic 程序,看着自己写出来的“超级玛莉”可以左右移动,还真的是有些激动,可是那时候的激动,却远远及不上本科之后的那一次。第一次接触真的电脑是在初一,一个电脑培训班里,对电脑有了概念,大致上就明白了一些基本操作和原理;后来有时会去网吧,再后来在初三拥有了自己的第一台电脑,从此才走上了正轨。有了第一台电脑后,不光用它来玩游戏,还开始买《大众软件》,慢慢的会的基础知识越来越多,游戏也玩的越来越多,可是却远远满足不了自己的好奇心,到底这些游戏是怎么做出来的呢?初三的那一年,我将自己的理想从“科学家”细化为“计算机软件学家”,呵呵,当时真的不知道有程序员这个词。大学报志愿,义无反顾的报考了计算机专业,大一第一学期末,用C 语言写出了自己平生第一个程序,望着几百行的main 函数,看着屏幕上闪动的“Welcome” 心里真的激动的不知道说什么好了。本科的计算机真的是偏理论也偏硬件,让一向好强的我,为了在学业上有所作为,硬啃那些不喜欢的东西,好不费力!大一、大二真的是迷茫,走了不少弯路,直到大三开始学Java ,开始自己寻找兴趣的出路,才逐渐有了自己的发展。从小到现在,这条路走的还真的弯弯曲曲,没有得到多少人的帮助,没有得到好老师的指导,一切靠自己摸索,就为了心中那两个字“喜欢”。
“海”的那句“弹琴是为自己弹得,不是为别人”,让我想到了自己。是啊,我写程序,研究技术,从来没有想过为任何人,就为了自己那份喜欢,当然这不是说,我写好的程序给别人带来了快乐,减少了别人的工作量我不开心,而是当初就压根没想到,就是想这个场景可以用自己喜欢的技术,可以这么做,可以做的更好,可以解决以前遇到的问题。而这几年,身边遇到了很多朋友,有时也跟他们交谈,大部分人给我说他当初选择计算机的原因是因为“热门”,少部分的人则是因为“这个行业可以赚钱”,还有几个人我认为是为了“超越身边的人”。这些人,从来没有觉得自己是真喜欢这个行业,这样做是有趣的,他们的动机都是由外在因素引起的,必然不会长久,无法坚持十几年、几十年,甚至一辈子,因为热门的条件会改变,别的赚钱的机会未来会更多,身边的强人你永远超越不完。扪心自问,这真的是你喜欢的吗,它对你来说真的是有趣的吗?如果这个行业只能给你保证温饱,就像很多数学家穷得叮当响,你也会义无反顾的坚守吗?
“如果你弹不出自己的舒伯特,迟早有一天,舒伯特会找你要回曲谱”,是啊,如果你设计不出自己真正想做的程序,那么你的所学所做,又有什么意义呢?而你如果不喜欢自己现在所做,那么将来,你还能做出自己想做的吗?“海”为了弹出自己的舒伯特,每天除了练琴还是练琴,加上自己固有的灵性,最后终于成功。“兴趣”和“爱好”对于你所要坚持的行业来说,是远远不够的,你能够在别人享受生活的时候,自己安静的看书吗?你能真的为了一个目标,每天坚持写代码吗?前几天被同学笑了,因为我说“我过年和平时一样的,看看书,写写程序,没啥不同的”,然后他们笑我“你的生活还真的无趣”,o(∩_∩)o...,其实他们不知道,这才对我是最有趣的,我每天都在享受着,每天都在过年。越深入这个行业,越发现自己所学太少,时间太少,还有很多自己感兴趣的东西,每一门想精深的东西,都还有那么多那么多知识。真的想早一些谱出自己的舒伯特,真的向往那一天,不知道何时真的能达到?努力吧!加油!
昨天,要写一段程序完成一个定时任务,是有关Socket 发送的。胖子给我发了一段现成的程序,这段程序基本上的功能是实现了,但是表达的并不是那么清晰,因此我想重构一下。没想到重构的过程竟然花了一个多小时,从晚上八点多,一下就写到了十点,但是重构完后,感觉清晰多了。仔细想想收获颇多,因此在这里写写经验进行总结。
重构程序的目的,不是因为程序不能用才要你去重构,重构的目的是因为一、你的代码,被人看的次数,远比它用到的次数多;二、重构有利于你发现问题,让你的程序结构优化,因此可复用性更强,遵守了知识的唯一性,DRY 原则;三、如果你要改动这段代码,那么先重构,使得你的代码好改,这实际是在为你的未来减少工作量,而且一段优秀的代码,带给你的价值,远比你每次都要Ctrl+C,Ctrl+V 大得多。
写代码,要让你的代码第一次呈现在别人面前的时候,像读英语一般,那么你的代码功底是足够了。你的代码就可以称作你最好的文档了,其余什么文档,大可不必!
基于昨天的经验,我新总结了两条:
一、经常使用重构方法extract method 的人,会发现,总是可以省掉一些临时变量。这是好事,但这可能会造成如下的结果:
method_one(method_two(method_three(method_four())))
也就是说,很可能会导致这种长串的嵌套,导致程序可读性的下降,使人看的晕头转向。那么如何解决呢,其实是一个度的问题。我给自己定了一个规矩,临界点是三个函数这样级联起来,如果超过三个,我就将它们拆开。比如说上面这个小例子,我会拆成:
arg = method_three(method(four));
method_one(method_two(arg));
虽然浪费了一个临时变量,但是这样就可以让人一眼看懂我的意思,可读性提升,修改起来自然也会容易些。
二、写过Java I/O 的人,肯定看到过这样的程序:
Reader in = null;
Writer out = null;
try
{
in = new InputStreamReader(socket.getInputStream(),"utf8");
out = new OutputStreamWriter(socket.getOutputStream(),"utf8");
/**
* some TODOs here
*
**/
}catch(IOException ioe)
{
System.err.println("error message");
ioe.printStackTrace();
}
finally
{
try
{
if(in != null)
in.close();
if(out != null)
out.close();
}catch(IOException ioe2)
{
System.err.println("some error message");
ioe2.printStackTrace();
}
}
怎么说呢,这段代码看上去,其实是够好了,其实不重构也是可以的。也许我偏执吧,我认为它不够好,因为:首先,大段的try catch 的确会捕获异常,但是这段代码至少有好几段是会独立抛出异常的,这里包含了四个IO 实例的创建和销毁,这四段代码如果出错都会抛出异常,那么你捕获的到底是哪个呢?其次,没有把功能段合理分开,这段代码的逻辑功能实际上是两个,一个是读,一个是写,那么合并在一起,首先顺序很乱,其次容易让阅读的人产生困惑,从而造成代码可读性差。我是这样做的:
private void writeFile(String fileName, String outStr)
{
Writer writer = null;
try
{
writer = new OutputStreamWriter(new FileOutputStream(fileName),
"utf8");
}
catch (UnsupportedEncodingException e)
{
System.err.println("不支持的编码方式");
e.printStackTrace();
}
catch (FileNotFoundException e)
{
System.err.println("初始化文件失败,或路径不存在:" + fileName);
e.printStackTrace();
}
try
{
writer.write(outStr);
writer.flush();
}
catch (IOException e)
{
System.err.println("写文件失败");
e.printStackTrace();
}
finally
{
try
{
if(writer != null)
writer.close();
}
catch (IOException e)
{
System.err.println("关闭文件失败");
e.printStackTrace();
}
}
}
类似的,也将读的逻辑独立抽出来,虽然,这不但没使代码的量减少,却增加了很多try catch 模块,不过逻辑上很完整,而且发挥了每个try catch 的最佳功效。我把它起名曰,我个人的偏执情节吧。
困了,要睡觉了,本来还想将代码从最初模样,到最后模样的过程复述一遍,改天有机会再说,精华都已经说了。嘿嘿
今天早上打破了原本的计划,对于网上看到的一位小狂人,发表了很多看法。中国IT 这个行业就是这样的,普遍的年轻化,轻狂化,但是真正的大师却少的可怜。看了看自己在豆瓣上的“想读”列表,突然觉得时间大大的不够,心里又激起了一层涟漪,打破了那片平静。不过经过一个小时的深入思考,我又重归了那份平静。
我是赞成中国道家学派的,人只有归于平静,身体和心灵都达到阴阳调和的状态,心情稳定,脾气温和,头脑冷静,做事要循序渐进,才可以稳稳当当,根基牢固。所以我个人并不羡慕暴发户,也不羡慕那些少年得志的人。一个完整的、健全的人,成大事的人,是要体会人生的低潮期的。和命运作斗争的过程,你的思想和心智都会得到历练,正如古人所说“天将降大任于斯人也,必先苦其心志,饿其体肤”,没有经历过失败的人,是很难长久守住你的成功的。就像我上个礼拜读的那本书里写的故事一样,一夜成名者,招致的嫉妒和怨恨太多,不是自己不够优秀,而是环境不允许你优秀,终归无以成大事。所以,做人还是要谦虚谨慎的,扎稳根基,一步一步的来,厚积而薄发。
思考到这一步,心情从浮躁终归于平静了。所以还是应当遵循我的目标,一步步来,时间之与我,的确寸秒寸金,所以我不能把这些时间浪费在对人生太多的感慨中,而应当去努力的寻觅,去体验生活,去做自己该做的事情!不去空叹光阴似箭,也不去妄自菲薄!从现在开始投入到实际的工作中吧!
今天算是在2008年的中国年、圣诞、阳历年新年之前,所以我写这篇blog无论你怎么算,那可是真正意义上的辞旧迎新啊(哈哈,我又有点偏执了)。一个目的,过去的一年是很精彩的,也很开心,我很努力,也收获很多。未来的一年,我要更加好好珍惜我的朋友们,更加努力的面对一切困难和挑战,拥抱2008!
在2007年发生了很多事情,有些可控,有些不可控,但是整体上来讲还是收获远远大于付出的。而我热爱的软件开发行业,也还是处于艺术的那种状况,而且我估计在未来的10到20年仍旧会继续这样的情况,因此我还是可以以艺术家自诩的(哎呦,好臭屁啊!),我也会继续充满热情的投入到这个行业中去。
过去的一年里,值得自豪的事情有(排名不分先后,想到哪写哪的):
1、做事情做的问心无愧,努力做好了每一件事情,认真面对生活的每一个细节
2、在繁重的项目压力下(最多同时负责五个项目,还要带团队OOPS,还要带导师的儿子,555555),依旧能坚持学习从而提高自己
3、体验了一把累病了的滋味,并成功恢复了健康,而且在累病了期间感悟了许多人生,收获颇多。恢复健康后,一直坚持锻炼身体,现在的身体状况一级棒!还胖啦,哇哈哈
4、在年底,顺利的完成了项目的平滑交接,让研二的师弟师妹们成为导师值得信赖的动力,最值得自豪的是我将很多平时钻研的开发软件的技术、思想和经验延承了下去,培养出实验室良好的研发气氛(应用了很多极限编程和敏捷开发的思想哦)。
5、找了一份非常适合自己,非常喜欢,有良好前景的工作
6、完成了6到7个项目,做了两个自己能给85分以上的项目(NASAC 论文评审系统和华秦智能管理系统)
7、深化了Java 语言的运用,可以熟练的使用Spring、Ajax、OSGi等框架和技术,深入研究了敏捷软件开发和项目管理的种种方法,并应用到实际的项目中去。总之是深化了自己最擅长的技术,而又学会了许多新的技术。
8、珍惜了已有的朋友,又新交了许多优秀的新朋友
9、好好孝敬了父母,做了很多父母都为我自豪的事情
10、明确了自己下一步要做的计划(这一条我感觉是在凑数吧,哈哈,圆圆满满吧)
过去一年里有些可惜的事情:
1、感情道路依然坎坷啊,还是没有方向啊,哎~~~~
2、以后要注意身体的,不能再次累病了,切记切记哦
3、研究生阶段有车有房的目标看来是宣告破产啦!
4、没有出去实习一次,的确是有些遗憾的
嗯,开始未来的计划吧:
1、依然要做事认真,注意细节,问心无愧;做一个正直的、善良的、有责任感的男人!
2、坚持锻炼身体,让自己再胖一些吧!
3、认真的、充满热情的投入到TW 的工作中,好好的和同事们相处,多交各种各样的朋友,并努力增加知己的数目
4、努力使自己的感情道路不要再那么坎坷了,慎重慎重!
5、深化自己已掌握的知识包括深化敏捷开发、Spring2.X(包括Spring Web Flow、Spring OSGi 等等)、Ajax(GWT 和CSS,尤其是CSS,一定要做到是真的可以用它来改变自己的风格和布局,而不只是简单的样式而已,master it);新的知识呢,再努力掌握RoR、Python、Erlang和项目风险控制、项目估算的相关知识,学会使用Unix/Linux 操作系统,并坚持下去,深入研究下Android 并努力应用到实际的项目中去;努力使自己的软件架构能力更上一层楼;努力提高自己的代码编写质量,达到90分以上
6、完成自己的BoBoBlog release 1
7、好好的,顺利的在四月份完成毕业(这个不难吧)
8、如果有出国的机会,努力把握之,好好见识一下!
9、让自己的英语能够,看英文书不累,跟看中文书一样;跟老外对话不需思考,听口音重的老外讲话也OK
10、学会做一手好菜,努力让自己的父母更开心快乐
好了,咋想也想不出来啥了,辞旧迎新、辞旧迎新!写此文以表决心!
上周六、日两天参加了公司的Away Day。作为一名还没入职的员工,能有这样的机会融入进去,实在很难得。两天的行程是这样安排的,第一天主要去听一些session,包括技术和非技术的;第二天就是真的away 啦,吃喝玩乐喽。整体感觉很舒心,公司的同事们都很好,很open mind,大部分都很健谈,很乐于帮助你。两天的生活感触多多,交了许多新朋友,也看到了差距和很多新的有趣的东西以供我修正自己前进的方向。
第一天刚进公司,就感觉外国人很多,我觉得公司在中国也就一百多号人,外国人至少占了三分之一吧。来之前就知道,公司的总部加大了对中国部门的投入,鼓励国外优秀员工进入中国帮助中国同事提高他们的项目完成能力,但是真的亲眼见到才觉得挺震撼的。这一天最有感触的是几件事,第一件事情是,刚进公司没多久就被发了一件印有公司名和Away Day 的长袖衫,赶紧穿上。然后所有人都乘电梯下到一楼去参加全体大会了,大会主要是对过去一年的总结,可以说是一个大大的show off 吧,才发现原来中国分公司在过去的一年中做了那么多重大的事情,收到了那么多客户的表扬和赞赏。心里着实的高兴了一把。然后就是Roy 给我们打气啦,说原来他是以麦肯锡为目标的,结果现在是麦肯锡以TW为目标,然后小小透漏了一下公司的秘密,那才真的是最震撼的,这件事情让我真的确信了我们加入了一个全球最好的技术咨询公司。从同事那里听到Roy 是一个极其个性的领军人物,是他决定了四年前公司进行Ruby 相关的实验开发(四年前啊,那是Ruby才出来,真有远见),是他反对公司进行股票上市,是他确定公司的目标为“using IT to make the world better”,还是他以自己的孩子专业是“促进世界和平”而自豪。进公司之前就听说了TW 绝对是非常人性化非常公平的一个公司,每个TWer 都觉得自己的公司是最好的,都很自豪,自己经历一下才发现是真的,因为对中国地区的老大当场就开始投票了,而且是绝对的公开投票,当然结果还是我们的G 大大了,因为他做的的确足够好,后面还有一段和他的故事呢。开会的最后,还有一件值得一提的事情,那就是见到了传说中的TW 第一美女 S,Sun 高层挖过来的,据说Java TW 第一人啊。真的是很漂亮,美丽的英国lady。
这一天值得提起的第二件事情,就是参加的session 了,印象最深的是A (就是面试我那个)讲的Erlang。在来之前,好像在杂志上还是网上略知一二,就是下一代语言么,很支持并行编程的那种,号称是下一代语言中的Java,这个自然是要狠狠的关注一下的。A 在讲的时候,好像也不那么熟悉,后来被问倒了,还真的很不好意思哪,哈哈,不过没什么,大家人都很好。我知道在Java 中同时处理千级别的线程就会出现比较严重的问题了,而且那程序写的可就是相当的难看啦。当天听了Erlang 的session,说是并行度可以轻松达到万以上的级别,而且不会像Java 中出现对具体线程的控制模块。我看到了那些示例程序,很优雅的脚本,从来没有出现诸如synchronized 这些词汇。语言风格有点DSL 的味道,Erlang 也是脚本语言,而且与那些主流语言的风格很不相同,是一种自顶向下,逆推式的风格。熊哥哥给我们当场演示了一个用Erlang 完成的消费者模式的程序,写的的确很清晰。据说公司有一个项目正在做的就是用Erlang,真的是很佩服TW 的先驱思想和执行力度。
晚上吃饭也发生了一件很有趣的事情——看TW 的酒协与来自澳大利亚的C 拼酒还有C 劝老大喝酒。C 是很壮的那种外国人,高大、英俊、强壮,那酒量,那可是相当的相当的......TW 酒协会长,差点就栽在他手里了。下一次一定能和C 合张影,他是给我感觉最好的外国人,很想和他成为朋友,幽默有趣,个性开朗。
晚上回到旅馆和小龙聊了好久,小龙透漏给我一个很有价值的信息,那就是在TW 里,如果你有好的想法,可以做一个session 希望大家和你一起同做,这对我来说可是天大的福音了。呵呵,加油,给自己打打气!
第二天的行程是爬长城和去红螺寺,一天里最有趣的事情莫过于和老大在车上玩杀人了,学会了一句经典对白“现在,我来理性的分析一下”,说的时候要注意脸部表情要认真严肃,声调要低但是要有穿透力和震撼力,不然没老大那效果。这是和老大在整个行程中最亲密的接触了,后来在爬长城的时候,还和老大和熊哥一起合影了。
记成流水帐了,哎,真不好。不过两天行程很紧张,活动密度大,经历的事情都是没经历过的,将就点吧。呵呵。我想我会在公司里好好努力和发展的,因为看到公司里很多人都是我这样的,不仅是喜欢这个行业,更想创造出无限的价值,来让生活更美好,艺术家,艺术家啊(哈哈,自夸了,真的好邪恶啊——这是和NaNa 学到的一句经典对白)。
看了同事的一篇Blog 讲的Uncle Bob 好像是生病了,还要用吗啡。不是真的吧,我可是看他的《敏捷软件开发》才开始喜欢上敏捷软件开发的,真的希望这不是真的,如果是真的,那我在这里祈祷希望他早日康复。
顺便提一下吧,今天看了了Jessie 的Blog 真的很喜欢Thoughtworks,大家让我感觉到那里是很开心的,很开朗,很人性的一个环境。有很多小故事都令我挺感动的,举一个小例子吧,我们在北京的住房都是公司帮我们找好,我们去看的,能做成这样的公司,全中国能有几家?好了,这算是我遇到前所未有的明主了,好好干吧,加油!
人生就是这样,有得有失,不过只要自己一直努力,那么得到的总会比失去多。我很满意啦,很知足啦!
前两天看到一个有趣的观点:早崩溃,不破坏。这个理论给我了许多思考,不只是软件开发上的,更有很多对人生的看法。
这个理论大致是这样的一个意思:当前的软件设计,与其说是科学不如说是艺术,因为并没有一个严格的方法和论断可以定夺一个软件的好坏,也没有一个确定的工业标准(通常很科学化的东西都可以很快的用工业标准来描述)可以指导、确保软件的开发过程不那么随意。正因为如此,当前的软件世界问题多多,而且久违的银弹还是没有出现。那么,在实际开发的过程中,如何开发出一个质量高,又符合要求的系统呢?这就是“早崩溃,不破坏”理论存在的价值了。它是说,项目你可以让它尽早的崩溃,实时的崩溃,以发现问题,从而改正这些Bug,使系统能够暴露问题,尽早的恢复到正常的状态。这就引出了测试要频繁的进行,甚至是使用测试驱动进行开发。当然开发的早期,会陷入比较痛苦的状态,问题多多,不知道如何解决。不过这些都是有好处的,做了这样的工作,确保了发展方向和软件质量的正确性,就使你的系统在最后才不会产生严重的破坏。破坏——disaster 级别的,有时是很难恢复的。所以这么看来,前期的打击会造就后期的轻松与成熟,这何尝不是大大的值得呢?
这个理论看似只是针对软件开发的,却给我了许多额外的思考。生活、工作、爱情等等又何尝不是这样的呢?
生活中,从最小的小孩子呀呀学语,蹒跚学步,多让家长“崩溃”啊,是不是,呵呵(其实我觉得那时候要是自己有意识,也会很崩溃的),可是却造就了他们未来发展的基础;最近要开始学做菜,因为要去北京发展了,这个学习过程也是很崩溃的,不过想想未来,做菜可以带来自己伙食的改善,可以增加自己的技艺,可以让家庭更幸福,可以让父母更开心等等,这个未来的力量还是很强大的。所以,生活实际上也是“早崩溃,不破坏”的。
工作中,你初期进入公司,总有个人生地不熟的过程,总有个和公司文化适应的过程,不是每个人都那么幸运,可以一去就融入环境的。一进公司,要学习很多知识,要学会与同事友好的相处,这些东西别看貌似很小,其实压力会不小的,所以也是很“崩溃”的。但是从长远来看,只要你努力的去做好前面的一切,那么这样的过程会让自己得到很大的提高,会让你的人际关系更加的顺畅,会让你的工作更加的舒心,当然经济价值也会逐渐的体现出来。这就使得你后期的“破坏”的可能性就很低了。看来有时“郁闷”“崩溃”不见得是一件坏事情,关键是你不要迷失,不要认为你的生活会永远如此,要开朗些,阳光些,继续努力下去。
最后就是关于爱情了。我有一些朋友曾经跟我说过他们希望找从来没有谈过恋爱的女孩子或男孩子,这样固然是好,因为单纯,可以给人很纯净的爱情的感觉。但是我个人觉得,如果一些女孩子有过恋爱的经验,至少是曾经很努力的去喜欢过一个人,能成熟的思考一些问题。这对于将来的爱情和婚姻是很大很大的一笔财富(当然爱看书的女孩子除外,因为她们可以从书中体验人生,使自己思想成熟起来)。先前的爱情失败的确会让一个人很“崩溃”的,爱情失败无所谓对错,两个人不可能一方全对,另一方全错。两人皆有不对的地方,皆有处理不当的事情,只是多少而已。失败的爱情双方都是输家,没有人是赢家。不过这样的“崩溃”是有好处的,它会引起你的反思,会让你思考自己的错误,从而为下一次感情做好准备。当然,“崩溃”的原因,也可能是真的不合适,那么你就更要好好总结一下,从而为下一个合适的做好准备。关键是,不要让“崩溃”麻痹了你,丧失了去追寻真爱的勇气,这是最最主要的!“崩溃”不是“破坏”,关键是看你怎么处理,怎么对待。只要结局不是“破坏”,那么前期的“崩溃”均是有很大的价值的!
归根到底还是,要有勇气,要能耐得住压力和寂寞,不要为社会和生活的繁杂丧失那颗珍贵的心,在那最艰难的时刻,听听你自己的心是怎么说的,坚强下去,你可以的。
傻傻的想,傻傻的揣摩,随便写写,从软件谈到人生,供大家思考。
When asked "Do you write tests?", a lot of developers these days will
say "of course" as their answers. However, not everyone can admit to
doing TDD (Test Driven Development) correctly. Test Driven Development
says, a developer will write a test that fails first, then write code
to make the test pass, and refactor when possible, and repeat. This is
what most people's TDD rhythm is. For the most part this is fairly easy
to do. But to reach the next level, one has to understand TDD as a
tool: TDD means more than just test your own code. Here is a couple
tips on what the last "D" means:
Discipline
It
takes a great deal of discipline to even write a failing test before
writing the actual code. Sometimes, we write a little seudo-code here,
or move a method definition there, or changing code else where trying
to see if more new code needs to be written after it, and sooner than
you think you are writing the actual implementation of the methods you
wanted to test (Test Afterwards Development anyone?). Other times you
write the test, but you are too anxious to even run it and see it
fails. And other times you want to jump into the actual code
immediately when you see your new test fails, but failing for the
unexpected reasons.
Don't fall into these traps. If anything is true, testing is hard, but it is at the same time rewarding and fun. What's also true is, it will pay off.
Write the failing test, draw up your list of tests you will need to
write, and satisfy them one by one. Having discipline is the
cornerstone of becoming a better programmer.
Design
It
takes too long to write a test? Tests are running too slowly? Are your
tests difficult to read? Are they too brittle and fail all the time?
Hang in there! You ever had the feeling you saw code in the codebase
that irks the living hell out of your mind written by someone else on
your team? Well, it is time for you to get some of these feedback about
your own code. Yay, your code sucks! Your tests
are telling you that! Let's address each of these one by one.
Slow
running tests? You shouldn't be hitting a database or web service in
your unit tests, because you can mock/stub them out. Difficult to
mock/stub it out? There probably is a better way to design your classes
your tests are hitting. Ever heard of Inversion of Control (or
Dependency Injection)? Master them. True TDD masters use them
extensively.
Unreadable tests? Is it because of too many
mocks/stubs? Or is it the code is 500 lines long and doing high octane
720-double-backflip logic? Either way, you have to learn to like small
objects. Check this
blog post of mine out.
Hard
to test something? Tests too brittle? Perhaps you have encapsulation
issues in your class design. If your classes are referencing 15 other
neighbors, of course they are hard to mock/stub. Chances are, you have
to spend time to debug your tests to find out what's wrong! Heard of
Law of Demeter? Even if you have, take a look at this
highly entertaining yet informative post. It might change your perspective a little.
The
bottom line is, TDD is a way to guide you to writing good code, but
only if you know how to use it as a tool. Now that you know, hopefully
you will have a new perspective next time you write a test.