听说南软去年复试考到了观察者模式,最近又在很多地方看到这个设计模式,就学习下
观察者模式又被称为发布-订阅模式
一、代码
Observer
public interface Observer {
//更新的方法
void update(String message);
}
具体观察者(订阅者)-WeixinUser
// 微信用户名
private String name;
public WeixinUser(String name){
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name + "-" + message);
}
发布者(被订阅者) - Subject
public interface Subject {
/**
* 增加订阅者
* @param observer
*/
void attach(Observer observer);
/**
* 删除订阅者
* @param observer
*/
void detach(Observer observer);
/**
* 通知订阅者更新消息
* @param message
*/
void notify(String message);
}
SubscriptionSubject
public class SubscriptionSubject implements Subject {
// 存储订阅公众号的微信用户
private List<Observer> weixinUserList = new ArrayList<>();
/**
* 增加订阅者
* @param observer
*/
@Override
public void attach(Observer observer) {
weixinUserList.add(observer);
}
/**
* 删除订阅者
* @param observer
*/
@Override
public void detach(Observer observer) {
weixinUserList.remove(observer);
}
/**
* 通知订阅者更新消息
* @param message
*/
@Override
public void notify(String message) {
for (Observer observer:weixinUserList) {
observer.update(message);
}
}
}
结果
public class Client {
public static void main(String[] args) {
//具体的被观察者(微信公众号),存储了订阅该公众号的微信用户
SubscriptionSubject subscriptionSubject = new SubscriptionSubject();
//创建微信用户
WeixinUser user1 = new WeixinUser("张三");
WeixinUser user2 = new WeixinUser("李四");
WeixinUser user3 = new WeixinUser("王五");
//订阅公众号-> 微信公众号增加订阅者
subscriptionSubject.attach(user1);
subscriptionSubject.attach(user2);
subscriptionSubject.attach(user3);
//公众号更新发出消息给订阅的微信用户
subscriptionSubject.notify("xxx的专栏更新了");
}
}

二、相关知识
出现原因
当一个对象的状态发生改变时,已经登记的其他对象能够观察到这一改变从而作出自己相对应的改变。通过这种方式来达到减少依赖关系,解耦合的作用。
对上面这句话的理解是
当一个对象的状态发生改变时——》 也即被订阅者
发生改变,在这个例子中,就是subscriptionSubject.notify()
方法。
已经登记的其他对象能够观察到这一改变从而作出自己相对应的改变——》user1,user2,user3就是已经登记的对象,也即订阅者
能够观察到这一改变,notify()
方法遍历每个订阅者,每个订阅者做出自己的改变——》执行自己的方法observer.update(message)
.
通俗的理解
被订阅者执行某个方法,告诉它的所有对象(称为订阅者),订阅者获得消息执行自己的业务逻辑。
UML图
观察者模式的解耦合
这里已经达到了解耦合的效果,同时也减少了依赖关系。每个观察者根本不要知道发布者处理了什么业务逻辑,也不用依赖发布者任何业务模型,只关心自己本身需要处理的逻辑就可以了。
如果有新的业务添加进来,我们也只需要创建一个新的订阅者,并且维护到observers 容器中即可,也符合我们的开闭原则。
这里只是一种同步的实现方式,我们还可以扩展更多其他的异步实现方式,或者采用多线程等实现方式。
观察者模式类似于触发机制,发布者执行某一方法,订阅者触发执行某一方法
使用场景 参考连接
新用户注册成功后我们需要给用户做两件事情,第一是发送注册成功短信,第二是给用发送新人优惠券。
看到这个问题 大家可能首先会想到用MQ消息处理呀,是的,用消息确实可以的,但是这里我们用观察者模式来实现这个问题。
消息队列(MQ),一种能实现生产者到消费者单向通信的通信模型,这也是现在常用的主流中间件。常见有 RabbitMQ、ActiveMQ、Kafka等 他们的特点也有很多 比如 解偶、异步、广播、削峰 等等多种优势特点。
在设计模式中也有一种模式能有效的达到解偶、异步的特点,那就是观察者模式又称为发布订阅模式。