简介

观察者属于行为型模式的一种, 又叫发布-订阅模式. 如果一个对象的状态发生改变,依赖他的对象都将发生变化, 那么这种情况就适合使用观察者模式.

它包含两个术语,主题(Subject),观察者(Observer), 主题管理一个观察者的列表, 并在状态发生变化时通知到他们.

实现层面上, 主题定义了一个观察者列表并可以管理这个列表(将观察者注册进去和撤销注册的行为), 同时定义了通知到所有观察者的行为.

Java类库有默认的观察者实现类Observer. 使用观察者模式的还有事件监听, RxJava等.

意图

定义对象之间的一对多依赖,当一个对象状态改变时,它的所有依赖都会收到通知并且自动更新状态。

类图

实现

一. 定义抽象观察者

/**
* 观察者抽象角色
*/
public interface MyObserver {
void update(Subject subject);
}

二. 定义抽象主题

/**
* 主题抽象角色
*/
public abstract class Subject {
private ArrayList<MyObserver> list = new ArrayList<MyObserver>(); public Subject register(MyObserver observer){
if(!list.contains(observer)){
list.add(observer);
}
return this;
} public Subject unRegister(MyObserver observer){
if(list.contains(observer)){
list.remove(observer);
}
return this;
} public final void notifyObservers(){
for (MyObserver item:list) {
item.update(this);
}
} /**
* 具体状态的变更
*/
abstract void change();
}

三. 定义具体主题

/**
* 具体主题角色
*/
@Data
public class ConcreteSubject extends Subject {
private String name;
public void change() {
this.setName("王多鱼");
super.notifyObservers();
}
}

四. 定义观察者的实现, 分别定义两个不同实现

public class UncleObserver implements MyObserver {
public void update(Subject subject) {
ConcreteSubject concreteSubject = (ConcreteSubject)subject;
System.out.println("UncleObserver 知道了: "+concreteSubject.getName());
}
} public class HentaiObserver implements MyObserver {
public void update(Subject subject) {
ConcreteSubject concreteSubject = (ConcreteSubject)subject;
System.out.println("HentaiObserver 知道了: "+concreteSubject.getName());
}
}

五. 调用, 首先注册观察者,然后调用主题的变更方法

// 实例化主题后为其注册了两个观察者的实例, 并最终调用主题的变更方法触发通知行为
public static void main(String[] args) {
new ConcreteSubject()
.register(new UncleObserver())
.register(new HentaiObserver())
.change();
}

总结

关键点: 定义通知到观察者的方法要注意, 如果有耗时严重的会阻塞其他观察者得到通知, 可以异步多线程实现; 避免循环引用;

观察者分推模式和拉模式, 推模式是指将主题的变更信息发送给观察者, 观察者可以用, 也可以不用. 拉模式则是将主题的引用发送给观察者, 观察者通过引用根据自己需要获取所需信息. 示例中使用的就是这种模式.

代码修改为推模式

// 观察者的方法接收具体信息
void update(String name); // 主题的通知方法做相应修改
public final void notifyObservers(){
for (MyObserver item:list) {
item.update("王多鱼");
}
}

设计模式九: 观察者模式(Observer Pattern)的更多相关文章

  1. 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)

    原文:乐在其中设计模式(C#) - 观察者模式(Observer Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 观察者模式(Observer Pattern) 作者:weba ...

  2. 二十四种设计模式:观察者模式(Observer Pattern)

    观察者模式(Observer Pattern) 介绍定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新. 示例有一个Message实体类,某些对象 ...

  3. [设计模式] 19 观察者模式 Observer Pattern

    在GOF的<设计模式:可复用面向对象软件的基础>一书中对观察者模式是这样说的:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新.当一个 ...

  4. c#设计模式之观察者模式(Observer Pattern)

    场景出发 一个月高风黑的晚上,突然传来了尖锐的猫叫,宁静被彻底打破,狗开始吠了,大人醒了,婴儿哭了,小偷跑了 这个过程,如果用面向对象语言来描述,简单莫过于下: public class Cat { ...

  5. 设计模式之观察者模式(Observer pattern)

    最近参加了一次面试,其中笔试题有一道编程题,在更换掉试题的描述场景后,大意如下: 上课铃声响起,学生A/B/C/D进入教室:下课铃声响起,学生A/B/C/D离开教室. 要求使用设计模式的思想完成铃与学 ...

  6. 【设计模式】观察者模式 Observer Pattern

    定义:观察者模式定义了对象之间的一对多依赖.当“主题”(Object)状态改变事,所有依赖它的“观察者”(Observer)都会受到通知并自动更新.主题支持观察者订阅和退订. 观察者模式提供了一种对象 ...

  7. 【UE4 设计模式】观察者模式 Observer Pattern

    概述 描述 定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新.观察者模式又叫做 发布-订阅(Publish/Subscribe)模式 模型-视图(M ...

  8. 设计模式-观察者模式(Observer Pattern)

    观察者模式(Observer Pattern):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己. 观察者 ...

  9. 设计模式 - 观察者模式(Observer Pattern) 详细说明

    观察者模式(Observer Pattern) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...

随机推荐

  1. @EnableWebMvc,WebMvcConfigurationSupport,WebMvcConfigurer和WebMvcConfigurationAdapter区别

    @EnableWebMvc是什么 直接看源码,@EnableWebMvc实际上引入一个DelegatingWebMvcConfiguration. @Retention(RetentionPolicy ...

  2. Linux内存都去哪了:(1)分析memblock在启动过程中对内存的影响

    关键词:memblock.totalram_pages.meminfo.MemTotal.CMA等. 最近在做低成本方案,需要研究一整块RAM都用在哪里了? 最直观的的就是通过/proc/meminf ...

  3. 《Java2 实用教程(第五版)》教学进程

    目录 <Java2 实用教程(第五版)>教学进程 预备作业1:你期望的师生关系是什么? 预备作业2 :学习基础和C语言基础调查 预备作业3:Linux安装及命令入门 第一周作业 第二周作业 ...

  4. cmd执行超大sql文件

    osql -S 127.0.0.1 -U sa -P 123456 -i d:\test.sql osql为SQL Server的命令,要在cmd中执行该命令,一般安装完SQL Server后该命令对 ...

  5. django 之 stark组件

    ----------------------------------------------------------------烦恼没完没了,内心动荡不安,呜呼哀哉. 一.有个特殊的需求,需要用sta ...

  6. spring boot 操作MySQL pom添加的配置

    1 在项目中的pom.xml配置文件添加依赖 <!--MySQL依赖 --> <dependency> <groupId>mysql</groupId> ...

  7. OpenCV__cv::Mat::step

    step[0]是矩阵中一行元素的字节数 step[1]是矩阵中一个元素的字节数(elemSize) step1 = step / elemSize1,elemSize1是元素的每个通道所占的字节数 s ...

  8. Andriod App类型简介

    App三种类型与区别 原生应用程序:(Native App) 原生APP是什么?原生APP就是利用Android.iOS平台官方的开发语言.开发类库.工具进行开发.比如安卓的java语言,iOS的ob ...

  9. Netty 5 io.netty.util.IllegalReferenceCountException 异常

    异常信息 io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1 原因 handler 继承了 SimpleChan ...

  10. CF1120D(神奇的构造+最小生成树)

    考虑把树展开,单独把叶子节点拿出来 于是可以把控制点\(x\)的,抽象成是在它叶子节点间连权值为\(c_x\)的边 显然只用在\(x\)子树的最左边的叶子节点和最右边的叶子节点的下一个节点连边(最后一 ...