微信订阅号项目中观察者模式解析

一、什么是观察者模式

1、生活中的观察者模式

警察抓小偷

在现实生活中,警察抓小偷是一个典型的观察者模式「这以一个惯犯在街道逛街然后被抓为例子」,这里小偷就是被观察者,各个干警就是观察者,干警时时观察着小偷,当小偷正在偷东西「就给干警发送出一条信号,实际上小偷不可能告诉干警我有偷东西」,干警收到信号,出击抓小偷。这就是一个观察者模式

装模作样写作业

小时候家里家活比较多,爸妈让我去干活的时候,我偶尔会说我要学习「其实不想去干活,当然只是偶尔,我还是常常干家务的」,然后爸妈就去地里了,我一个人在家里,先摆出一张桌子「上面放好想看的书」,然后打开电视机看起电视剧,但是又怕家里人回到家中看到我在看电视,于是把家里的大门锁住「当爸妈回的时候肯定要开门」,当我听见开门声就会立马关掉电视,做到作业桌上「装模作样写作业」----在这过程中:我充当的就是观察者,爸妈就是被观察者,他们开门就会触发门响「相当于告诉我说他们回来了」,我听到响声「关电视,写作业」,有过类似的经验的朋友们下面点个赞

远程视频会议

老板和员工远程开会:老板是被观察者,员工是观察者。微信公号:微信公号作者是被观察者,微信用户是观察者「当公号作者发送一篇文章,关注了公号的观察者都可以收到文章」等

2、程序中的观察者模式

观察者模式的定义

观察者模式描述的是一种一对多的关系「一个被观察者对应多个观察者」,当被观察者的状态发生改变时,所有观察者都会得到通知。通俗的理解:观察者模式就是在特定的时刻「被观察者发送通知」干特定的事情「观察者收到通知处理自己相应的事件」

  

观察者模式的特点

观察者模式的三要素:观察者,被观察者,事件「订阅」

观察者模式的结构

角色类别说明
Subject 接口或抽象类 主题也叫被观察者
RealSubject 真实的主题类 具体的被观察者,内部维护了观察者的列表
IObserver 观察者接口或抽象类 抽象出观察者的接口
RealObserver 具体的观察者 被观察者有更新,观察者立马响应更新

 

 

 

 

 

 

二、观察者模式在微信订阅号中的应用

在微信的订阅号中,订阅号可以被关注或取消关注,当有新的文章、消息、出现的时候,订阅了的读者都会收到消息。所以可以抽象出来一个共同的抽象类Publisher来实现这些公共的方法。

https://github.com/get-set/get-designpatterns/blob/master/observer/src/main/java/com/getset/designpatterns/observer/Publisher.java#L7

 1 public abstract class Publisher {
 2     private List<Subscriber> funs = new ArrayList<Subscriber>();
 3     private String message;
 4 
 5     public void publishMessage(String message) {
 6         this.message = message;
 7         notifyAllSubscribers();
 8     }
 9 
10     public String getMessage() {
11         return message;
12     }
13 
14     public void addSubscriber(Subscriber subscriber) {
15         funs.add(subscriber);
16     }
17     public void delSubscriber(Subscriber subscriber) {
18         funs.remove(subscriber);
19     }
20     public void notifyAllSubscribers() {
21         Iterator<Subscriber> it = funs.iterator();
22         while (it.hasNext()) {
23             it.next().update(this);
24         }
25     }
26 }

Publisher维护有一个订阅者的集合,其中message统一表示文章、信息或声音作品等各种形式的内容,由publishMessage更新内容,而当有新的内容更新时,会调用notifyAllSubscibers方法来通知所有关注人。这里要注意的是,这种通知是一种回调行为,也就是通过遍历并调用各个subscriberupdate方法来进行通知。

https://github.com/get-set/get-designpatterns/blob/master/observer/src/main/java/com/getset/designpatterns/observer/Subscriber.java#L3

1 public interface Subscriber {
2     void update(Publisher publisher);
3 }

因此,具体来说,微信订阅号就是一种Publisher。

https://github.com/get-set/get-designpatterns/blob/master/observer/src/main/java/com/getset/designpatterns/observer/WeixinPublisher.java#L3

 1 public class WeixinPublisher extends Publisher {
 2     private String dingyuehao;
 3 
 4     public WeixinPublisher(String dingyuehao) {
 5         this.dingyuehao = dingyuehao;
 6     }
 7 
 8     @Override
 9     public String toString() {
10         return "微信订阅号[" + dingyuehao + "]";
11     }
12 }

而普通的微信用户——即关注者——就是Subscriber。

https://github.com/get-set/get-designpatterns/blob/master/observer/src/main/java/com/getset/designpatterns/observer/WeixinAccount.java#L3

 1 public class WeixinAccount implements Subscriber {
 2     private String accountName;
 3 
 4     public WeixinAccount(String accountName) {
 5         this.accountName = accountName;
 6     }
 7 
 8     public void update(Publisher publisher) {
 9         System.out.println(accountName + "的微信收到了来自" + publisher + "的推送文章: " + publisher.getMessage());
10     }
11 }

微信用户实现了具体的update方法,定义了在收到通知后要做哪些操作,比如阅读、转发等等,这里通过打印一行文字来表示。

https://github.com/get-set/get-designpatterns/blob/master/observer/src/main/java/com/getset/designpatterns/observer/Client.java#L3

 1 public class Client {
 2     public static void main(String[] args) {
 3         WeixinPublisher publisher = new WeixinPublisher("享学IT");
 4         publisher.addSubscriber(new WeixinAccount("张三"));
 5         publisher.addSubscriber(new WeixinAccount("李四"));
 6         publisher.addSubscriber(new WeixinAccount("王五"));
 7 
 8         publisher.publishMessage("Java设计模式百例-观察者模式");
 9     }
10 }

例如,张三执行“关注”操作后,微信订阅号执行addSubscriber操作将他添加到自己的订阅者名单中,当发布新消息时,订阅者都可以收到,输出如下。

张三的微信收到了来自微信订阅号[享学IT]的推送文章: Java设计模式百例-观察者模式

三、观察者模式的优缺点

1、优点

  1、解耦,被观察者只知道观察者列表「抽象接口」,被观察者不知道具体的观察者

  2、被观察者发送通知,所有注册的观察者都会收到信息「可以实现广播机制」

2、缺点

  1、如果观察者非常多的话,那么所有的观察者收到被观察者发送的通知会耗时

  2、观察者知道被观察者发送通知了,但是观察者不知道所观察的对象具体是如何发生变化的

  3、如果被观察者有循环依赖的话,那么被观察者发送通知会使观察者循环调用,会导致系统崩溃

 

本文源码见:https://github.com/get-set/get-designpatterns/tree/master/observer/src/main/java/com/getset/designpatterns/observer

posted on 2018-10-25 21:29  Trigger_lee  阅读(390)  评论(0编辑  收藏  举报