观察者模式又称发布-订阅模式,就是观察者通过订阅被观察者,或关注被观察者,从而实时更新观察者的信息。比如我们玩微博的时候,如果关注了一些博主,那么当博主发动态时,在首页微博列表中就会自动更新这些博主发的微博,而不需要我们自己去获取。其中我们(粉丝)就是观察者,博主是被观察者,关注就相当于订阅,订阅之后被观察者的更新动态都会通知给观察者,从而更细观察者自己的关注信息。

下面以微博为例,假设有三个程序员分别是张三、李四、王麻子,还有一个名为Java大本营的一个博主,这个博主每天会更新一些java知识的博文,在关注之前这三个程序员必须每次主动进入这个博主的主页去查看有哪些更新,为了不这么麻烦,他们决定关注这个博主,订阅他更新的文章,这样他们只要在自己的微博关注中下拉刷新一下,就能看到博主所有的动态。

第一步:创建一个观察者接口

 /*
* 定义一个观察者接口
*/
public interface Observer {
//更新消息
public void update(String message,String bloggerName);
}

第二步:定义一个微博用户类,做为观察者实现上面的接口

 /*
* 定义一个微博用户类,实现观察者接口
*/
public class WeiboUser implements Observer {
private String nickName;// 用户昵称 public WeiboUser(String nickName) {
this.nickName = nickName;
} /*
* 微博用户刷新自己的关注列表
*/
public void update(String message, String bloggerName) {
System.out.println("用户" + nickName + "收到了博主" + bloggerName + "更新的微博:" + message);
}
}

第三步:定义一个被观察者接口,用来添加、删除、通知观察者

 /*
* 定义一个被观察者接口:接口中定义增加观察者、删除观察者和通知观察者的接口
*/
public interface Observable {
// 增加观察者
public void addObserver(Observer observe); // 删除观察者
public void deleteObserver(Observer observer); // 通知观察者
public void notifyObserver(); }

第四步:定义一个博主类,作为被观察者实现上面的接口

 /*
* 定义一个博主类:实现被观察者接口
*/
public class Blogger implements Observable {
public String name;// 博主名称
public String message;// 微博信息
public List<Observer> fansList = new ArrayList<Observer>();// 粉丝列表 public Blogger(String name) {
this.name = name;
} // 增加一个粉丝
public void addObserver(Observer observer) {
fansList.add(observer);
} // 删除一个粉丝
public void deleteObserver(Observer observer) {
if (!fansList.isEmpty()) {
fansList.remove(observer);
}
} // 通知粉丝更新的消息
public void notifyObserver() {
for (Observer observer : fansList) {
observer.update(message, name);
}
} // 博主更新微博
public void updateWeibo(String message) {
this.message = message;
System.out.println("博主" + name + "更新了一条微博,内容为:" + message);
} }

第五步:用户开始玩微博

 /*
* 实现玩微博
*/
public class PlayWeibo {
public static void main(String[] args) {
// 三个程序员用户
Observer zhangsan = new WeiboUser("张三");
Observer lisi = new WeiboUser("李四");
Observer wangmazi = new WeiboUser("王麻子");
// Java大本营博主
Blogger javaBlogger = new Blogger("Java大本营"); //让三个程序员关注博主
javaBlogger.addObserver(zhangsan);
javaBlogger.addObserver(lisi);
javaBlogger.addObserver(wangmazi); //Java大本营更新微博
javaBlogger.updateWeibo("Java是世界上最好的语言"); //Java大本营通知所有粉丝
javaBlogger.notifyObserver(); //粉丝张三对Java大本营取关
javaBlogger.deleteObserver(zhangsan); //Java大本营又更新了一条消息
javaBlogger.updateWeibo("Hello World!"); //Java大本营再次通知所有粉丝
javaBlogger.notifyObserver(); }
}

第六步:分析结果

 博主Java大本营更新了一条微博,内容为:Java是世界上最好的语言
用户张三收到了博主Java大本营更新的微博:Java是世界上最好的语言
用户李四收到了博主Java大本营更新的微博:Java是世界上最好的语言
用户王麻子收到了博主Java大本营更新的微博:Java是世界上最好的语言
博主Java大本营更新了一条微博,内容为:Hello World!
用户李四收到了博主Java大本营更新的微博:Hello World!
用户王麻子收到了博主Java大本营更新的微博:Hello World!

从上述结果可以看出,当三个程序员用户关注了博主之后,每当博主发布了微博,他们三个都能收到;而当张三取关博主之后,博主再次更新的微博他就看不到了,所以说只有用户(观察者)关注(订阅)了博主(被观察者),才能及时看到博主更新的内容,这就是观察者模式,或发布-订阅模式。

