消息队列(MQ),一种能实现生产者到消费者单向通信的通信模型,这也是现在常用的主流中间件。
常见有 RabbitMQ、ActiveMQ、Kafka等 他们的特点也有很多 比如 解偶、异步、广播、削峰 等等多种优势特点。
在设计模式中也有一种模式能有效的达到解偶、异步的特点,那就是观察者模式又称为发布订阅模式。
什么是观察者模式
观察者(Observer)模式的定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。
观察者模式优点
- 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。符合依赖倒置原则
- 目标与观察者之间建立了一套触发机制
观察者模式缺点
- 目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用
- 当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率
模式的结构

- 抽象主题(Subject)角:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法
- 具体主题(Concrete Subject)角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象
- 抽象观察者(Observer):它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用
- 具体观察者(Concrete Observer):实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态
怎么看都感觉还是有点抽象,我们用具体实例代码来走一遍,下面以朋友圈为例,当前个人作为订阅者,好友作为主题。一个人发一条动态朋友圈出去,他的好友都能看到这个朋友圈,并且可以在自主选择点赞或者评论。
定义添加删除关系以及通知订阅者
public interface Subject {
// 添加订阅关系
void attach(Observer observer);
// 移除订阅关系
void detach(Observer observer);
// 通知订阅者
void notifyObservers(String message);
}
其次再创建的具体主题,并且构建一个容器来维护订阅关系
//具体目标
class ConcreteSubject extends Subject {
public void notifyObserver() {
System.out.println("发生了改变");
System.out.println("===============");
for (Object obs : observers) {
((Observer) obs).response();
}
}
}
创建一个观察者接口,方便我们管理
//抽象观察者
interface Observer {
void response(); //反应
}
最后就是创建具体的观察者类,实现观察者接口的response方法,处理本身的业务逻辑
//具体观察者1
class ConcreteObserver1 implements Observer {
public void response() {
System.out.println("观察者1接收到你的该改变了!");
}
}
//具体观察者1
class ConcreteObserver2 implements Observer {
public void response() {
System.out.println("观察者2接收到你的该改变了!");
}
}
最后是测试结果
public static void main(String[] args) {
// TODO Auto-generated method stub
Subject subject = new ConcreteSubject();
Observer obs1 = new ConcreteObserver1();
Observer obs2 = new ConcreteObserver2();
subject.add(obs1);
subject.add(obs2);
subject.notifyObserver();
}
发生了改变
===============
观察者1接收到你的该改变了!
观察者2接收到你的该改变了!
应用场景
- Spring 框架中有一个 ApplicationListener ,也是采用观察者模式来处理的,ApplicationEventMulticaster作为主题,里面有添加,删除,通知等
- 熟悉 JDK 的人应该知道 在java.util 包下 除了常用的 集合 和map之外还有一个Observable类,他的实现方式其实就是观察者模式。里面也有添加、删除、通知等方法,这里需要注意是的它是用 Vector 作为订阅关系的容器,同时在他的定义方法中都添加 synchronized 关键字修饰类,以达到线程安全的目的
- Google Guava的事件处理机制 Guava EventBus 他的实现也是采用设计模式中的观察者设计模式
1566

被折叠的 条评论
为什么被折叠?



