java设计模式--观察者模式(Observer)

java设计模式--观察者模式(Observer)

观察者模式的定义:
定义对象间的一种一对多的依赖关系。当一个对象的状态发生改变时,所有依赖于它的对象
都得到通知并被自动更新。

认识观察者模式:
1.目标和观察者之间的关系:
按照模式的定义,目标和观察者之间是典型的一对多的关系。
但是要注意,如果观察者只有一个,也是可以的,这样就变相的实现了目标和观察者之间
一对一的关系。

2.观察者模式中有四种对象:
Subject(目标对象),
Observer(定义观察者接口),
ConcreteSubject(具体的目标实现对象),
ConcreteObserver(观察者的具体实现对象)

一个目标可以有任意多个观察者对象,一旦目标的状态发生了改变,所有注册的观察者都会等到通知,
然后各个观察者会对通知作出相应的响应,执行相应的业务功能处理,并使自己的状态和目标的状态保存一致。

Subject:目标对象接口,提供如下功能:
a.一个目标可以被多个观察者观察
b.目标提供对观察者注册和退订的维护
c.当目标的状态发生变化时,目标负责通知所有注册的,有效的观察者

Observer:观察者的接口,提供目标通知时对应的更新方法,这个方法进行相应的业务处理,可以在这个方法
里面回调目标对象,以获取目标对象的数据。

ConcreteSubject:具体的目标实现对象,用来维护目标状态,当目标对象的状态发生改变时,通知
所有注册的、有效的观察者,让观察者执行相应的处理。

ConcreteObserver:观察者的具体实现对象,用来接收目标的通知,并进行相应的后续处理,比如更新
自身的状态以保持和目标的相应状态一致。

举例:

import java.util.ArrayList;
import java.util.List;/*** 功能:*         目标对象,作为被观察者,它知道观察它的观察者,并提供注册和删除观察者的接口* @author Administrator**/
public class Subject
{//用来保存注册的观察者对象,也就是报纸的订阅者private List<Observer> readers = new ArrayList<Observer>();/*** 功能:*         注册观察者对象(报纸的读者需要向报社订阅,先要注册)* @param observer 观察者对象*/public void attach(Observer reader){readers.add(reader);}/*** 功能:*         删除观察者对象(报纸的读者可以取消订阅)* @param observer*/public void detach(Observer reader){readers.remove(reader);}/*** 功能:*         通知所有的观察者*         (当有报纸出版后,就要主动的送到读者手中,相当于通知读者)*/protected void notifyAllObservers(){for(Observer reader : readers){reader.update(this);}}
}

/*** 功能:*         具体的目标对象,负责把有关状态存入到相应的观察者对象*         并在自己状态发生改变时,通知各个观察者*         (报纸对象)* @author Administrator**/
public class NewPaper extends Subject
{//报纸的具体内容private String content;/*** 功能:*         获取报纸的具体内容* @return*/public String getContent(){return content;}/*** 功能:*         设置报纸的具体内容,相当于出版报纸* @param content*/public void setContent(String content){this.content = content;//通知所有注册的读者this.notifyAllObservers();}
}

/*** 功能:*         观察者接口,定义一个更新的接口给那些在目标发生改变的时候被通知的对象*         (报纸的读者)* @author Administrator**/
public interface Observer
{/*** 功能:*         更新的接口* @param subject 传入目标对象,方便获取相应的目标对象的状态*/public void update(Subject subject);
}

/*** 功能:*         具体的观察者对象,实现更新的方法,使自身的状态和目标的状态保存一致*         (真正的读者)* @author Administrator**/
public class Reader implements Observer
{//读者的姓名private String name;@Overridepublic void update(Subject subject){//这里采用拉的方式System.out.println(name + "收到报纸,内容为: "+ ((NewPaper)subject).getContent());}public String getName(){return name;}public void setName(String name){this.name = name;}
}

public class Client
{public static void main(String[] args){//创建一个报纸,作为被观察者NewPaper subject = new NewPaper();//创建阅读者,也就是观察者Reader reader1 = new Reader();reader1.setName("罗纳尔多");Reader reader2 = new Reader();reader2.setName("贝克汉姆");//注册观察者
        subject.attach(reader1);subject.attach(reader2);subject.setContent("世界杯要开始了哦.....");}
}

对上面的模式进行讲解:
一、目标和观察者之间的关系
按照模式的定义,目标和观察者之间是典型的一对多的关系。
但是,观察者也可以只有一个,这样就实现了目标和观察者之间一对一的关系。

