JUNIT源碼探秘(七):Junit代碼分析之裝飾模式
在Junit實(shí)現(xiàn)中,對(duì)于大部分測(cè)試代碼的執(zhí)行都是按照前文分析的執(zhí)行過(guò)程,但同時(shí)在Junit中也提供對(duì)一個(gè)測(cè)試方法重復(fù)執(zhí)行多次能力。而重復(fù)執(zhí)行的過(guò)程中實(shí)際上他是把執(zhí)行過(guò)程給分解成若干個(gè)相同的測(cè)試過(guò)程,也是說(shuō)他的執(zhí)行本質(zhì)還是和單個(gè)測(cè)試方法的執(zhí)行是一樣的。直接使用Juint源碼來(lái)說(shuō)吧,Junit真正調(diào)用執(zhí)行Junit測(cè)試代碼是在TestCase這個(gè)類中;對(duì)于要重復(fù)多次執(zhí)行一個(gè)測(cè)試方法時(shí),則過(guò)繼承Test的另一個(gè)接口類TestDecorator的實(shí)現(xiàn)類之一RepeatedTest來(lái)執(zhí)行。而這完全是有個(gè)裝飾模式。由其可以看出代理模式有以下幾個(gè)角色
抽象構(gòu)建角色(Component):給出一個(gè)抽象的接口,以規(guī)范準(zhǔn)備接受附加責(zé)任的對(duì)象。相當(dāng)于Junit源碼中的Test。
具體的構(gòu)建角色(ConcreteComponent):定義一個(gè)將要接受附加責(zé)任的類。相當(dāng)于Junit源碼中的TestCase。
裝飾角色(Docorator):持有一個(gè)抽象構(gòu)建(Component)角色的引用,并定義一個(gè)與抽象構(gòu)件一致的接口。相當(dāng)于Junit源碼中的TestDecorator。
具體的裝飾角色(ConcreteDecorator):負(fù)責(zé)給構(gòu)建對(duì)象“貼上”附加的責(zé)任。相當(dāng)于Junit源碼中RepeatedTest類;
當(dāng)然,如果Junit有其他功能需要擴(kuò)展時(shí),可以繼續(xù)對(duì)裝飾角色繼續(xù)持續(xù)實(shí)現(xiàn)。由此可以看出裝飾模式是動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé),也是在不必改變?cè)愇募褪褂美^承的情況下,動(dòng)態(tài)的擴(kuò)展一個(gè)對(duì)象的功能。它是通過(guò)創(chuàng)建一個(gè)包裝對(duì)象,也是裝飾來(lái)包裹真實(shí)的對(duì)象。增加功能來(lái)說(shuō),Decorator模式相比生成子類更為靈活。
利用Junit源碼中的類的關(guān)系圖大家可以繼續(xù)看下裝飾模式的關(guān)系
為了更明白的說(shuō)明裝飾模式,可以繼續(xù)看下裝飾模式各個(gè)角色的實(shí)現(xiàn)代碼(為了易于理解裝飾模式,在這塊實(shí)現(xiàn)代碼用一個(gè)簡(jiǎn)單的例子說(shuō)明):
抽象構(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):
實(shí)現(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");
}
}
實(shí)現(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");
}
}
在具體的裝飾角色中實(shí)現(xiàn)了兩個(gè)具體的類,而此處正是裝飾模式大的好處,裝飾模式擴(kuò)展的是對(duì)象的功能,不需要增加類的數(shù)量,而類繼承擴(kuò)展是類的功能,在繼承的關(guān)系中,如果我們想增加一個(gè)對(duì)象的功能,我們只能通過(guò)繼承關(guān)系,在子類中增加一個(gè)方法。
關(guān)于Junit使用裝飾模式的代碼,再次不再詳細(xì)分析,有興趣的同學(xué)可以根據(jù)上面的類圖具體查看