Observer模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。

  Observer模式提供给关联对象一种同步通信的手段,使某个对象与依赖它的其他对象之间保持状态同步。

  观察者模式的结构

  观察者模式的角色和职责

  1、Subject(被观察者)
      被观察的对象。当需要被观察的状态发生变化时,需要通知队列中所有观察者对象。Subject需要维持(添加,删除,通知)一个观察者对象的队列列表。

  2、ConcreteSubject
      被观察者的具体实现。包含一些基本的属性状态及其他操作。

  3、Observer(观察者)
      接口或抽象类。当Subject的状态发生变化时,Observer对象将通过一个callback函数得到通知。

  4、ConcreteObserver
      观察者的具体实现。得到通知后将完成一些具体的业务逻辑处理。

  而被观察者想要起作用,就必须继承java.util包下的Observable类,这是它的方法,后面会有介绍

构造方法摘要
Observable()
          构造一个带有零个观察者的 Observable。
方法摘要
 void addObserver(Observer o)

          如果观察者与集合中已有的观察者不同,则向对象的观察者集中添加此观察者。
protected
 void
clearChanged()

          指示对象不再改变,或者它已对其所有的观察者通知了最近的改变,所以 hasChanged 方法将返回
false
 int countObservers()

          返回 Observable 对象的观察者数目。
 void deleteObserver(Observer o)

          从对象的观察者集合中删除某个观察者。
 void deleteObservers()

          清除观察者列表,使此对象不再有任何观察者。
 boolean hasChanged()

          测试对象是否改变。
 void notifyObservers()

          如果 hasChanged 方法指示对象已改变,则通知其所有观察者,并调用
clearChanged 方法来指示此对象不再改变。
 void notifyObservers(Object arg)

          如果 hasChanged 方法指示对象已改变,则通知其所有观察者,并调用
clearChanged 方法来指示此对象不再改变。
protected
 void
setChanged()

          标记此 Observable 对象为已改变的对象;现在 hasChanged 方法将返回
true

  下面写一个例子:新建一个Person类

 public class Person {
private String name;
private String sex;
private int age; public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}

  我们要做的就是监听成员变量name,sex,age的变化,在数值变化是,执行我们的操作,所以Person就是被观察者,所以server必须继承Observable,而Observable中有这三个方法:

  1、notifyObservers() : 如果 hasChanged 方法指示对象已改变,则通知其所有观察者,并调用 clearChanged 方法来指示此对象不再改变。

    这个方法是通知观察者被观察者是否改变的,只要hasChanged()方法指示的对象改变,就会调用观察者中的方法。

  2、hasChanged() : 测试对象是否改变。

  3、setChanged() :标记此 Observable 对象为已改变的对象;现在 hasChanged 方法将返回 true

  所以,如果想观察成员变量是否改变,就要在set方法中,执行setChanged()与notifyObservers()

  所以,被观察者应该改为:

 import java.util.Observable;

 public class Person extends Observable{
private String name;
private String sex;
private int age; public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
this.setChanged();
this.notifyObservers();
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
this.setChanged();
this.notifyObservers();
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
this.setChanged();
this.notifyObservers();
}
}

  有了被观察者,就要有观察者,观察者必须实现java.util包下的Observer接口,并重写update(Observable o, Object arg)方法,当被观察者改变时,就会执行update()方法

 import java.util.Observable;
import java.util.Observer; public class MyObserver implements Observer { @Override
public void update(Observable o, Object arg) {
System.out.println("对象已改变");
} }

  现在,就可以执行看一看了。不过在执行set()方法之前一定要使用addObserver(Observer o) 这个方法注册观察者,不然不会生效。

 public class MainClass {
public static void main(String[] args) {
Person person = new Person();
//注册观察者
person.addObserver(new MyObserver());
person.setName("小明");
person.setSex("男");
person.setAge(18);
}
}

输出结果是这样的:

      对象已改变
      对象已改变
      对象已改变

  同时,notifyObservers()为什么是s结尾呢,因为我们可以同时注册多个观察者,这样写

 public class MainClass {
public static void main(String[] args) {
Person person = new Person();
//注册观察者
person.addObserver(new MyObserver());
person.addObserver(new MyObserver()); person.setName("小明");
person.setSex("男");
person.setAge(18);
}
}

  我们注册两个观察者,两个都会生效,结果就变为了:    

      对象已改变
     对象已改变
     对象已改变
     对象已改变
     对象已改变
     对象已改变

  还有三个方法deleteObserver(Observer o) ,deleteObservers() ,countObservers()

 public class MainClass {
public static void main(String[] args) {
Person person = new Person();
//注册观察者
MyObserver myObserver = new MyObserver();
person.addObserver(myObserver);
person.addObserver(new MyObserver());
//获得当前对象已注册的观察者数目
person.countObservers();
//删除指定的一个观察者
person.deleteObserver(myObserver);
//删除该对象全部观察者
person.deleteObservers(); person.setName("小明");
person.setSex("男");
person.setAge(18);
}
}

 

  观察者模式的典型应用

    1、侦听事件驱动程序设计中的外部事件

    2、侦听/监视某个对象的状态变化

    3、发布者/订阅者(publisher/subscriber)模型中,当一个外部事件(新的产品,消息的出现等等)被触发时,通知邮件列表中的订阅者

