设计模式(十六)—— 观察者模式

观察者模式

定义

定义对象间的一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖与他的对象都会得到通知并被自动更新。

S

  • Subject:被观察者,定义被观察者必须实现的职责,必须能过动态的增加、取消观察者,一般是抽象类或者实现类,管理观察者并通知观察者。
  • Observer:观察者,观察者接收到消息后进行更新操作,对接收到的信息进行处理。
  • ConcreteSubject:具体被观察者,定义被观察者自己的业务逻辑,同时定义对那些事件进行通知。
  • ConcreteObserver:具体观察者,观察者自己的业务逻辑。

具体实现

1
2
3
4
5
6
7
8
9
10
public interface Observer {
void update();
}

public class ConcreteObserver implements Observer {
@Override
public void update() {
System.out.println("接收到消息,进行处理");
}
}

被观察者:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public abstract class Subject {
private List<Observer> list = new ArrayList<>();

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

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

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

}

被观察者实现:

1
2
3
4
5
6
public class ConcreteSubject extends Subject {
public void doSomething(){
System.out.println("具体的被观察者的业务");
super.notifyObserver();
}
}

测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Main {

public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
Observer observer = new ConcreteObserver();
subject.addObserver(observer);
subject.doSomething();

}
}
// 输出
具体的被观察者的业务
接收到消息,进行处理

优点

  • 观察者和被观察者之间是抽象耦合的
  • 目标与观察者之间建立了一套触发机制。

缺点

  1. 目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。
  2. 当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。

应用场景

  1. 对象间存在一对多关系,一个对象的状态发生改变会影响其他对象。
  2. 当一个抽象模型有两个方面,其中一个方面依赖于另一方面时,可将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。

Java提供了java.util.Observable实现类和java.util.Observer接口。上面的被观察者类和观察者接口可以用java提供的api代替了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ObserverApi implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("接收到消息,进行处理----使用java.util.Observer接口");
}

}

public class SubjectApi extends Observable {
public void doSomething(){
System.out.println("具体的被观察者的业务---继承java.util.Observable");
super.setChanged();
super.notifyObservers();
}
}

public static void main(String[] args) {
SubjectApi subjectApi = new SubjectApi();
ObserverApi observerApi = new ObserverApi();
subjectApi.addObserver(observerApi);
subjectApi.doSomething();

}

代码:GitHub


欢迎关注公众号:
欢迎关注公众号

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
显示 Gitment 评论