最近想深刻研究下响应式编程,做为基础颇有必要来把观察者模式撸一遍;一开始我是以为很easy,而后就直接开撸了,撸着撸着发现撸不动了。由于我忽然不太明白这个模式了,说好的观察者,到底发布-订阅的二者执行者谁才是观察者?又或者说还有其余角色?可是根据《JAVA与模式》一书中的结构,并无额外的角色出现。
java
思考中....,好吧想不出来....,跑步去...编程
跑步时我给本身罗列了几个问题:后端
这里先抛出定义:GOF给观察者模式以下定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,全部依赖于它的对象都获得通知并被自动更新。设计模式
这里因为一些定式思惟,总会以为既然是“被观察者”,那么这个“被”字就是否是就代表“被观察者”是被动接受变动的一方,也就是接受通知的一方呢?微信
以前我也是走到这个胡同里了,程序写完总以为哪里不对;回过头看,仍是本身太年轻,没有get到哪些大佬们的点。app
先来看程序;这里用掘金来打个比方,个人博客glmmaper做为被观察者,也就是发布者。掘金小伙伴们做为观察者,也就是订阅者。ide
具体逻辑:小伙伴们(订阅者)关注(订阅)了个人博客(发布者),若是我发布了一篇文章(状态变动),就会通知(推送消息)全部关注个人小伙伴。spa
package com.glmapper.designmode.observor;
/** * @description: 抽象主题接口 * @email: <a href="glmapper_2018@163.com"></a> * @author: 磊叔 * @date: 18/4/22 */
public interface Subject {
/** * 新增关注者 * @param observer 关注的小伙伴 */
void addFocusObserver(Observer observer);
/** * 取消关注 * @param observer 取消关注的小伙伴 */
void removeFocusObserver(Observer observer);
/** * 通知机制,通知机制由相关事件来触发,好比说发布文章 * @param blogName 博客名 * @param articleName 文章名 */
void notifyObservers(String blogName,String articleName);
}
复制代码
三个方法,一个是博客主页增长了一个关注者;一个是博客主页有小伙伴取消的关注(对于博客来讲就是移除一个关注者,这里不知道是否也会以为别扭?明明你取消的关注,为啥说成是我移除你,也就是不让你关注了,还能这么玩?这里确定是须要在引入其余的一些辅助机制,好比说你在客户端发起了一个取消关注的请求,后端处理的时候掘金的工程师们就是在个人关注列表中将你移除的,嗯,这么一想确实是我不让你关注了。😄....);最后一个方法是发起一个通知。下面是一个具体的博客,好比说是glmapper;设计
package com.glmapper.designmode.observor;
import java.util.ArrayList;
import java.util.List;
/** * @description: 这个是具体发布者,这里比喻成个人博客glmapper * @email: <a href="glmapper_2018@163.com"></a> * @author: 磊叔 * @date: 18/4/22 */
public class ConcreteSubject implements Subject {
/** 个人当前关注列表 */
List<Observer> Observers = new ArrayList<>();
/** 个人博客名 :求关注 */
private static final String blogName = "glmapper";
@Override
public void addFocusObserver(Observer observer) {
Observers.add(observer);
}
@Override
public void removeFocusObserver(Observer observer) {
Observers.remove(observer);
}
@Override
public void notifyObservers(String blogName,String articleName) {
for (Observer observer:Observers) {
observer.update(blogName,articleName);
}
}
/** * 这里是发布文章,触发通知事件 */
public void publishArticle(String articleName){
notifyObservers(blogName,articleName);
}
}
复制代码
前面提到,通知事件确定是因为某些状态发生变动了,才会进行通知,这里就能够比方为我发布了一篇博客,而后通知你(这里只能假如你关注了)。再来看观察者:code
package com.glmapper.designmode.observor;
/** * @description: 订阅者抽象接口 * @email: <a href="glmapper_2018@163.com"></a> * @author: 磊叔 * @date: 18/4/22 */
public interface Observer {
/** * 调用此方法会更新状态,作出相应的动做 * @param blogName * @param articleName */
void update(String blogName,String articleName);
}
复制代码
抽象订阅者,有一个update方法,通知你去作出相应的动做,具体动做每一个观察者均可能不一样。
package com.glmapper.designmode.observor;
/** * @description: 这个是具体订阅者,这里能够比喻成博客关注者, * 收到变动信息以后须要作出相应的动做 * @email: <a href="glmapper_2018@163.com"></a> * @author: 磊叔 * @date: 18/4/22 */
public class ConcreteObserver implements Observer {
@Override
public void update(String blogName,String articleName) {
System.out.println(blogName+"发布了新的文章,文章名为:"+articleName);
read(articleName);
}
private void read(String articleName){
System.out.println("即将阅读 "+articleName+" 这篇文章");
}
}
复制代码
上面是一个具体的关注者,加入说就是你。博客更新以后发了一个通知给你(掘金app推送的消息),而后你点了一下,这个也是一种动做。例子中举的是read,就是关注者作出阅读的动做。
看下最后的运行结果:
package com.glmapper.designmode.observor;
/** * @description: [描述文本] * @email: <a href="glmapper_2018@163.com"></a> * @author: 磊叔 * @date: 18/4/22 */
public class MyMainIndex{
public static void main(String[] args) {
//博客主体
ConcreteSubject subject = new ConcreteSubject();
//关注者:handSome是帅气的意思
Observer handSome = new ConcreteObserver();
//增长一个关注者
subject.addFocusObserver(handSome);
//发一篇文章
subject.publishArticle("设计模式-观察者模式");
}
}
glmapper发布了新的文章,文章名为:设计模式-观察者模式
即将阅读 设计模式-观察者模式 这篇文章
复制代码
酒桶说:啊,欢乐时光老是短暂的
因此做为积累,仍是须要将一些基本的概念来罗列一下的。
主要角色:
具体关系:
抽象主题(Subject)(接口)-->被具体主题(ConcreteSubject)角色(1个)实现
抽象观察者(Observer)(接口)-->被具体观察者(ConcretedObserver)角色(N个)实现
观察者对象载入主题方法,并在主题方法中调用观察者对象实现的接口方法update来让本身发生变动响应。
一些场景:
基于发布订阅的具体实现例子仍是不少的,比较典型的就是这种订阅一个博客,而后博客更新推送;还有微信公众号,服务号这些。
到这里咱们再回过头来看一开始留下的几个问题:
OK,观察者模式就撸到这里,也欢迎小伙伴们提出本身珍贵的意见;有写的不当之处烦请及时提出。
播报:菜鸟成长系列又开始更新了....