观察者模式通常包括两个部分:
- 抽象主题接口:定义了被观察者必须实现的方法,包括添加、删除和通知观察者。
- 具体主题类:实现了抽象主题接口,可以有多个具体主题类,每个具体主题类代表不同的被观察者。
- 观察者接口:定义了观察者必须实现的方法,包括接收通知并做出相应的处理。
- 具体观察者类:实现了观察者接口,可以有多个具体观察者类,每个具体观察者类代表不同的观察者。
下面是一个简单的示例:
import java.util.ArrayList; import java.util.List; interface Subject { void attach(Observer observer); void detach(Observer observer); void notifyObservers(); } class ConcreteSubject implements Subject { private List<Observer> observers = new ArrayList<>(); public void attach(Observer observer) { observers.add(observer); } public void detach(Observer observer) { observers.remove(observer); } public void notifyObservers() { for (Observer observer : observers) { observer.update(); } } } interface Observer { void update(); } class ConcreteObserverA implements Observer { private ConcreteSubject subject; public ConcreteObserverA(ConcreteSubject subject) { this.subject = subject; subject.attach(this); } public void update() { System.out.println("ConcreteObserverA has been notified."); } } class ConcreteObserverB implements Observer { private ConcreteSubject subject; public ConcreteObserverB(ConcreteSubject subject) { this.subject = subject; subject.attach(this); } public void update() { System.out.println("ConcreteObserverB has been notified."); } }
在上面的示例中,Subject 接口定义了被观察者必须实现的方法。ConcreteSubject 是具体主题类,通过维护一个 List 来存储观察者,并实现了 Subject 接口中的添加、删除和通知方法。Observer 接口定义了观察者必须实现的方法。ConcreteObserverA 和 ConcreteObserverB 是具体观察者类,都实现了 Observer 接口。
下面是一个使用观察者模式的示例:
public class Client { public static void main(String[] args) { ConcreteSubject subject = new ConcreteSubject(); ConcreteObserverA observerA = new ConcreteObserverA(subject); ConcreteObserverB observerB = new ConcreteObserverB(subject); subject.notifyObservers(); } }
在上面的示例中,我们使用 ConcreteSubject 具体主题类来作为被观察者,并创建了两个具体观察者类 ConcreteObserverA 和 ConcreteObserverB。通过调用 ConcreteSubject 的 notifyObservers() 方法,可以通知所有观察者对象。
使用观察者模式可以带来一些好处:
- 降低耦合度:被观察者和观察者之间的依赖关系变得松散了,它们可以独立地进行改变。
- 可维护性提高:当系统需要更改时,只需要增加或删除具体观察者类即可,不需要修改原有代码。