博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
观察者模式
阅读量:6641 次
发布时间:2019-06-25

本文共 2857 字,大约阅读时间需要 9 分钟。

阅读目录

一、概念

  观察者模式,又被称为发布—订阅模式、源—收听者模式,是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依与它的观察者物件,并且在它本身的状态改变时主动发出同时,此种模式通常被用来实现事件处理系统。

二、观察者模式组成

  观察者模式一般包含以下四种角色:

  抽象主题角色Watched:把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察这角色。

  抽象观察者角色Watcher:为所有具体的观察者定义一个接口,在得到主题的通知更新自己。

  具体主题角色ConcreteWatched:在具体主题内部状态改变时,给所有登记过的观察者发出通知。

  具体观察者角色ConcreteWatcher:该角色实现抽象观察者角色所要求的更新接口,以便使自身的状态与主题的状态相协调。

三、观察者模式实现方式

  观察者模式有很多实现方式,从根本上说,该模式必须包含两个角色,观察者和被观察对象。比较直观的一种是使用“注册”—“通知”—“撤销通知”的形式。

  观察者将自己注册到被观察对象中,被观察者将观察者放在一个容器中。

  被观察者对象发生某种变化时,从容器中得到所有被注册过的观察者,将变化通知观察者。

  观察者将自己注册到被观察者的容器时,被观察者不应该过问观察者的具体类型,而是应该使用观察者的接口。这样的好处是:假定程序还有别的观察者,那么只要这个观察者也是相同的接口即可。一个被观察者可以对应多个观察者,当被观察者发生变化的时候,他可以将消息一一通知给所有的观察者。如下图所示:

  

  具体到一个应用场景就是:读者订阅新闻,每一个读者都可以通过regist来订阅新闻,通过remove来取消订阅,当有新闻到来时,使用sendNews来通知每一位订阅的读者来收取新闻。

  下面用代码来实现上面的实例:

  抽象主题角色Watched:新闻接口,定义订阅、取消订阅和推送新闻三个方法

public interface Watched{    //订阅新闻    void registeSubscriber(Watcher f_subscriber);    //取消订阅    void removeSubscriber(Watcher f_subscriber);    //推送新闻    void sendNews();}

  抽象观察者角色Watcher:读者接口,定义了获取新闻的方法

public interface Watcher{    //获取新闻    void updateNews();}

  具体主题角色ConcreteWatched,即被观察者,实现了Watched接口:

import java.util.ArrayList;import java.util.List;/* * 具体被观察者 * 新闻发布者 */public class ConcreteWatched implements Watched{    private List
subList=new ArrayList
(); @Override public void registeSubscriber(Watcher f_subscriber) { subList.add(f_subscriber); } @Override public void removeSubscriber(Watcher f_subscriber) { subList.remove(f_subscriber); } @Override public void sendNews() {
System.out.println("开始本轮新闻推送!"); for (Watcher watcher : subList) { watcher.updateNews(); } System.out.println("本次新闻推送结束!"); }}

  具体观察者角色ConcreteWatcher,即观察者对象

/* * 具体的观察者 * 读者 */public class ConcreteWatcher implements Watcher{    private String username;            public ConcreteWatcher(String username)    {        super();        this.username = username;    }    @Override    public void updateNews()    {        System.out.println(username+"获取到最新的新闻了!");            }}

  下面是一个测试用例:

import org.junit.Test;public class WatchTest{    @Test    public void test()    {        ConcreteWatched concreteWatched=new ConcreteWatched();        Watcher watcher1=new ConcreteWatcher("读者A");        Watcher watcher2=new ConcreteWatcher("读者B");        Watcher watcher3=new ConcreteWatcher("读者C");                //订阅新闻        concreteWatched.registeSubscriber(watcher1);        concreteWatched.registeSubscriber(watcher2);        concreteWatched.registeSubscriber(watcher3);                //推送新闻        concreteWatched.sendNews();        //读者A取消订阅        concreteWatched.removeSubscriber(watcher1);        //再次推送新闻        concreteWatched.sendNews();    }}

  执行结果:

  

四、参考资料

  1、

转载地址:http://orovo.baihongyu.com/

你可能感兴趣的文章
访问百度的过程
查看>>
内存对齐.结构体对齐
查看>>
USB子系统gadget analyse
查看>>
selenium webdriver API
查看>>
关于Android开发中Arm、X86和Mips(草稿)
查看>>
Weblogic报错:Unsupported major.minor version 52.0
查看>>
Python_函数_参数
查看>>
排序算法之堆排序及其C语言代码实现
查看>>
Linux Shell基础 Bash常见命令 echo命令
查看>>
公开一个云计算和云存储的源代码.
查看>>
js点击出现二级菜单,点击二级菜单主菜单换成二级菜单
查看>>
Git远程操作详解(clone、remote、fetch、pull、push)
查看>>
jquery mobile 复选框和单选框
查看>>
cookie,session与中间键
查看>>
webstorm快捷键
查看>>
@Selector 的一些总结
查看>>
OpenJudge/Poj 1936 All in All
查看>>
orcale 之 数据完整性约束
查看>>
spring boot自定义properity
查看>>
<20180927>新开一篇章记录常用到的IT名词
查看>>