Month: July 2009

COBRA

COBRA, or the Consolidated Omnibus Budget Reconciliation Act, was passed in 1986. COBRA contains health benefit provisions that protect one’s group health insurance coverage when employment is terminated or when one loses his or her coverage for another reason. Other reasons may include divorce from a covered employee, death of a covered employee, or when …

COBRA Read More »

Jester的独特之处

Jester是一款用来检查测试覆盖性的工具,它与其它类似工具的不同之处在于:其它测试工具的检测指标是每行被测代码是否被执行,而Jester则是通过一种奇怪的模式:改变一下被测代码的逻辑,执行一下测试用例,如果仍能全部通过,则表示测试有遗漏。 这种逻辑很古怪,但仔细想想就会发现它的合理之处,本文就不提了。 但是这种逻辑比起传统逻辑,即检测每行被测代码是否被执行的逻辑,到底强在哪里呢?一般来说,如果每行代码都被执行到了,那测试自然就完备了。 我被这个问题几乎搞得睡不着觉。由于智商太低,数理逻辑也不扎实,怎么想也想不出来。就当我要放弃的时候,灵感终于来了,我终于明白: 传统工具虽然可以找到未被测试的代码,但未必能找到未被测试的程序逻辑;为什么呢?因为有的逻辑是隐式的,而不是通过代码显式声明的。 举一个例子就能说明这个问题: 测试用例: List resultList = ….; testee.do(3,resultList); assertTrue(resultList.size() == 1) 被测代码: //Testee public void do(int index,Collection resultList){ if(index >= 3){ resultList.add(new Object()); } } 被测代码只有一个If/Then逻辑。如果用传统检测工具来检查,那覆盖率肯定是100%,一切都很好。 但用jester来检查,jester就会报错。因为把  if(index >= 3) 变成  if(true || (index >= 3))后,测试用例仍然可以绿色通过。 这是为什么? 因为jester期望测试用例能够考虑到 index < 3的情况。只有考虑到了index < 3的情况,在 if(index >= 3) 变成  if(true || (index >= …

Jester的独特之处 Read More »

[TDD] About Jester?

Go to http://www.ibm.com/developerworks/library/j-jester/ 一句话概括:Jester changes the source code, recompiles it, and runs the test suite to see if anything breaks 今天试玩了一下,我觉得它功能很强大很有意义,但是可用性太差了! 具体原因我以后再说!

[TDD]如何提高单元测试的质量

这里的质量,指的是功能点的覆盖性。 Kent Beck说有两种基本方法:    1.写更多的测试代码,最大可能穷尽所有的输入组合    2.或者把代码写得尽量简单,代码简单了IF/ELSE就少了,需要的测试用例也就少了。 他还推荐了一个工具用于检测测试代码的覆盖性: Jester

