composite合成模式可以使用户对象以同样的方式对待单独的对象或复合的对象,合成模式要设计一个公共接口,即可提供给单独的对象使用,也可以供给复合对象使用。
使得用户类一致地使用单独的对象或者复合的对象,也不必关系要如何处理复合对象,只需要向复合对象添加单独对象即可。
junit的Test接口的两个子类TestCase和TestSuite就是使用了合成模式。
其部分关键源代码如下,合成模式的代码结构基本上跟下面代码一样:
package junit.framework;
/** * A <em>Test</em> can be run and collect its results. * * @see TestResult
*/
public interface Test {
/**
* Counts the number of test cases that will be run by this test.
*/
public abstract int countTestCases();
/**
* Runs a test and collects its result in a TestResult instance.
*/
public abstract void run(TestResult result);
}
package junit.framework;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public abstract class TestCase extends Assert implements Test {
/*......*/
public int countTestCases() {
return 1;
}
public TestResult run() {
TestResult result= createResult();
run(result);
return result;
}
/**
* Runs the test case and collects the results in TestResult.
*/
public void run(TestResult result) {
result.run(this);
}
/*......*/
}
package junit.framework;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;
public class TestSuite implements Test {
/*......*/
private Vector<Test> fTests= new Vector<Test>(10);
/**
* Adds a test to the suite.
*/
public void addTest(Test test) {
fTests.add(test);
}
/**
* Adds the tests from the given class to the suite
*/
public void addTestSuite(Class<? extends TestCase> testClass) {
addTest(new TestSuite(testClass));
}
/**
* Counts the number of test cases that will be run by this test.
*/
public int countTestCases() {
int count= 0;
for (Test each : fTests)
count+= each.countTestCases();
return count;
}
/**
* Runs the tests and collects their result in a TestResult.
*/
public void run(TestResult result) {
for (Test each : fTests) {
if (result.shouldStop() )
break;
runTest(each, result);
}
}
public void runTest(Test test, TestResult result) {
test.run(result);
}
/*......*/
}
要一起执行若干个TestCase只要向TestSuit的addTest添加,和TestCast一样执行run即可。