赞
踩
观察者模式是一种常见的设计模式,也称作发布-订阅模式。它主要解决了对象之间的通知依赖关系问题。在这种模式中,一个对象(称作Subject)维护着一个对象列表,这些对象(称作Observers)都需要被通知来响应某些事件。
观察者模式的好处在于它创建了松耦合的对象之间的一对多关系,使得Subject和Observers之间的耦合度降低。在Java中,通过定义接口和抽象类等方式,可以很容易实现观察者模式。
观察者模式包含两个主要角色:Subject和Observer。Subject是需要被监视的对象,Observer则是负责观察Subject的变化记录并做出相应处理的对象。
当Subject发生变化时,会通知所有的Observer,并调用其相应的回调方法(也就是Observer中定义的处理Subject变化的方法)。因此,每个Observer都需要注册到Subject中去,以便Subject在发生变化时能够通知到它们。
观察者模式总体结构如下所示:
其中,Subject包含一个状态(state)和一个Observer列表(observers),它有如下几个主要方法:
registerObserver(Observer observer):将一个Observer对象注册到Subject中。
removeObserver(Observer observer):将一个Observer对象从Subject中移除。
notifyObservers():通知所有已经注册的Observer,以便它们做出相应的处理。
Observer接口则主要定义Observer对象中需要实现的处理Subject变化的方法。在Java中,通常将Observer接口定义为如下所示:
public interface Observer {
public void update(Object arg);
}
其中,update方法用于处理Subject发生变化时的操作。
在Java中,实现观察者模式有多种方式。下面介绍两种比较常见的实现方式:使用Java内置类库提供的Observer和Observable类实现和使用自定义接口实现。
2.1 使用Java内置类库提供的Observer和Observable类实现
Java内置类库提供了一个Observer接口和一个Observable类,可以方便地实现观察者模式。
Observable类实际上就是Subject,它有如下方法:
addObserver(Observer o):注册一个Observer对象到Observable中。
deleteObserver(Observer o):从Observable中删除指定的Observer对象。
notifyObservers():通知所有已经注册的Observer,以便它们做出相应的处理。
Observer接口同上。
下面是一个使用这种方式实现观察者模式的简单示例:
import java.util.Observable; import java.util.Observer; public class SimpleObservable extends Observable { private int data = 0; public int getData() { return data; } public void setData(int data) { this.data = data; setChanged(); // 标记Subject对象的状态已发生变化 notifyObservers(data); // 通知所有已注册的Observer对象 } } public class SimpleObserver implements Observer { private int data; public void update(Observable o, Object arg) { if (arg instanceof Integer) { this.data = (Integer) arg; System.out.println("Data has changed to " + this.data + " in SimpleObserver."); } } } public class Test { public static void main(String[] args) { SimpleObservable observable = new SimpleObservable(); SimpleObserver observer = new SimpleObserver(); observable.addObserver(observer); observable.setData(1); observable.setData(2); observable.setData(3); } }
这个示例中,SimpleObservable类继承了Observable,并在setData方法中使用了setChanged和notifyObservers方法,标记Subject对象的状态已发生变化并通知所有已注册的Observer对象。
SimpleObserver类实现了Observer接口,并在update方法中处理Subject发生变化时的操作。
最后,Test类将SimpleObservable和SimpleObserver组装起来,实现了一个简单的观察者模式示例。
需要注意的是,Java内置的Observable类有几个限制:
Observable是一个类而不是一个接口,这意味着你不能再继承其他类。
setChanged方法被定义为protected,因此你不能显式地调用这个方法。
Observer接口中只有一个update方法,而Observable没有额外的状态变量来描述它的内部状态,这使得Observer无法获得有关Observable的状态信息。
如果Observable涉及到线程安全问题,你需要在使用Observable时自己处理。
2.2 使用自定义接口实现
另一种实现观察者模式的方式是使用自定义接口,这种方式比较灵活,也可以适用于一些特定场景。
下面是一个使用这种方式实现观察者模式的简单示例:
public interface Observer { public void update(Object obj); } public interface Subject { public void registerObserver(Observer observer); public void removeObserver(Observer observer); public void notifyObservers(Object obj); } public class SimpleSubject implements Subject { private List<Observer> observers = new ArrayList<Observer>(); private int data = 0; public void registerObserver(Observer observer) { observers.add(observer); } public void removeObserver(Observer observer) { observers.remove(observer); } public void notifyObservers(Object obj) { for (Observer observer : observers) { observer.update(obj); } } public int getData() { return data; } public void setData(int data) { this.data = data; notifyObservers(data); } } public class SimpleObserver implements Observer { private int data; public void update(Object obj) { if (obj instanceof Integer) { this.data = (Integer) obj; System.out.println("Data has changed to " + this.data + " in SimpleObserver."); } } } public class Test { public static void main(String[] args) { SimpleSubject subject = new SimpleSubject(); SimpleObserver observer = new SimpleObserver(); subject.registerObserver(observer); subject.setData(1); subject.setData(2); subject.setData(3); } }
这个示例中,Subject接口定义了三个方法:registerObserver、removeObserver和notifyObservers。SimpleSubject类实现了Subject接口,并在setData方法中调用了notifyObservers方法。
Observer接口定义了update方法,SimpleObserver类实现了Observer接口,并在update方法中处理Subject发生变化时的操作。
最后,Test类将SimpleSubject和SimpleObserver组装起来,实现了一个简单的观察者模式示例。
自定义接口的优点在于它的灵活性,能够适用于各种场景。另外,自己实现Observer模式通常需要写更多的代码,并且Observer对象可能需要自己维护许多状态信息。
观察者模式具有以下优点:
观察者模式将Subject和Observer之间解耦,使得它们可以独立地变化或扩展,提高了系统的灵活性和可扩展性。
观察者模式建立了一种灵活的一对多关系,可以在任何时候添加或删除Observer对象,实现不同的业务需求。
当Subject发生变化时,只需要通知已经注册的Observer对象,而无需通知未注册的Observer对象,从而避免了系统产生不必要的开销。
观察者模式具有以下缺点:
观察者模式可能会导致系统中出现大量的细粒度对象,从而增加系统的复杂性。
如果Subject和Observer之间相互依赖,会导致循环依赖问题,从而导致系统崩溃。
总之,观察者模式是一种常用的设计模式,主要解决了对象之间的通知依赖关系问题。在Java中,可以使用Java内置类库提供的Observer和Observable类或者自定义接口实现观察者模式。观察者模式具有灵活性、可扩展性和提高系统松耦合度等优点,但也会带来一些复杂性和循环依赖问题。在使用观察者模式时,需要根据具体业务场景进行权衡和选择。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。