奇妙的Visitor模式: 从树遍历说起

   最近在项目中反复使用了Visitor模式,觉得它真的很奇妙。    很多人用Visitor模式可能都和我一样,初衷是为了遍历一棵树,但其实在“树遍历”市场上还有其它方案可以选择,这些方案可能还更简单。那为什么还要用Visitor模式?难道它的方案更优?如果更优,它的优点有更高的意义?    我的答案是: Visitor是高性能高价格的方案,而且它的优点是“Sepration of Concern”。因为这个优点,它不但可用于树遍历,还可在任何需要多态的场合,提供比“子类直接实现”更低的耦合。    1.Visitor 可用于树遍历,visitorFather(), visitorSon()什么的,这没什么可说的。    2.其实不用Visitor也可以实现树遍历,而且还更直观。让Father和Son都实现一个visitTree()方法,Father.visitTree()在visit自己之后再调用所有Son的visitTree()方法,这种方案更符合直觉,而且不需要引入新类,比Visitor模式更简单。我们不妨把这种方案称作 直觉模式。    3. 那为什么说Visitor更优?        a. 直觉模式的算法是死的,而Visitor模式的算法不是。虽然 Father.visitTree() 跟 Son.visitTree() 的实现可以不一样,但是算法是死的,只能先序遍历,并且不能跳过节点。Visitor类可以任意组合自己的visitXXX()方法和决定这些方法的调用顺序,想先序就先序,想广度优先就广度优选,想跳过节点就跳过节点。        b. 直觉模式不方便处理与各节点无关的操作,而Visitor模式可以。比如要在访问Father和访问Son之间打印N个空格,用直觉模式就不好做:这个倒底算Father的职责还是Son的职责?用Visitor模式就没有这个问题,因为Visitor本身是肮脏的,你尽可以往里面塞入各种操作。而且Visitor类还可以设定一些成员变量作为上下文,为树遍历提供必要的背景信息。        c. 最关键的一点,直觉模式只能有一种遍历操作,而Visitor模式可以有多种,并且它们可以互不干涉地同时运行。这是因为Father.visitTree()只能写一个,运行时只能执行这一个方法;而一套Visitor可以有多个Visitor子类,各个子类可以同时实例化,同时运行。        d. 把这个结论推而广之,可以发现任何多态的场合都可以用Visitor模式。要实现多态,一般是让各子类分别实现指定的抽象方法;但就像前面说的,这种方法只能写一个; 在直觉模式中,父类被多态掉了,而子类却是死的。而在Visitor模式中,由于我们可以在运行时动态选择,以致于子类也多态掉了!        e. 再深入一步,我们可以发现直觉模式只在实现某种特定契约时使用了多态,契约本身是固定的;而Visitor模式却对契约本身也进行了抽象。比如说在直觉模式中,大家可以有“买菜”这种契约,可以有“去银行”这种契约,契约的种类是具体的,虽然Father.买菜()和Son.买菜()时的还价方式不同;而在Visitor模式中,大家只有一种契约,即“做”,“做”本身是抽象的,直到我们创建“买菜Visitor”,“去银行Visitor”时,这个契约才被具体化。这就是更高层次的“Separation of Concern”,对不对?     4. 最后,说一下Visitor模式的高代价(如果你还有耐心继续看)         a.不直观,很古怪的一种思维方式。并且Visitor与Visitable要频繁互调,别人跟你的代码时会很费劲。         b.要新加一个Visitor接口和N个具体类,并且这个接口要定义对所有“被访问类”的访问方法,这很麻烦         c.虽然可以引入Context作为Visitor的成员变量,但这个Context只是全局的。如果要在访问Son时拿到Father的相关信息,用Visitor模式就远远不如直觉模式好用。我的做法是为每个visitor方法都引入一个subContext参数,把父结点的信息保存在里面,再调用子结点的visitor方法。这是一种弱类型的方案,使用时要小心

[TDD] 为什么要测一点,改一点;改一点,测一点

为什么不多改一些代码再测?这样效率不会更高吗? 因为代码写多了再测,就会遗漏一些测试点。比如说测试一个“圆”,你只能在圆孤上选择测试点;而这个圆其实是由两个半圆组成的(就像今天的日偏食),你本来还应该分别测试这两个半圆的边! 那我们的测试粒度倒底要小到什么地步?Kent Beck说,看感觉。他用一句很口语化的话来概括:"Are the teeny-tiny steps feeling restrictive? Take bigger steps; Are you feeling a little unsure? Take Smaller steps".

[TDD] Triangulation

1. This is not Triangulation public void testMultiplication(){ Assert.assertEquals(new Dollar(3).times(2),6 ); } public int times(int i) { return 6; } 2. This is Triangulation public void testMultiplication(){ Assert.assertEquals(new Dollar(3).times(2),6 ); Assert.assertEquals(new Dollar(4).times(3),12 ); } public int times(int i) { return amount * i; } 3.A Triangle? Yes //test Assert.assertEquals(new Dollar(3).times(2),6 ); //1 Assert.assertEquals(new Dollar(4).times(3),12 ); …

[TDD] Triangulation Read More »

[TDD] Overview

I’ve been reading this book of TDD, written by Kent Beck Overview   1.Goal: Clean Code that Works   2.Benefit: Manage fear during Programming   3.Three Steps:       a. Write a test case in advance of writing code. Of course it won’t work, so it’s RED       b. Try your best to make your test …

[TDD] Overview Read More »

我所能理解的SOA的好处

SOA的好处有很多种,我绝不否认。但以我的阅历,能体会的只有以下几种。     1. SOA的优点即分布式计算的优点        a. 解决信息孤岛问题,最大限度地利用现存系统        b. 业务层的复用,重用更好,冗余更少        c. 可重用性强,那么添加新功能就快        d. 冗余少,那么可维护性就好,适应需求变化的能力也就强        e. 相比于传统的分布式系统,SOA还提倡采用标准化的互操作性接口,并主张采用更大的业务组件粒度,这是它最大的创新之处。   2.从程序员的角度看, SOA导致了分而治之的开发模式,提高了软件活动的敏捷性。由于一个系统被拆散成多个相对独立的子系统,开发/测试/部署/项目管理/组织管理 的对象都变小很多,应付起来也更容易。比如说,以前开发时要打一个巨大的EAR包,部署一次要10分钟,现在拆散了,1分钟就可以部好了。

SOA的一些术语

先记下来,以后再研究   1.SLA, Sevice Level Agreement   2.Java Business Integration (JBI)   3.EIP, Enterprise Integeration Patterns