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;

    @Override
    public 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;

    @Override
    public 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;
    }

    @Override
    public 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的

时候执行的功能。

java设计模式--观察者模式(Observer)的更多相关文章

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

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

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

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

  3. 设计模式 - 观察者模式(Observer Pattern) 详细解释

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

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

    包括这个模式在内的接下来的四个模式,都是类和类之间的关系,不涉及到继承,学的时候应该 记得归纳,记得本文最开始的那个图.观察者模式很好理解,类似于邮件订阅和RSS订阅,当我们浏览一些博客或wiki时, ...

  5. Java设计模式 - 观察者模式

    定义 观察者模式属于对象行为型模式. 在对象之间定义一对多的依赖,这样一来当一个对象改变状态,依赖它的对象都会收到通知并自动更新. 优点 1.  主题和观察者之间抽象耦合.无论什么对象主要实现了特定的 ...

  6. 我的Java设计模式-观察者模式

    相信大家都有看过<喜洋洋与灰太狼>,说的是灰太狼和羊族的"斗争",而每次的结果都是灰太狼一飞冲天,伴随着一句"我还会回来的......".为灰太狼感 ...

  7. [工作中的设计模式]观察者模式observer

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

  8. C#设计模式——观察者模式(Observer Pattern)1

    一.概述在软件设计工作中会存在对象之间的依赖关系,当某一对象发生变化时,所有依赖它的对象都需要得到通知.如果设计的不好,很容易造成对象之间的耦合度太高,难以应对变化.使用观察者模式可以降低对象之间的依 ...

  9. C#设计模式——观察者模式(Observer Pattern)

    一.概述在软件设计工作中会存在对象之间的依赖关系,当某一对象发生变化时,所有依赖它的对象都需要得到通知.如果设计的不好,很容易造成对象之间的耦合度太高,难以应对变化.使用观察者模式可以降低对象之间的依 ...

随机推荐

  1. CSharpGL(9)解析OBJ文件并用CSharpGL渲染

    CSharpGL(9)解析OBJ文件并用CSharpGL渲染 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码中包含10多个独立的Demo ...

  2. [NodeJS] Hello World 起步教程

    概述: 做数据,免不了需要展示数据,数据可视化是必须经历的步骤. 本文将提供一个NodeJS的起步教程,是笔者这两天探索的小结. 正文:  1. 为什么使用NodeJS 究竟是以B/S还是C/S的架构 ...

  3. nyoj 776 删除元素

    删除元素 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描述 题意很简单,给一个长度为n的序列,问至少删除序列中多少个数,使得删除后的序列中的最大值<= 2*最小值 输 ...

  4. CSS3的calc()使用

    CSS3的calc()使用 calc是英文单词calculate(计算)的缩写,是css3的一个新增的功能,用来指定元素的长度.比如说,你可以使用calc()给元素的border.margin.pad ...

  5. Unity4升级Unity5后Image Effects问题

    Assets\Editor\Image Effects\CameraMotionBlurEditor.js 会出现Ambiguous reference 'preview'错误提示,解决方法 查找pr ...

  6. 模糊测试——强制发掘安全漏洞的利器(Jolt 大奖精选丛书)

    模糊测试——强制发掘安全漏洞的利器(Jolt 大奖精选丛书) [美]Sutton, M.Greene, A.Amini, P. 著 段念赵勇译 ISBN 978-7-121-21083-9 2013年 ...

  7. 本地Yum

    1. mkdir xxx #新建文件夹 (新建一个挂载需要的文件夹) 2.配置本地yum源(挂载光盘) 3.进入 yum.repos.d 4.ls (查看当前文件夹全部的文件) 并 mv 修改   除 ...

  8. 在win8中如何实现下拉刷新的功能

      现在我以listview为例来讲述下拉刷新的功能! 在xaml中设置listview一定要设置一个这样的属性,IsSwipeEnabled=false,然后再listview控件的前面要布局下拉刷 ...

  9. dp与px之间的转换

    代码如下: package com.example.fxvideo.utils; import android.content.Context; public class DensityUtils { ...

  10. Maven初学之经验浅谈

    关于Maven这个东西,我不做任何评价. 直接上资料,适合初学者 推荐资料 http://www.imooc.com/learn/443 www.imooc.com/article/15037 还有个 ...