版权声明
- 本文原创作者:谷哥的小弟
- 作者博客地址:http://blog.csdn.net/lfdfhl
观察者模式概述
在正式进入该设计模式之前,我想问一下:你们平常都用微信干什么呢?
“聊天”
“发朋友圈”
“逛微店”
“看微信公众号,关注自己喜欢的内容”
好嘞,就从微信公众号入手!平常我们关注一个微信公众号,当它推送新内容时,手机界面上就会出现一个红色的小点提醒我们查看详细内容。换句话说:我们订阅了公众号,当它有新消息时就会自动告知我们。也就是说:我们自己是观察者,在观察微信公众号,微信公众号就是被观察者。
观察者模式的主要角色如下:
- 抽象主题(Subject):该角色为抽象目标类(或接口),它是一个被观察者。该角色提供增加、删除观察者对象的抽象方法,以及通知所有观察者的抽象方法。
- 具体主题(Concrete Subject):该角色是抽象主题(被观察者)的具体实现。
- 抽象观察者(Observer):该角色是一个抽象类或接口,在该角色中包含接收到主题消息时的响应方法。
- 具体观察者(Concrete Observer):该角色是抽象观察者的具体实现。
观察者模式示例
在此,以微信公众号为例阐述观察者模式。
抽象观察者
package com.observerPattern02;
/**
* 原创作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public interface Observer {
public void receiveMessage(String message);
}
具体观察者
package com.observerPattern02;
/**
* 原创作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class ObserverImpl implements Observer{
private String name;
public ObserverImpl(String name){
this.name=name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void receiveMessage(String message) {
System.out.println(name+",收到消息:"+message);
}
}
抽象主题
package com.observerPattern02;
/**
* 原创作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public interface Subject {
public void addObserver(Observer observer);
public void deleteObserver(Observer observer);
public void sendMessage(String message);
}
抽象的主题(被观察者)的常用方法:添加观察者,删除观察者,发送消息。
具体主题
package com.observerPattern02;
import java.util.ArrayList;
/**
* 原创作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class SubjectImpl implements Subject{
private ArrayList<Observer> observerArrayList;
public SubjectImpl(){
observerArrayList=new ArrayList<Observer>();
}
@Override
public void addObserver(Observer observer) {
if (observer!=null){
observerArrayList.add(observer);
}
}
@Override
public void deleteObserver(Observer observer) {
if (observer!=null){
observerArrayList.remove(observer);
}
}
@Override
public void sendMessage(String message) {
if(message!=null){
for(Observer observer:observerArrayList){
observer.receiveMessage(message);
}
}
}
}
测试
package com.observerPattern02;
/**
* 原创作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class Test {
public static void main(String[] args) {
Subject subscription = new SubjectImpl();
Observer observer1 = new ObserverImpl("老王");
Observer observer2 = new ObserverImpl("小弟");
Observer observer3 = new ObserverImpl("大熊");
subscription.addObserver(observer1);
subscription.addObserver(observer2);
subscription.addObserver(observer3);
subscription.sendMessage("公众号内容更新:最新动漫上线啦");
}
}
嗯哼,看到了么?三个微信用户(观察者)都收到了微信公众号发布的消息。我们平常订阅微信公众号的本质是:微信公众号记录下我们的微信账号。所以,当它有新消息推送时瞅瞅自己的小本子上记录了谁就发送给谁。
小结
看完这个小例子,我们再来梳理一下观察者模式。
- 该模式中存在观察者和被观察者
- 观察者和被观察者通过订阅(例如:addObserver( ))发生关联关系
- 当被观察者发出消息后,所有观察者均会收到消息
OK,当你看完了这个例子,再看RxJava框架的代码:
observable.subscribe(observer);
是不是就反应过来了呢?很多初学者看到这句代码的时候都会抓狂:怎么会是被观察者订阅了观察者?!!不该是观察者订阅被观察者么?!!其实,不必过于纠结文字表述的细节,重要的是明白其中的思想,它和我们刚才的:
subscription.addObserver(observer1);
难道不一样么?就是同一回事!没啥不同的。我们在思考问题的时候,不能单纯地只站在生活的角度来看,也不能光从计算机的角度来考虑;而是要把两者结合起来,不要钻牛角尖,认死理。
感悟
很多刚开始做开发的童鞋喜欢拿着一本厚厚的设计模式在角落里默默地啃。学习的劲头很足,态度也很端正,配得上10086个赞。在此,我也想提醒一下小伙伴们:学习态度和努力程度固然非常重要,但是我们也要注意学习方法。抛开实际应用和业务逻辑单纯地看设计模式是很难理解其精髓的。我们不妨将设计模式和自己的实际工作结合起来学习,从理论到实践,从书本到实战。