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; @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)的更多相关文章
- 【设计模式】Java设计模式 - 观察者模式
[设计模式]Java设计模式 - 观察者模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 @一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长 ...
- 设计模式 - 观察者模式(Observer Pattern) Java内置 用法
观察者模式(Observer Pattern) Java内置 用法 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26601659 ...
- JAVA 设计模式 观察者模式
用途 观察者模式 (Observer) 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象. 这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 观 ...
- Java设计模式--观察者模式到监听器
观察者模式是对象的行为模式.又叫做发布-订阅模式.模型-视图模式.源-监听器模式. 抽象主题角色:主题角色将所有对观察者对象的引用到保存在一个集合里,每个主题都可以拥有任意数量的观察者.抽象主题提供一 ...
- 设计模式 - 观察者模式(Observer Pattern) 详细说明
观察者模式(Observer Pattern) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...
- 设计模式 - 观察者模式(Observer Pattern) 详细解释
观察者模式(Observer Pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...
- 设计模式-观察者模式(Observer Pattern)
观察者模式(Observer Pattern):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己. 观察者 ...
- Java设计模式の观察者模式(推拉模型)
目录: 一.观察者定义 二.观察者模式的结构(推模式实现) 三.推模型和拉模型(拉模式实现) 四.JAVA提供的对观察者模式的支持 五.使用JAVA对观察者模式的支持(自带推模式实现实例) 一.观察者 ...
- Java设计模式-观察者模式(Observer)
包括这个模式在内的接下来的四个模式,都是类和类之间的关系,不涉及到继承,学的时候应该 记得归纳,记得本文最开始的那个图.观察者模式很好理解,类似于邮件订阅和RSS订阅,当我们浏览一些博客或wiki时, ...
随机推荐
- UNIX网络编程——带外数据
许多传输层有带外数据的概念,它有时也称为经加速数据.其想法是一个连接的某端发生了重要的事情,而且该端希望迅速通告其对端.这里"迅速"意味着这种通知应该在已排队等待发送的任何&quo ...
- 如何在Cocos2D 1.0 中掩饰一个精灵(三)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 尝试编译运行,在你每一次点击屏幕的时候,你将看到我可爱的妻子制作 ...
- 【一天一道LeetCode】#115. Distinct Subsequences
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...
- Linux IPC实践(1) -- 概述
进程的同步与互斥 进程同步: 多个进程需要相互配合共同完成一项任务. 进程互斥: 由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的这种关系为进程的互斥;系统中某些 ...
- ios入门OC_UI晋级学什么?
1. OC 语法初步, 你可能学到面向对象最近本的概念, 并且可以大致的建立几个自以为是的类,但这仅仅是开始. 你知道为什么面向对象要有3大特性么.知道他们是用到什么设计模式的么 2. 你可能学到了N ...
- 程序员的软实力武器-star法则
hhh 程序员的表达能力一直被诟病,尤其面试讲述自己的项目的时候 下面的star原则能够帮助你: 所谓STAR原则,即Situation(情景).Task(任务).Action(行动)和Result( ...
- 认识一下Android 事件分发机制
1.引子 由于android是采用分层布局(可以想象成PS时的图层概念一样),这样才可以在有限大小的手机屏幕上完成一些复杂的操作.当手指点击屏幕开始,这些动作在各层之间如何传递?就引出了Android ...
- Ubuntu_ROS中应用kinect v2笔记
Ubuntu_ROS中应用kinect v2笔记 个人觉得最重要的资料如下: 1. Microsoft Kinect v2 Driver Released http://www.ros.org/new ...
- Linux用户管理命令(第二版)
添加用户 1.useradd -设置选项 用户名 [-D 查看缺省参数 ] 选项: u: UID [必须是系统中没有的] g:缺省所属用户组GID[最好有] G: 指定用户所属多个组[可以指定这个用户 ...
- 【60】Spring总结之基础架构(1)
为什么用Spring? Spring一直贯彻并遵守"好的设计优于具体实现,代码应易于测试",这一理念,并最终带给我们一个易于开发.便于测试而又功能齐全的开发框架.概括起来Sprin ...