什么是“观察者模式”
观察者模式也叫做“发布/订阅模式”。它是一种在项目中常用的模式。
定义:定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
观察者模式的类图如下:
其实通俗一点讲,观察者模式就类似于我们生活中的订报纸。如果我们向报社订了报纸,你每天都会收到报社送过来的新报纸。如果没有订阅,那自然就收不到。
所以,观察者模式也是如此,假如观察者类依赖了主题类(被观察者),那么每当主题类发生变化时,观察者类都会收到信息。
观察者模式如何实现?
要实现观察者模式之前,我们先看看上面的类图,类图中有抽象类Subject、接口ObServer以及分别继承和实现了抽象类和接口的ConcreteSubject、ConcreteObServer
- Subject 被观察者(主题)
- ObServer 观察者
- ConcreteSubject 具体的被观察者
- ConcreteObServer 具体的观察者
了解了他们的具体含义之后,我们就可以实现观察者模式了:
首先,我们定义观察者接口
/**
* 观察者接口
* */
public interface ObServer {
//接收到被观察者的更新后执行某些事情
public void uodate();
}
接下来,我们定义被观察者抽象类
public abstract class Subject {
//定义一个观察者列表
private List<ObServer> obServersList = new ArrayList<>();
//添加一个观察者
public void addObServer(ObServer server){
obServersList.add(server);
}
//删除一个观察者
public void deleteObServer(ObServer server){
obServersList.remove(server);
}
//通知所有观察者
public void notifyObServer(){
for (ObServer obServer : obServersList){
obServer.uodate();
}
}
}
上面两个类完成之后,我们就可以实现具体的观察者和被观察者了
/**
* 具体的主题(被观察者)
* */
public class TestSubject extends Subject{
public void doSomething(){
System.out.println("我是主题(被观察者), 我要开始干活了!!");
super.notifyObServer();
}
}
public class TestObServer implements ObServer {
@Override
public void uodate() {
System.out.println("我是观察者一号,我知道你要开始干活了!!");
}
}
public class TestObServer2 implements ObServer {
@Override
public void uodate() {
System.out.println("我是观察者二号,我知道你要开始干活了!!");
}
}
接下来我们进行测试:
public class Test {
public static void main(String[] args){
TestSubject subject = new TestSubject();
TestObServer obServer1 = new TestObServer();
TestObServer2 obServer2 = new TestObServer2();
subject.addObServer(obServer1);
subject.addObServer(obServer2);
subject.doSomething();
}
}
输出结果:
我是主题(被观察者), 我要开始干活了!!
我是观察者一号,我知道你要开始干活了!!
我是观察者二号,我知道你要开始干活了!!
从上面的代码中我们可以发现,我们只执行了被观察者的doSomething()方法,他就会自动通知所有的观察者。这就是所谓的观察者模式,简单吧~
那么,总结来了
优点:
- 观察者和被观察者之间是抽象耦合。因为已经完成了抽象层级的定义,不管是在增加观察者或者被观察者都很容易。
- 建立了一套触发机制。 比如,老师向学习委员发送今天的作业,学习委员又向同学们发送这份作业,如此循环,就可以传递下去。因此观察者也可以成为被观察者,这样就可以形成一套触发链。
缺点:
- 开发效率和运行效率问题。 一个被观察者,多个观察者,这样会导致调试困难等问题。
- 多级触发时,会很恐怖。
使用场景:
- 关联行为场景。
- 事件的多级触发场景
- 跨系统的消息交换场景,如消息队列的处理机制。
感谢阅读本博客。
欢迎关注我的博客:https://li-weijian.github.io/
欢迎关注我的CSDN:https://blog.csdn.net/qq352642663
需要联系请加QQ:352642663
欢迎联系我共同交流