JUNIT源碼探秘(七):Junit代碼分析之裝飾模式
在Junit實現(xiàn)中,對于大部分測試代碼的執(zhí)行都是按照前文分析的執(zhí)行過程,但同時在Junit中也提供對一個測試方法重復(fù)執(zhí)行多次能力。而重復(fù)執(zhí)行的過程中實際上他是把執(zhí)行過程給分解成若干個相同的測試過程,也是說他的執(zhí)行本質(zhì)還是和單個測試方法的執(zhí)行是一樣的。直接使用Juint源碼來說吧,Junit真正調(diào)用執(zhí)行Junit測試代碼是在TestCase這個類中;對于要重復(fù)多次執(zhí)行一個測試方法時,則過繼承Test的另一個接口類TestDecorator的實現(xiàn)類之一RepeatedTest來執(zhí)行。而這完全是有個裝飾模式。由其可以看出代理模式有以下幾個角色
抽象構(gòu)建角色(Component):給出一個抽象的接口,以規(guī)范準備接受附加責(zé)任的對象。相當于Junit源碼中的Test。
具體的構(gòu)建角色(ConcreteComponent):定義一個將要接受附加責(zé)任的類。相當于Junit源碼中的TestCase。
裝飾角色(Docorator):持有一個抽象構(gòu)建(Component)角色的引用,并定義一個與抽象構(gòu)件一致的接口。相當于Junit源碼中的TestDecorator。
具體的裝飾角色(ConcreteDecorator):負責(zé)給構(gòu)建對象“貼上”附加的責(zé)任。相當于Junit源碼中RepeatedTest類;
當然,如果Junit有其他功能需要擴展時,可以繼續(xù)對裝飾角色繼續(xù)持續(xù)實現(xiàn)。由此可以看出裝飾模式是動態(tài)地給一個對象添加一些額外的職責(zé),也是在不必改變原類文件和使用繼承的情況下,動態(tài)的擴展一個對象的功能。它是通過創(chuàng)建一個包裝對象,也是裝飾來包裹真實的對象。增加功能來說,Decorator模式相比生成子類更為靈活。
利用Junit源碼中的類的關(guān)系圖大家可以繼續(xù)看下裝飾模式的關(guān)系
為了更明白的說明裝飾模式,可以繼續(xù)看下裝飾模式各個角色的實現(xiàn)代碼(為了易于理解裝飾模式,在這塊實現(xiàn)代碼用一個簡單的例子說明):
抽象構(gòu)建角色(Component):
package com.wonew.mode;
public interface Component {
publicvoiddoSomething();
}
具體的構(gòu)建角色(ConcreteComponent):
package com.wonew.mode;
public class ConcreteComponent implementsComponent{
publicvoiddoSomething(){
System.out.println("功能A……");
}
}
裝飾角色(Docorator):
package com.wonew.mode;
public class Decorate implements Component{
privateComponent component;
publicDecorate(Component component) {
this.component = component;
}
publicvoiddoSomething() {
component.doSomething();
}
}
具體的裝飾角色(ConcreteDecorator):
實現(xiàn)一:
package com.wonew.mode;
public class ConcreteDecorate1 extends Decorate
{
publicConcreteDecorate1(Component component)
{
super(component);
}
publicvoiddoSomething()
{
super.doSomething();
this.doAnotherDosomething();
}
privatevoiddoAnotherDosomething()
{
System.out.println("功能B");
}
}
實現(xiàn)二:
package com.wonew.mode;
public class ConcreteDecorate2 extends Decorate
{
publicConcreteDecorate2(Component component)
{
super(component);
}
publicvoiddoSomething()
super.doSomething();
this.doAnotherDosomething();
}
privatevoiddoAnotherDosomething()
{
System.out.println("功能C");
}
}
在具體的裝飾角色中實現(xiàn)了兩個具體的類,而此處正是裝飾模式大的好處,裝飾模式擴展的是對象的功能,不需要增加類的數(shù)量,而類繼承擴展是類的功能,在繼承的關(guān)系中,如果我們想增加一個對象的功能,我們只能通過繼承關(guān)系,在子類中增加一個方法。
關(guān)于Junit使用裝飾模式的代碼,再次不再詳細分析,有興趣的同學(xué)可以根據(jù)上面的類圖具體查看