简介

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

它包含两个术语,主题(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. Luogu5058 [ZJOI2004]嗅探器

    $Luogu5058 [ZJOI2004]嗅探器 给定一张 \(n\) 个点, \(m\) 条边的无向图,和两点 \(s,\ t\) ,求 \(s\to t\) 编号最小的必经点(排除 \(s,\ t ...

  2. MongoDB install

    下载地址1:https://www.mongodb.org/dl/linux下载地址2:https://www.mongodb.com/download-center/community关于Mongo ...

  3. C语言中可变参数的函数(三个点,“...”)

    C语言中可变参数的函数(三个点,“...”) 本文主要介绍va_start和va_end的使用及原理. 在以前的一篇帖子Format MessageBox 详解中曾使用到va_start和va_end ...

  4. IS创新之路 -- 都昌公司赋能型HIT企业发展之路

    ◆◆前言 近日,上海瑞金医院对我司表示:“我院从2000年开始自主开发医院信息系统,走出了一条可持续的信息化发展之路.已建成五大系统,284个子系统.但我院仍然坚持在努力推进以电子病历为核心医院信息化 ...

  5. Linux配置外网访问mysql

    stream{    upstream abc{        server 192.168.8.249:3306;    }    server{        listen 9211 ; prox ...

  6. ubuntu 18.04安装pytorch、cuda、cudnn等

    版权声明:本文为博主原创文章,欢迎转载,并请注明出处.联系方式:460356155@qq.com ubuntu 16.04用了1年多了,18.04版已经发布也半年了,与时俱进,重装Linux系统,这里 ...

  7. 4.1 socket

    socket  背景概念 脑图结构 OSI 模型 socket 概念特性 脑图结构 理解示意图  额外补充 Socket是应用层与 TCP/IP协议族通信的中间软件抽象层,它是一组接口. 在设计模式中 ...

  8. MT【316】常数变易法

    已知数列$\{a_n\}$满足$a_1=0,a_{n+1}=\dfrac{n+2}{n}a_n+1$,求$a_n$ 解答:$\dfrac{a_{n+1}}{n(n+1)}=\dfrac{a_n}{n( ...

  9. 20165223 《信息安全系统设计基础》 实现mypwd

    一.学习pwd命令 1. pwd命令简介 英文原名:Print Working Directory 指令功能:打印出当前工作目录 执行权限:All User 指令所在路径:/usr/bin/pwd 或 ...

  10. python之路day06--python2/3小区别,小数据池的概念,编码的进阶str转为bytes类型,编码和解码

    python2#print() print'abc'#range() xrange()生成器#raw_input() python3# print('abc')# range()# input() = ...