网站首页 > 文章中心 > 其它

观察者模式代码java

作者:小编 更新时间:2023-09-06 23:10:09 浏览量:437人看过

java设计模式-回调、事件监听器、观察者模式

转自( )

背景

关于设计模式,之前笔者写过工厂模式,最近在使用gava ListenableFuture时发现事件监听模型特别有意思,于是就把事件监听、观察者之间比较了一番,发现这是一个非常重要的设计模式,在很多框架里扮演关键的作用.

回调函数

为什么首先会讲回调函数呢?因为这个是理解监听器、观察者模式的关键.

观察者模式代码java-图1

什么是回调函数

所谓的回调,用于回调的函数. 回调函数只是一个功能片段,由用户按照回调函数调用约定来实现的一个函数. 有这么一句通俗的定义:就是程序员A写了一段程序(程序a),其中预留有回调函数接口,并封装好了该程序.程序员B要让a调用自己的程序b中的一个方法,于是,他通过a中的接口回调自己b中的方法.

举个例子:

这里有两个实体:回调抽象接口、回调者(即程序a)

回调接口(ICallBack )

观察者模式代码java-图2

public interface ICallBack {

public void callBack();

}

回调者(用于调用回调函数的类)

public class Caller {

回调测试:

public static void main(String[] args) {

Caller call = new Caller();

call.call(new ICallBack(){

控制台输出:

start...

终于回调成功了!

end...

还有一种写法

或实现这个ICallBack接口类

class CallBackC implements ICallBack{

@Override

public void callBack() {

System.out.println("终于回调成功了!");

有没有发现这个模型和执行一个线程,Thread很像. 没错,Thread就是回调者,Runnable就是一个回调接口.

new Thread(new Runnable(){

public void run() {

System.out.println("回调一个新线程!");

}}).start();

Callable也是一个回调接口,原来一直在用. 此时此刻呢我们开始讲事件监听器

事件监听模式

什么是事件监听器

监听器将监听自己感兴趣的事件一旦该事件被触发或改变,立即得到通知,做出响应.例如:android程序中的Button事件.

java的事件监听机制涉及到 事件源,事件监听器,事件对象 三个组件,监听器一般是接口,用来约定调用方式

当事件源对象上发生操作时,它将会调用事件监听器的一个方法,并在调用该方法时传递事件对象过去

事件监听器实现类,通常是由开发人员编写,开发人员通过事件对象拿到事件源,从而对事件源上的操作进行处理

举个例子

这里我为了方便,直接使用jdk,EventListener 监听器,感兴趣的可以去研究下源码,非常简单.

监听器接口

public interface EventListener extends java.util.EventListener {

//事件处理

public void handleEvent(EventObject event);

事件对象

public class EventObject extends java.util.EventObject{

private static final long serialVersionUID = 1L;

public EventObject(Object source){

super(source);

public void doEvent(){

System.out.println("通知一个事件源 source :"+ this.getSource());

事件源

事件源是事件对象的入口,包含监听器的注册、撤销、通知

public class EventSource {

//监听器列表,监听器的注册则加入此列表

private VectorEventListener ListenerList = new VectorEventListener();

//注册监听器

public void addListener(EventListener eventListener){

ListenerList.add(eventListener);

//撤销注册

public void removeListener(EventListener eventListener){

ListenerList.remove(eventListener);

//接受外部事件

public void notifyListenerEvents(EventObject event){

for(EventListener eventListener:ListenerList){

eventListener.handleEvent(event);

测试执行

EventSource eventSource = new EventSource();

控制台显示:

通知一个事件源 source :openWindows

doOpen something...

到这里你应该非常清楚的了解,什么是事件监听器模式了吧. 那么哪里是回调接口,哪里是回调者,对!EventListener是一个回调接口类,handleEvent是一个回调函数接口,通过回调模型,EventSource 事件源便可回调具体监听器动作.

有了了解后,这里还可以做一些变动. 对特定的事件提供特定的关注方法和事件触发

...

public void onCloseWindows(EventListener eventListener){

System.out.println("关注关闭窗口事件");

EventSource windows = new EventSource();

/**

* 另一种实现方式

*/

观察者模式代码java-图3

//关注关闭事件,实现回调接口

windows.onCloseWindows(new EventListener(){

这种就类似于,我们的窗口程序,Button监听器了.我们还可以为单击、双击事件定制监听器.

观察者模式

什么是观察者模式

观察者模式其实原理和监听器是一样的,使用的关键在搞清楚什么是观察者、什么是被观察者.

观察者(Observer)相当于事件监器.有个微博模型比较好理解,A用户关注B用户,则A是B的观察者,B是一个被观察者,一旦B发表任何言论,A便可以获得.

被观察者(Observable)相当于事件源和事件,执行事件源通知逻辑时,将会回调observer的回调方法update.

为了方便,同样我直接使用jdk自带的Observer.

一个观察者

public class WatcherDemo implements Observer {

public void update(Observable o, Object arg) {

if(arg.toString().equals("openWindows")){

System.out.println("已经打开窗口");

被观察者

Observable 是jdk自带的被观察者,具体可以自行看源码和之前的监听器事件源类似.

主要方法有

addObserver() 添加观察者,与监听器模式类似

notifyObservers() 通知所有观察者

类Watched.java的实现描述:被观察者,相当于事件监听的事件源和事件对象.又理解为订阅的对象 主要职责:注册/撤销观察者(监听器),接收主题对象(事件对象)传递给观察者(监听器),具体由感兴趣的观察者(监听器)执行

Watched watched = new Watched();

WatcherDemo watcherDemo = new WatcherDemo();

watched.addObserver(watcherDemo);

watched.addObserver(new Observer(){

if(arg.toString().equals("closeWindows")){

System.out.println("已经关闭窗口");

});

//触发打开窗口事件,通知观察者

watched.notifyObservers("openWindows");

//触发关闭窗口事件,通知观察者

watched.notifyObservers("closeWindows");

已经打开窗口

已经关闭窗口

总结

从整个实现和调用过程来看,观察者和监听器模式基本一样.

有兴趣的你可以基于这个模型,实现一个简单微博加关注和取消的功能. 说到底,就是事件驱动模型,将调用者和被调用者通过一个链表、回调函数来解耦掉,相互独立.

"你别来找我,有了我会找你".

整个设计模式的初衷也就是要做到低耦合,低依赖.

再延伸下,消息中间件是什么一个模型? 将生产者+服务中心(事件源)和消费者(监听器)通过消息队列解耦掉. 消息这相当于具体的事件对象,只是存储在一个队列里(有消峰填谷的作用),服务中心回调消费者接口通过拉或取的模型响应. 想必基于这个模型,实现一个简单的消息中间件也是可以的.

还比如gava ListenableFuture,采用监听器模式就解决了future.get()一直阻塞等待返回结果的问题.

有兴趣的同学,可以再思考下观察者和责任链之间的关系, 我是这样看的.

同样会存在一个链表,被观察者会通知所有观察者,观察者自行处理,观察者之间互不影响. 而责任链,讲究的是击鼓传花,也就是每一个节点只需记录继任节点,由当前节点决定是否往下传. 常用于工作流,过滤器web filter.

java设计模式 观察者模式 代码

第一个

public interface RandomNumberListener {//接口

public void numberChanged(double d);

第二个

public class Consol implements RandomNumberListener{

public void numberChanged(double d) {

System.out.println(d);

第三个

public class SwingWindow

extends JFrame

implements RandomNumberListener{//观察者

private JLabel label = new JLabel();

public SwingWindow(){

this.getContentPane().add( label);

this.setVisible(true);

label.setText(String.valueOf(d));

第四个

public class RandomNumber {//业务

private double r;

private ListRandomNumberListener listeners = new ArrayListRandomNumberListener();

//添加所有观察者

public void addRandomNumberListener(RandomNumberListener lis){

listeners.add(lis);

public void random(){

r = Math.random();

//数据发生改变,通知所有的观察者

for (RandomNumberListener lis : listeners) {

lis.numberChanged(r);

第五个

public class Test {

public static void main(String[] args) throws InterruptedException{

RandomNumber rn = new RandomNumber();

SwingWindow sw = new SwingWindow();

Consol c = new Consol();

rn.addRandomNumberListener(sw);

rn.addRandomNumberListener(c);

while(true){

rn.random();

求 JAVA 异步观察者模式 的源代码(完整的),不要同步的,好的给加分

package TestObserver;

import java.util.Iterator;

import java.util.Vector;

*

* @author Seastar

interface Observed {

public void addObserver(Observer o);

public void removeObserver(Observer o);

public void update();

interface Observer {

public void takeAction();

class Invoker {

private Observer o;

Handler handler;

public Invoker(Observer o) {

new Handler();

this.o = o;

private class Handler extends Thread {

public Handler() {

handler = this;

o.takeAction();

public boolean TestSameObserver(Observer o) {

return o == this.o;

public void invoke() {

handler.start();

class ObservedObject implements Observed {

private VectorInvoker observerList = new VectorInvoker();

public void addObserver(Observer o) {

observerList.add(new Invoker(o));

public void removeObserver(Observer o) {

IteratorInvoker it = observerList.iterator();

while (it.hasNext()) {

Invoker i = it.next();

if (i.TestSameObserver(o)) {

observerList.remove(i);

break;

public void update() {

for (Invoker i : observerList) {

i.invoke();

class ObserverA implements Observer {

public void takeAction() {

System.out.println("I am Observer A ,state changed ,so i have to do something");

class ObserverB implements Observer {

System.out.println("I am Observer B ,i was told to do something");

class ObserverC implements Observer {

System.out.println("I am Observer C ,I just look ,and do nothing");

public class Main {

* @param args the command line arguments

ObserverA a = new ObserverA();

ObserverB b = new ObserverB();

ObserverC c = new ObserverC();

ObservedObject oo = new ObservedObject();

oo.addObserver(a);

oo.addObserver(b);

oo.addObserver(c);

oo.addObserver(new Observer() {

System.out.println("我是山寨观察者"+",谁敢拦我");

//sometime oo changed ,so it calls update and informs all observer

oo.update();

观察者模式的精髓在于注册一个观察者观测可能随时变化的对象,对象变化时就会自动通知观察者,

这样在被观测对象影响范围广,可能引起多个类的行为改变时很好用,因为无需修改被观测对象的代码就可以增加被观测对象影响的类,这样的设计模式使得代码易于管理和维护,并且减少了出错几率

至于异步机制实际是个噱头,可以有观测对象来实现异步,也可以有观察者自身实现,这个程序实际是观测对象实现了异步机制,方法是在观察者类外包装了一层invoker类

以上就是土嘎嘎小编为大家整理的观察者模式代码java相关主题介绍,如果您觉得小编更新的文章只要能对粉丝们有用,就是我们最大的鼓励和动力,不要忘记讲本站分享给您身边的朋友哦!!

版权声明:倡导尊重与保护知识产权。未经许可,任何人不得复制、转载、或以其他方式使用本站《原创》内容,违者将追究其法律责任。本站文章内容,部分图片来源于网络,如有侵权,请联系我们修改或者删除处理。

编辑推荐

热门文章