同样,一个观察者可以观察多个目标。

观察者模式中的: 推模型和拉模型

推模型:
目标对象主动向观察者推送目标的详细信息,不管观察者是否需要,推送的信息通常是
目标对象的全部或部分数据

拉模型:
目标对象在通知观察者的时候,只传递少量信息。如果观察者需要更具体的信息,
由观察者主动到目标对象中获取,相当于观察者从目标对象中拉数据。

将上面的代码通过推模型进行实现:

import java.util.ArrayList;
import java.util.List;/*** 功能:*         目标对象,作为被观察者,使用推模型* @author Administrator**/
public class Subject
{    //用来保存注册的观察者对象(报纸订阅者)private List<Observer> readers = new ArrayList<Observer>();/*** 功能:*         注册观察者对象(报纸的读者需要向报社订阅,先要注册)* @param observer 观察者对象*/public void attach(Observer reader){readers.add(reader);}/*** 功能:*         删除观察者对象(报纸的读者可以取消订阅)* @param observer*/public void detach(Observer reader){readers.remove(reader);}/*** 功能:*         通知所有的观察者*         (当有报纸出版后,就要主动的送到读者手中,相当于通知读者)*/protected void notifyAllObservers(String content){for(Observer reader : readers){reader.update(content);}}
}

public class NewsPaper extends Subject
{private String content;public String getContent(){return content;}public void setContent(String content){this.content = content;//通知所有注册的观察者(读者)this.notifyAllObservers(content);}
}

/*** 功能:*         观察者(报纸的读者)* @author Administrator**/
public interface Observer
{/*** 功能:*         被通知的方法,直接把报纸的内容推送过来* @param content*/public void update(String content);
}

public class Reader implements Observer
{//读者的姓名private String name;@Overridepublic void update(String content){//这里采用推的方式System.out.println(name + "收到报纸了,内容是:" + content);}public String getName(){return name;}public void setName(String name){this.name = name;}
}

public class Client
{public static void main(String[] args){//创建一个报纸,作为被观察者NewsPaper subject = new NewsPaper();//创建阅读者,也就是观察者Reader reader1 = new Reader();reader1.setName("罗纳尔多");Reader reader2 = new Reader();reader2.setName("贝克汉姆");//注册观察者
        subject.attach(reader1);subject.attach(reader2);subject.setContent("世界杯要开始了哦.....");}
}

两种模型的比较:(1)推模型是假定目标对象知道观察者需要的数据;而拉模型是目标对象不知道观察者具体
需要什么数据,没有办法的情况下,把自身传给观察者,让观察者自己去按需取值。
(2)推模型可能会使得观察者对象难以复用,因为观察者定义的update方法是按需而定义的,
可能无法兼顾没有考虑到的使用情况。这就意味着出现新情况的时候,就可能需要提供新的update方法,
或者干脆重新实现观察者。java中的观察者在java.util包里面有一个类Observable,实现了大部分目标的功能。
java.util包里面有一个类Observer,其中定义了update的方法,就是观察者的接口

import java.util.Observable;public class NewsPaper extends Observable
{//报纸的具体内容private String content;/*** 功能:*         获取报纸的具体内容* @return*/public String getContent(){return content;}/*** 功能:*         设置报纸的具体内容,相当于出版报纸* @param content*/public void setContent(String content){this.content = content;//通知观察者this.setChanged();this.notifyObservers(this.content);//采用推的方法
        }
}

import java.util.Observable;
import java.util.Observer;/*** 功能:*         观察者(读者)* @author Administrator**/
public class Reader implements Observer
{private String name;public String getName(){return name;}public void setName(String name){this.name = name;}@Overridepublic void update(Observable arg0, Object obj){System.out.println(name + "收到报纸了,内容为:"+obj);}
}

public class Client
{public static void main(String[] args){//创建一个报纸,作为被观察者NewsPaper subject = new NewsPaper();//创建阅读者,也就是观察者Reader reader1 = new Reader();reader1.setName("罗纳尔多");Reader reader2 = new Reader();reader2.setName("贝克汉姆");//注册阅读者
        subject.addObserver(reader1);subject.addObserver(reader2);//出版报纸subject.setContent("世界杯要开始了咯");}
}

观察者模式的本质:触发联动

当修改目标对象的状态的时候,就会触发相应的通知,然后会循环的调用所有注册的观察者对象
的相应方法,其实就相当于联动调用这些观察者的方法。

这个联动还是动态的,可以通过注册和取消注册来控制观察者,因而可以可以在程序运行期间,
通过动态的控制观察者,来变相地实现添加和删除某些功能处理,这些功能就是观察者在update的
时候执行的功能。

转载于:https://www.cnblogs.com/baiduligang/p/4247420.html

java设计模式--观察者模式(Observer)相关推荐

