博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【设计模式】—-(16)观察者模式(行为型)
阅读量:4103 次
发布时间:2019-05-25

本文共 3486 字,大约阅读时间需要 11 分钟。

对自己说声对不起:大年初二去姥姥家玩了,所以迟更新了一天,罪过。。。

一、概述:

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。

这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

二、观察者模式所设计的角色:

         ●  抽象主题(Subject)角色:抽象主题角色把所有对观察者对象的引用保存在一个聚集(比如ArrayList对象)里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,抽象主题角色又叫做抽象被观察者(Observable)角色。

  ●  具体主题(ConcreteSubject)角色:将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者(Concrete Observable)角色。

  ●  抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口。

  ●  具体观察者(ConcreteObserver)角色:存储与主题的状态自恰的状态。具体观察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态 像协调。如果需要,具体观察者角色可以保持一个指向具体主题对象的引用。

适用场景
1) 当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
2) 当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。
3) 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望这些对象是紧密耦合的。

三、UML:

四、代码:

首先定义抽象的观察者:

//抽象观察者角色public interface Watcher{    public void update(String str);}

  然后定义抽象的主题角色,即抽象的被观察者,在其中声明方法(添加、移除观察者,通知观察者):

//抽象主题角色,watched:被观察public interface Watched{    public void addWatcher(Watcher watcher);    public void removeWatcher(Watcher watcher);    public void notifyWatchers(String str);}

  然后定义具体的观察者:

public class ConcreteWatcher implements Watcher{    @Override    public void update(String str)    {        System.out.println(str);    }}

  之后是具体的主题角色: 

import java.util.ArrayList;import java.util.List;public class ConcreteWatched implements Watched{    // 存放观察者    private List
list = new ArrayList
(); @Override public void addWatcher(Watcher watcher) { list.add(watcher); } @Override public void removeWatcher(Watcher watcher) { list.remove(watcher); } @Override public void notifyWatchers(String str) { // 自动调用实际上是主题进行调用的 for (Watcher watcher : list) { watcher.update(str); } }}

  编写测试类:

public class Test{    public static void main(String[] args)    {        Watched girl = new ConcreteWatched();                Watcher watcher1 = new ConcreteWatcher();        Watcher watcher2 = new ConcreteWatcher();        Watcher watcher3 = new ConcreteWatcher();                girl.addWatcher(watcher1);        girl.addWatcher(watcher2);        girl.addWatcher(watcher3);                girl.notifyWatchers("开心");    }}

在JAVA中对观察者模式的支持

  这里给出一个非常简单的例子,说明怎样使用JAVA所提供的对观察者模式的支持。在这个例子中,被观察对象叫做Watched;而观察者对象叫做Watcher。Watched对象继承自java.util.Observable类;而Watcher对象实现了java.util.Observer接口。另外有一个Test类扮演客户端角色。

  源代码

  被观察者Watched类源代码

public class Watched extends Observable{        private String data = "";        public String getData() {        return data;    }    public void setData(String data) {                if(!this.data.equals(data)){            this.data = data;            setChanged();        }        notifyObservers();    }        }

 

  观察者类源代码

public class Watcher implements Observer{        public Watcher(Observable o){        o.addObserver(this);    }        @Override    public void update(Observable o, Object arg) {                System.out.println("状态发生改变:" + ((Watched)o).getData());    }}

  测试类源代码

public class Test {    public static void main(String[] args) {                //创建被观察者对象        Watched watched = new Watched();        //创建观察者对象,并将被观察者对象登记        Observer watcher = new Watcher(watched);        //给被观察者状态赋值        watched.setData("start");        watched.setData("run");        watched.setData("stop");    }}

  Test对象首先创建了Watched和Watcher对象。在创建Watcher对象时,将Watched对象作为参数传入;然后Test对象调用Watched对象的setData()方法,触发Watched对象的内部状态变化;Watched对象进而通知实现登记过的Watcher对象,也就是调用它的update()方法。

你可能感兴趣的文章
Ubuntu下Adb调试Android找不到设备的解决方法
查看>>
Android DownloadManager 的使用
查看>>
Android DRM解析
查看>>
OMA DRM V1.0学习笔记
查看>>
移动通信知识之GSM
查看>>
android控件之DowloadManager
查看>>
Android调用系统内部的下载程序下载文件(二)
查看>>
DownloadManager下载管理类2.3新增API介绍
查看>>
在Android中创建一种新的输入法(Creating an Input Method))
查看>>
android避免弹出软键盘遮盖listview
查看>>
Android Jni代码示例讲解
查看>>
数码相机里的白平衡作用
查看>>
git中文安装教程
查看>>
IntelliJ IDEA 配置 Chrome 和 Firefox 浏览器
查看>>
Windows 安装配置 NVM
查看>>
CentOS7/RedHat7/OracleLinux7 安装 Oracle 12c 分区教程
查看>>
虚拟机 CentOS7/RedHat7/OracleLinux7 配置静态IP地址 Ping 物理机和互联网
查看>>
git rebase 和 merge 的区别
查看>>
indexOf 和 findIndex 的区别
查看>>
typeof 可以判断哪些类型?instanceof 做了什么?null为什么被typeof错误的判断为了‘object‘
查看>>