接著我們看下Junit中觀察者的實(shí)現(xiàn)類是如何實(shí)現(xiàn)接口類,在swt、swing的UI方式和控制臺(tái)方式這三種運(yùn)行模式中都對(duì)其觀察者接口的具體實(shí)現(xiàn)。在這以testui運(yùn)行模式調(diào)用為例。在testui模式中,TestRunner繼承BaseTestRunner而這段代碼在BaseTestRunner實(shí)現(xiàn)如下:
public synchronized void endTest(Test test) {
testEnded(test.toString());
}
public synchronized void addError(final Test test, final Throwable t) {
testFailed(TestRunListener.STATUS_ERROR, test, t);
}
public synchronized void addFailure(final Test test, final AssertionFailedError t) {
testFailed(TestRunListener.STATUS_FAILURE, test, t);
}
另外在testui中的ResultPrinter也實(shí)現(xiàn)了對(duì)TestListener的實(shí)現(xiàn),具體如下:
public void addError(Test test, Throwable t) {
getWriter().print("E");
}
public void addFailure(Test test, AssertionFailedError t) {
getWriter().print("F");
}
public void endTest(Test test) {
}
public void startTest(Test test) {
getWriter().print(".");
if (fColumn++ >= 40) {
getWriter().println();
fColumn= 0;
}
}
Junit中的說被觀察者是TestResult對(duì)象,它有添加觀察者的方法:
public synchronized voidaddListener(TestListener listener) {
fListeners.addElement(listener);
}
在Junit中被觀察者是如何通知觀察者呢?請(qǐng)看這幾個(gè)方法,在TestResult中下面幾個(gè)方法都是循環(huán)遍歷觀察者列表,并調(diào)用相應(yīng)的更新方法:
public synchronized void addError(Test test, Throwable t) {
fErrors.addElement(new TestFailure(test, t));
for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
((TestListener)e.nextElement()).addError(test, t);
}
}
public synchronized void addFailure(Test test, AssertionFailedError t) {
fFailures.addElement(new TestFailure(test, t));
for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
((TestListener)e.nextElement()).addFailure(test, t);
}
}
public synchronized voidaddListener(TestListener listener) {
fListeners.addElement(listener);
}
public synchronized voidremoveListener(TestListener listener) {
fListeners.removeElement(listener);
}
private synchronized Vector cloneListeners() {
return (Vector)fListeners.clone();
}
在Junit中使用觀察者模式帶來的好處:
1)上面提到的Subject與Observer的抽象耦合,使JUnit可以支持不同的使用方式,為Junit執(zhí)行平臺(tái)(如textui、awtextui等)的擴(kuò)展非常容易
2)支持了廣播通信,目標(biāo)對(duì)象不關(guān)心有多少對(duì)象對(duì)自己注冊(cè),它只是通知注冊(cè)的觀察者