装饰模式(Decorate)
如果你知道静态代理的话,那么理解装饰模式就不会很难,其本质目的都是在原有功能基础上增加新功能;有人说用继承不就可以了吗?继承的话,每增加一个新功能点就要实现一个类,这样的结果会导致子类数量无限增加,这种场景我们使用装饰模式。
复杂的概念就不说了,直接定义,目标类与装饰类都要实现同一个接口,同时在装饰类中要持有目标类的引用;那么实际增加附加职责的类就必须继承装饰类。这个定义里面涉及到几个概念,目标类,装饰类,共同接口以及附加职责类。那么在Junit中,这种关系见下图:
目标类:TestCase
装饰类:TestDecorator
共同接口:Test
附加职责类:Repeated Test 和 TestSetup
下面看源码,在junit的extensions包中,定义了装饰器类TestDecorator,并且其中持有了TestCase的引用;
/**
* A Decorator for Tests. Use TestDecorator as the base class
* for defining new test decorators. Test decorator subclasses
* can be introduced to add behaviour before or after a test
* is run.
*
*/
public class TestDecorator extends Assert implements Test {
//持有目标类的引用
protected Test fTest;
public TestDecorator(Test test) {
//通过构造方法将目标类传递进来
fTest= test;
}
/**
* The basic run behaviour.
*/
public void basicRun(TestResult result) {
fTest.run(result);
}
public int countTestCases() {
return fTest.countTestCases();
}
//实现接口方法由目标类来完成
public void run(TestResult result) {
basicRun(result);
}
public String toString() {
return fTest.toString();
}
public Test getTest() {
return fTest;
}
}
需要扩展测试用例功能时,继承装饰器即可,我们看Junit中实现的扩展实例代码;
/**
* A Decorator that runs a test repeatedly.
*
*/
public class RepeatedTest extends TestDecorator {
private int fTimesRepeat;
//通过构造方法将test目标类传递进去
public RepeatedTest(Test test, int repeat) {
super(test);
if (repeat < 0)
throw new IllegalArgumentException("Repetition count must be > 0");
fTimesRepeat= repeat;
}
public int countTestCases() {
return super.countTestCases()*fTimesRepeat;
}
//在实现接口方法时,添加附加逻辑,这里是重复执行测试
public void run(TestResult result) {
for (int i= 0; i < fTimesRepeat; i++) {
if (result.shouldStop())
break;
super.run(result);
}
}
public String toString() {
return super.toString()+"(repeated)";
}
}
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于