定义
定义对象间一种一对多的依赖关系,使得当每一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。
UML
优点
- 观察者和被观察者之间是松耦合的,分别可以各自独立改变。
- Subject在发送广播通知的时候,无须指定具体的Observer,Observer可以自己决定是否要订阅Subject的通知。
- 遵守大部分GRASP原则和常用设计原则,高内聚、低耦合。
缺点
- 松耦合导致代码关系不明显,有时可能难以理解。
- 如果一个对象被大量观察者订阅的话,在广播通知的时候可能会有效率问题。(毕竟只是简单的遍历)
应用场景
- 对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态可变。
- 对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节。
示例
实现一个简单的观察者和被观察者的示例。
Java
import java.util.ArrayList;
import java.util.List; public class Main
{
public static void main(String[] args)
{
Subject sub = new ConcreteSubject();
sub.addObserver(new ConcreteObserver1()); //添加观察者1
sub.addObserver(new ConcreteObserver2()); //添加观察者2
sub.doSomething();
} /**
* 观察则接口
*/
public interface Observer
{
void update();
} /**
* 被观察者基类
*/
public static abstract class Subject
{
private List<Observer> obs = new ArrayList<>(); public void addObserver(Observer obs)
{
this.obs.add(obs);
} public void delObserver(Observer obs)
{
this.obs.remove(obs);
} protected void notifyObserver()
{
for (Observer o : obs)
{
o.update();
}
} public abstract void doSomething();
} /**
* 观察者对象1
*/
public static class ConcreteObserver1 implements Observer
{
public void update()
{
System.out.println("观察者1收到信息,并进行处理。");
}
} /**
* 观察者对象2
*/
public static class ConcreteObserver2 implements Observer
{
public void update()
{
System.out.println("观察者2收到信息,并进行处理。");
}
} /**
* 具体的被观察者
*/
public static class ConcreteSubject extends Subject
{
public void doSomething()
{
System.out.println("被观察者事件反生");
this.notifyObserver();
}
}
}