Java内功修炼系列一观察者模式的更多相关文章

  1. Java内功修炼系列一反射

    “JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制 ...

  2. Java内功修炼系列一拦截器

    在动态代理中,我们知道在代理类中,执行真实对象的方法前后可以增加一些其他的逻辑,这些逻辑并不是真实对象能够实现的方法,比如一个租房的用户希望租一套公寓,但是中介所代理的这个房东并没有可以出租的公寓,那 ...

  3. Java内功修炼系列一代理模式

    代理模式是JAVA设计模式之一,网上设计模式相关的博文铺天盖地,参考它们有助于自己理解,但是所谓“尽信书不如无书”,在参考的同时也要思考其正确性,写博客也是为了记录自己理解知识点的思路历程和心路历程, ...

  4. Java内功修炼系列一工厂模式

    工厂模式是一种创建型模式,它提供了一种新的创建对象的方式,一般情况下我们都习惯用new关键字直接创建对象.有时候会遇到这种情况,我们需要根据具体的场景选择创建什么类型的对象,可能有多种类型都能选择,但 ...

  5. Java内功修炼系列一责任链模式

    在上一节的拦截器中提到,程序的设计者一般会用拦截器替替代动态代理,将动态代理的逻辑隐藏起来,而把拦截器接口提供给开发者,使开发者不需要关系动态代理的具体实现过程,但是有时候需要多个拦截器,而且拦截器之 ...

  6. Java 内功修炼 之 数据结构与算法(一)

    一.基本认识 1.数据结构与算法的关系? (1)数据结构(data structure): 数据结构指的是 数据与数据 之间的结构关系.比如:数组.队列.哈希.树 等结构. (2)算法: 算法指的是 ...

  7. Java 内功修炼 之 数据结构与算法(二)

    一.二叉树补充.多叉树 1.二叉树(非递归实现遍历) (1)前提 前面一篇介绍了 二叉树.顺序二叉树.线索二叉树.哈夫曼树等树结构. 可参考:https://www.cnblogs.com/l-y-h ...

  8. Hadoop内功修炼

    IT十八掌<大数据内功修炼系列课程>强势推出!由实战派名师徐培成亲自操刀,学完做不了大数据我们负全责!2015.12.21前,优惠价:4999(名额已不多!)2015.12.31前,优惠价 ...

  9. Java设计模式(20)观察者模式(Observer模式)

    Java深入到一定程度,就不可避免的碰到设计模式(design pattern)这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模式在java的中型系统中应用广泛,遵循 ...

随机推荐

  1. 求一个n!中尾数有多少个零

    题目描述: 输入一个正整数n,求n!(即阶乘)末尾有多少个0? 比如: n = 10; n! = 3628800,所以答案为2 输入描述: 输入为一行,n(1 ≤ n ≤ 1000) 输出描述: 输出 ...

  2. flexbox属性速览及常见布局实现

    CSS3 弹性盒子(Flex Box)弹性盒子是即 CSS2 浮动布局后, CSS3 的一种新的布局模式. CSS3 弹性盒( Flexible Box 或 flexbox),是一种当页面需要适应不同 ...

  3. USACO training course Mother's Milk /// DFS(有点意思) oj10120

    题目大意: 输入 A B C 为三个容器的容量 一开始A B是空的 C是满的 每一次倾倒只能在 盛的容器满 或 倒的容器空 时才停止 输出当A容器空时 C容器内剩余量的所有可能值 Sample Inp ...

  4. UMP系统架构

  5. pg总览

    一.编译安装初始化等 ./configure --prefix=/release --with-openssl --without-ldap --with-libxml - -enable-threa ...

  6. logger----->模块级别的函数

    #_author:star#date:2019/11/6#logger----->模块级别的函数#文件与屏幕同时显示日志信息import logginglogger=logging.getLog ...

  7. 自定义StringBuilder类拼接非空字符串

    主要目的: 为了拼接多个非空字符串,还能达到链式的装X效果这里不考虑线程安全,所以使用StringBuilder快速拼接非空内容,中间用","作为分隔. 代码如下: package ...

  8. C#可扩展编程之MEF(四):见证奇迹的时刻

      前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往 ...

  9. System.Web.Mvc.RedirectToRouteResult.cs

    ylbtech-System.Web.Mvc.RedirectToRouteResult.cs 1.程序集 System.Web.Mvc, Version=5.2.3.0, Culture=neutr ...

  10. 组件component

    <!DOCTYPE html> <html lang="zh"> <head> <title></title> < ...