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

下面以微博为例,假设有三个程序员分别是张三、李四、王麻子,还有一个名为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. JS 变量的数据类型转换

    变量的类型转换,一般情况是JS自动转换的,但也有些时候需要手动转换. 1.其它类型转成布尔型 函数和方法的区别 Boolean(a)  //函数是可以独立使用的 document.write(a)   ...

  2. Hdu-1452-Happy 2004-费马小定理推除法逆元+同余定理+积性函数

    Consider a positive integer X,and let S be the sum of all positive integer divisors of 2004^X. Your ...

  3. shell脚本练习02--求字符串的长度

    ######################################################################### # File Name: -.sh # Author ...

  4. mac brew nginx php php-fpm xdebug

    /usr/local/opt/nginx/bin/nginx -v brew services restart nginx sudo /usr/local/sbin/php-fpm --fpm-con ...

  5. 提问(prompt 消息对话框)用于询问一些需要与用户交互的信息。弹出消息对话框(包含一个确定按钮、取消按钮与一个文本输入框)

    提问(prompt 消息对话框) prompt弹出消息对话框,通常用于询问一些需要与用户交互的信息.弹出消息对话框(包含一个确定按钮.取消按钮与一个文本输入框). 语法: prompt(str1, s ...

  6. webpack打包出错分析

    Module not found: Error: Can't resolve 'bundle.js' in 更改打包命令 webpack run1.js  -o bundle.js

  7. html-圣杯布局

    1.两边固定 当中自适应 2.当中列要完整显示 3.当中列要优先加载 浮动: 搭建完整的布局框架 margin 为赋值:调整旁边两列的位置(使三列布局到一行上) 使用相对定位:调整旁边两列的位置(使两 ...

  8. PostgreSQL问题解决--连接数过多

    I am trying to connect to a Postgresql database, I am getting the following Error: Error:org.postgre ...

  9. 今天介绍一个渐变的方法,在shell里面自动生成注释简介

    在编辑sh脚本时,我经常在shell中写一些注释.今天我介绍一种渐变方法,它可以在每次vim shell脚本时自动在shell中生成注释和其他信息. 让我们共享一个shell脚本模板文件,将其复制到用 ...

  10. make: 警告:检测到时钟错误。您的创建可能是不完整的。

    我在make的时候也出现了同样的问题,不过不是什么大问题,这个不影响编译结果,但是强迫症还是希望能解决掉 分析原因可能是:服务器上的文件最后修改时间比当前时钟要晚 解决办法:用touch 命令把源程序 ...