  1. Java设计模式—观察者模式(Observer pattern)

    故事: 小雪是一个非常漂亮的女孩,漂亮的女孩总是有很多的追求者,而且追求者的队伍在不断的变动,随时有人进入这个队伍,也有人退出.男孩们追求女孩时总是表现出120%的关心,当小雪私自游玩时总是不断收到追 ...

  2. 设计模式-观察者模式(Observer)-Java

    设计模式-观察者模式(Observer)-Java 目录 文章目录 1.前言 2.示例案例-多人联机对战游戏的设计 3.观察者模式概述 3.1.观察者模式定义 3.2.观察者模式结构 3.3.观察者模 ...

  3. Java设计模式-观察者模式(订阅发布模式)

    Java设计模式-观察者模式(订阅发布模式) 一起来看 会了就当复习丫,不会来一起来看看吧. 很喜欢一句话:"八小时内谋生活,八小时外谋发展". 如果你也喜欢,让我们一起坚持吧!! ...

  4. 设计模式 - 观察者模式(Observer Pattern) Java内置 用法

    观察者模式(Observer Pattern) Java内置 用法 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26601659 ...

  5. java设计模式 观察者模式_理解java设计模式之观察者模式

    在生活实际中,我们经常会遇到关注一个事物数据变化的情况,例如生活中的温度记录仪,当温度变化时,我们观察它温度变化的曲线,温度记录日志等.对于这一类问题,很接近java设计模式里面的"观察者模 ...

  6. JAVA 设计模式 观察者模式

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

  7. java设计模式观察者模式吗_Java设计模式之观察者模式原理与用法详解

    Java设计模式之观察者模式原理与用法详解 本文实例讲述了Java设计模式之观察者模式原理与用法.分享给大家供大家参考,具体如下: 什么是观察者模式 可以这么理解: 观察者模式定义了一种一对多的依赖关 ...

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

    设计模式-观察者模式 观察者模式是使用频率最高的设计模式之一,它用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应作出反应.在观察者模式中,发生改变的对象称为观 ...

  9. java设计模式---观察者模式

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

最新文章

  1. 用Unity和C#创建在线多人游戏学习教程
  2. 在word中的公式以代码形式体现在web上的方法
  3. hadoop搭建_hadoop分布式搭建之虚拟机克隆
  4. 机器学习recall含义_机器学习的业务含义
  5. java jar apktool,ShakaApkTool.jar v3.0.0(反编译显示中文的apktool)下载
  6. DNS在企业网络中的应用(一)
  7. 阶段1 语言基础+高级_1-3-Java语言高级_05-异常与多线程_第5节 线程池_1_线程池的概念和原理...
  8. 软件工程课程实践-可行性研究报告
  9. C语言再学习-- 大端小端详解(转)
  10. 古建筑数字化影像采集技术分析
  11. 什么是视频监控平台的平台对接
  12. 今天是2012年8月14日
  13. 分布式文件系统(DFS)浅析
  14. 制作html语言网站全攻略,(网页制作HTML代码全攻略.doc
  15. NOIP2009提高组复赛原题题解——Proking
  16. 【icon图标】icon字体图标的下载与使用
  17. 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(11.2)- FlexSPI NOR连接方式大全(RT1060/1064(SIP))...
  18. excel shell合成_shell快速合并多个Excel表格
  19. Python面向过程编程主要知识
  20. esp8266设置sta失败_ESP8266的AP模式与STA模式简单测试

热门文章

  1. 数据仓库、数据湖、流批一体,终于有大神讲清楚了!
  2. 老弟,Redis 6.0 除了多线程,别忘了这个牛逼特性!
  3. 在Spring事务管理下,Synchronized为啥还线程不安全?
  4. “RPC 好,还是 RESTful 好?” 不要选错了!
  5. 快速开发一个自定义 Spring Boot Starter ,希望你也会
  6. RESTful Web 服务 - 缓存
  7. Andriod --- JetPack (一):初识 JetPack
  8. Android --- 怎么设置 EditText 控件中光标默认位置,当 EditText 里有文字的时候,光标跑到了最前面
  9. IDEA_Spring Data JPA有关报错Cannot resolve table 'XXX'
  10. db2分页查询语句优化_面试官:数据量很大,分页查询很慢,怎么优化?