装饰模式(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)"; }
}
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于