`
luogankun
  • 浏览: 19438 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

junit设计模式分析五(观察者模式)

阅读更多

问题
如果测试总是能够正确运行,那么我们将没有必要编写它们。只有当测试失败时测试才是有意义的,尤其是当我们没有预期到它们会失败的时候。更有甚者,测试能够以我们所预期的方式失败。JUnit区分了失败(failures)和错误(errors)。失败的可能性是可预期的,
Junit 中的设计模式
并且以使用断言(assertion)来进行检查。而错误则是不可预期的问题,如ArrayIndexOutOfBoundsException。因此我们必须进行报告测试的进行状况,或者打印到控制台,或者是文件,或者GUI界面,甚至同时需要输出到多种介质。如JUnit提供了三种方式如Text,AWT,Swing这三种运行方式,并且JUnit需要提供方便的扩展接口,这样就存在对象间的依赖关系,当测试进行时的状态发生时(TestCase的执行有错误或者失败等),所有依赖这些状态的对象必须自动更新,但是JUnit又不希望为了维护一致性而使各个类紧密耦合,因为这样会降低它们的重用性,怎样解却这个问题?

 

 

模式的选择
同样需要思考设计模式的适用性,Observer(观察者)模式便是第一个要考虑的。Observer观察者模式是行为模式,又叫做发布-订阅(Publish-Subscribe)模式,模型-视图(Model/View)模式,源-监听器(Source/Listener)模式。具有以下意图“定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新”。这听起来非常适合需求。在JUnit测试用例时,测试信息一旦发生改变,如发生错误或者失败,结束测试等,各种输出就要有相应的更新,如文本输出就要在控制台打印信息,GUI则在图形中标记错误信息等。

 

 

Observer(观察者)模式的构成

1、Subject 提供注册和删除观察者对象的方法,可以保存多个观察者
2、 ConcreteSubject 当它的状态发生改变时,向它的各个观察者发出通知
3、 Observer 定义那些目标发生改变时需要获得通知的对象一个更新接口
4、 ConcreteObserver 实现更新接口

 

Observer模式的代码实现:

Subject:

public interface Subject {
	public void addObserver(Observer observer);
	public void removeObserver(Observer observer);
	public List<Observer> getAll();
	public void notifyAllObservers();
}

 

ConcreteSubject:

public class ConcreteSubject implements Subject {
	
	private List<Observer> list = new ArrayList<Observer>();

	public void addObserver(Observer observer) {
		list.add(observer);
	}

	public List<Observer> getAll() {
		return list;
	}

	public void notifyAllObservers() {
		for (Observer observer : list) {
			observer.update();
		}
	}

	public void removeObserver(Observer observer) {
		list.remove(observer);
	}
}

 

Observer:

public interface Observer {
	public void update();
}

 

ConcreteObserver:

public class ConcreteObserver implements Observer {
	public void update() {
		System.out.println("update");
	}
}

 

Client:

public class Client {
	public static void main(String[] args) {
		Observer o1 = new ConcreteObserver();
		Observer o2 = new ConcreteObserver();
		
		Subject subject = new ConcreteSubject();
		subject.addObserver(o1);
		subject.addObserver(o2);
		
		subject.notifyAllObservers();
	}
}

 

 

junit3.8源码的实现:
首先定义Observer观察者的就是TestListener,它是一个接口,定义了几个方法,说明它监听的几个方法。如测试开始,发生失败,发生错误,测试结束等监听事件的时间点。由具体的类来实现。

// A Listener for test progress
public interface TestListener {

	// An error occurred.
	public void addError(Test test, Throwable t);

	// A failure occurred.
	public void addFailure(Test test, AssertionFailedError t);

	// A test started.
	public void startTest(Test test);

	//A test ended.
	public void endTest(Test test);
}

 

在JUnit里有三种方式来实现TestListener,如TextUI,AWTUi,SwingUI并且很容易使开发人员进行扩展,只需实现TestListener即可。下面看在TextUi方式是如何实现的,它由一个类ResultPrinter实现

 

public class ResultPrinter implements TestListener {
	PrintStream fWriter; * A test ended.
		public PrintStream getWriter() {
		return fWriter;
	}

	public void startTest(Test test) {
	getWriter().print(".");
		}

	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) {
	}
}

 在JUnit中使用TestResult来收集测试的结果,它使用Collecting Parameter(收集参数)设计模式(The Smalltalk Best Practice Patterns中有介绍),它实际是ConcreteSubject,在JUnit中Subject和ConcreteSubject是同一个类,我们看它的实现

public class TestResult extends Object {
	//使用Vector来保存,事件的监听者
	protected Vector fListeners = new Vector();

	// Registers a TestListener
	public synchronized void addListener(TestListener listener) {
		fListeners.addElement(listener);
	}

	//Unregisters a TestListener
	public synchronized void removeListener(TestListener listener) {
		fListeners.removeElement(listener);
	}

	//Informs the result that a test will be started.
	public void startTest(Test test) {
		for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
			((TestListener)e.nextElement()).startTest(test);
		}
	}

	//Adds an error to the list of errors. The passed in exception
	//caused the error.
	public synchronized void addError(Test test, Throwable t) {
		for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
			((TestListener)e.nextElement()).addError(test, t);
		}
	}
	
	//以下省略了addFailure和endTest代码
}

 效果
我们来考虑经过使用Observer模式后给系统的架构带来了那些效果:
1、Subject和Observer之间地抽象耦合一个TestResult所知道的仅仅是它有一系列的观察者,每个观察者都实现TestListener接口,TestResult不必知道任何观察者属于哪一个具体的实现类,这样使TestResult和观察者之间的耦合是抽象的和最小的。
2、支持广播通信被观察者TestResult会向所有的登记过的观察者如ResultPrinter发出通知。这样不像通常的请求,通知的发送不需指定它的接收者,目标对象并不关心到底有多少对象对自己感兴趣,它唯一的职责就是通知它的观察者。

 

分享到:
评论

相关推荐

    Junit设计模式分析

    《Junit设计模式分析》这本书深入探讨了如何在单元测试框架Junit中巧妙地应用设计模式,以提高代码的可测试性和可维护性。在软件开发过程中,设计模式是解决常见问题的最佳实践,它们能够帮助开发者创建灵活、可扩展...

    JUnit设计模式分析

    总之,JUnit的设计模式分析展示了如何将经典设计模式融入实际项目中,以达到简化代码、增强可维护性和提高代码复用性的目的。理解这些模式及其在JUnit中的应用,对于提升Java测试能力及软件开发实践具有重要意义。

    Junit设计模式分析(带源码)

    本资源"Junit设计模式分析(带源码)"旨在深入探讨JUnit在设计上的模式和最佳实践,通过源码分析帮助开发者更好地理解和应用这个工具。 1. 单元测试基础: 单元测试是对软件中的最小可测试单元进行检查,如函数、...

    Junit设计模式分析.rar

    《JUnit设计模式分析》 JUnit,作为Java编程领域中最广泛使用的单元测试框架,它的重要性不言而喻。在软件开发过程中,单元测试是确保代码质量、可维护性和可扩展性的重要手段。本分析将深入探讨JUnit的设计模式,...

    Junit设计模式分析.pdf

    以下是一些在JUnit中常见的设计模式: 1. 工厂模式:JUnit通过TestSuite类实现了工厂模式,它可以根据测试类动态创建测试集合。这使得用户可以方便地组合不同的测试类进行批量执行。 2. 单例模式:JUnit的Test...

    JUnit设计模式分析及简化的JUnit代码

    观察者模式在JUnit中也得到了广泛应用,比如`TestWatcher`,它监听测试的生命周期事件,如测试开始、结束、失败或成功。开发者可以通过扩展这个类来定制测试事件的通知行为。 此外,JUnit还利用了装饰者模式,例如...

    JUnit的框架设计及其使用的设计模式

    5. **观察者模式**:JUnit实现了Observer设计模式,通过TestListener接口通知测试事件,如测试开始、结束、失败等,使得外部系统可以监听测试过程并做出相应反应。 6. **模板方法模式**:JUnit的TestWatcher是一个...

    Junit设计模式应用

    《Junit设计模式应用》是基于作者业余时间的翻译成果,旨在通过设计模式的角度深入剖析JUnit的内在原理,以此促进读者对单元测试框架理解和运用能力的提升。设计模式是软件工程中的宝贵经验总结,它为解决常见问题...

    一个参考Junit的设计模式ppt

    JUnit的架构设计遵循了简单而高效的原则,同时采用了多种设计模式,如工厂模式用于创建测试实例,单例模式用于全局唯一的测试运行器,观察者模式用于事件通知等。这些模式的运用使得JUnit具有高度的可扩展性和可维护...

    junit源码以及牵涉到的设计模式

    ### JUnit源码及其涉及的设计模式 #### 一、引言 JUnit作为一款广泛应用于Java项目的单元测试框架,其设计理念和实现方式对于软件开发者来说具有很高的学习价值。本文将深入探讨JUnit源码,并重点关注其中使用的...

    设计模式 观察者 发布/订阅 Observer

    当一个对象的改变同时会影响其他对象的行为的时候,可以使用此设计模式。 l 主题对象 :一个需要被关注的主题对象,这个主题对象改变会影响其他对象的行为 l 订阅对象:当主题对象发生改变,订阅对象需要相应处理...

    使用JUNIT框架实现的设计模式验证演示代码

    3. 观察者模式:验证观察者是否能正确订阅和接收主题发布的事件,同时检查解订阅功能是否正常。 4. 建造者模式:测试建造者是否能按预期构建复杂对象,确保各个步骤的正确性。 5. 装饰器模式:确保装饰者能在不...

    JUnit -- 分析

    9. **源码分析**:可能深入到JUnit的源代码,解释其设计模式,如观察者模式、装饰器模式,以及JUnit如何处理测试失败和测试报告。 10. **实战示例**:结合实际项目,展示如何利用JUnit进行单元测试,解决实际问题。...

    吉林大学软件设计模式大富翁游戏(JAVA实现)

    3. **设计模式** - 表明项目的核心在于使用了软件工程中的设计模式,这些模式是解决常见问题的最佳实践,如单例模式、工厂模式、观察者模式等,它们有助于提高代码质量和可读性。 【文件名称列表】:由于没有提供...

    设计模式面试题

    - 观察者模式是一种基于发布/订阅模式的行为设计模式,适用于构建响应式的系统。 - 当一个主题的状态发生变化时,所有观察该主题的对象都会收到通知,并能够自动更新自己的状态。 - `java.util.Observable`类和`java...

    junit-4.8.2.jar包

    在设计模式方面,JUnit 4.8.2体现了观察者模式,测试运行器(Runner)观察并执行测试,当测试完成时,它可以通知其他系统组件(如构建工具或IDE)测试的结果。此外,扩展机制如自定义测试运行器(Custom Test ...

Global site tag (gtag.js) - Google Analytics