java设计模式-----9、观察者模式的更多相关文章

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

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

  2. java设计模式之观察者模式以及在java中作用

    观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式.模型-视图(Model/View)模式.源-监听器(Source/Listener)模式或从属者(Dependen ...

  3. java设计模式02观察者模式

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

  4. java设计模式之观察者模式

    观察者模式 观察者模式(有时又被称为发布(publish )-订阅(Subscribe)模式.模型-视图(View)模式.源-收听者(Listener)模式或从属者模式)是软件设计模式的一种.在此种模 ...

  5. JAVA设计模式 之 观察者模式

    简介: 观察者模式是JDK中最多的设计模式之一,非常有用,观察者模式介绍了一对多的依赖关系及松耦合,有了观察者,你将会消息灵通. 认识观察者模式,看一个报纸.杂志订阅是怎么回事: (1). 报社的业务 ...

  6. 折腾Java设计模式之观察者模式

    观察者模式 Define a one-to-many dependency between objects where a state change in one object results in ...

  7. JAVA设计模式之观察者模式 - Observer

    有趣的事情发生时,可千万别错过了!有一个模式可以帮你的对象知悉现况,不会错过该对象感兴趣的事.对象甚至在运行时可决定是否要继续被通知.有了观察者,你将会消息灵通. 介绍 观察者模式的定义: 在对象之间 ...

  8. JAVA设计模式 之 观察者模式(JDK内置实现)

    简介:使用JAVA内置的帮你搞定观察者模式. 1. 先把类图放在这里: (1). Observable类追踪所有的观察者,并通知他们. (2). Observer这个接口看起来很熟悉,它和我们之前写的 ...

  9. java设计模式之观察者模式(9)

    Java观察者模式的浅析 简单地说,观察者模式定义了一个一对多的依赖关系,让一个或多个观察者对象监察一个主题对象.这样一个主题对象在状态上的变化能够通知所有的依赖于此对象的那些观察者对象,使这些观察者 ...

  10. java设计模式:观察者模式

    package Observer; public class Test { /** * client测试类别 * 观察者模式一般由四部分组成: * 1摘要观察员(教科书被称为一般"Subje ...

随机推荐

  1. 磁盘IO的概念

    转载自:http://blog.csdn.net/letterwuyu/article/details/53542291 在数据库优化和存储规划过程中,总会提到IO的一些重要概念,在这里就详细记录一下 ...

  2. 创建一个简单的maven的web程序

    最近学习Hadoop,发现学习要想用hadoop作为后台运行web程序,必须应用maven,所以学习了今天学习了一下maven,然后搭建了一个简单的web程序 首先我使用的是eclipse中自带的ma ...

  3. C#-WebForm-组合查询(Queryable延迟查询、Intersect交集)、分页展示基础

    组合查询: 方法一:Queryable<> 延迟查询 其特点是:读到词句代码时不会立即执行,而是在进行数据绑定时执行 优点:此期间可以进行添加查询条件,以减少数据库查询内容,来减少内存占用 ...

  4. Python库大全

    网络 urllib -网络库(stdlib). requests -网络库. grab – 网络库(基于pycurl). pycurl – 网络库(绑定libcurl). urllib3 – Pyth ...

  5. IntelliJ IDEA 18 周岁,吐血推进珍藏已久的必装插件

    IntelliJ IDEA是目前最好最强最智能的Java IDE,前几天,他刚刚年满18岁.  本文,给大家推荐几款我私藏已久的,自己经常使用的,可以提升代码效率的插件. IDEA插件简介 常见的I ...

  6. vue 在 html 中自定义 tag

    v-if,v-for,:key,:style,v-text,@click,:src,:poster,:class,:href

  7. Java类型简介

    1 java基本数据类型 1.1 基本数据类型 java的基础数据类型有多少个,每个在内存的分配是多少呢? 类型 分配字节 byte 1 short 2 char 2 int 4 long 8 ref ...

  8. 【HNOI2019】部分题简要题解

    题意懒得写了 LOJ Day 1 T1 鱼 个人做法比较猎奇,如果有哪位大佬会证明能分享一下的话感激不尽. 题解:枚举鱼尾和鱼身的交点D,将所有其他点按照到D的距离排序,距离相同的分一组. 感性的理解 ...

  9. 博客主题皮肤探索-主题的本地化和ChromeCacheView使用

    还有前言 用了大佬的主题之后,有些资源是无法在暴露的接口处更改的,需要自己去css更改.但后台给的都是压缩过的,找起来比较困难,所以特意记录了这篇. 本地资源替换 侧边栏: .introduce-bo ...

  10. 数据库其他注入思路 - 万能密码 - cookie注入 -搜索型注入

    另类登录注入形式: 经常有一类验证(ASP,PHP,JSP均存在),先判断user是否存在,ASP为例子:"select password from admin where user_nam ...