Java回调函数与观察者模式实例代码

本文研究的主要是Java回调函数与观察者模式的实现,具体介绍和实现代码如下。

观察者模式(有时又被称为发布(publish )-订阅(Subscribe)模式、模型-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。

什么时候使用观察者模式:

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

其实观察者模式同前面讲过的桥梁、策略有着共同的使用环境:将变化独立封装起来,以达到最大的重用和解耦。观察者与后两者不同的地方在于,观察者模式中的目标和观察者的变化不是独立的,而是有着某些联系。

在Java中通过Observable类和Observer接口实现了观察者模式。一个Observer对象监视着一个Observable对象的变化,当Observable对象发生变化时,Observer得到通知,就可以进行相应的工作。

package com.demo.test;
import java.util.Observable;
import java.util.Observer;
//观察者模式里面目标类维护了所有观察者的引用,而回调里面只是维护了一个引用
public class ObserverCallbackDemo {
	// 观察者A
	static class ConcreteObserverA implements Observer {
		@Override
		    public void update(Observable o, Object arg) {
			System.out.println("ConcreteObserverA update");
		}
	}
	// 观察者B
	static class ConcreteObserverB implements Observer {
		@Override
		    public void update(Observable o, Object arg) {
			System.out.println("ConcreteObserverB update");
		}
	}
	// 被观察对象
	static class ConcreteObservable extends Observable {
		public void changeValue() {
			//protected方法只能在子类被调用
			setChanged();
			notifyObservers();
		}
	}
	// 回调函数接口
	interface ICallback {
		public void onCall();
	}
	// 回调类
	static class CallbackDemo {
		private ICallback callback;
		public void setListener(ICallback callback) {
			this.callback = callback;
		}
		public void call() {
			callback.onCall();
		}
	}
	public static void main(String[] args) {
		// 观察者
		ConcreteObserverA observerA = new ConcreteObserverA();
		ConcreteObserverB observerB = new ConcreteObserverB();
		ConcreteObservable observable = new ConcreteObservable();
		observable.addObserver(observerA);
		observable.addObserver(observerB);
		System.out.println("countObservers = " + observable.countObservers());
		observable.changeValue();
		// 回调函数
		CallbackDemo callbackDemo = new CallbackDemo();
		callbackDemo.setListener(new ICallback() {
			@Override
			      public void onCall() {
				System.out.println("callback onCall");
			}
		}
		);
		callbackDemo.call();
	}
}

输出结果:

countObservers = 2
ConcreteObserverB update
ConcreteObserverA update
callback onCall

总结

从上面代码可以看出:回调函数应该属于观察者模式的一种,目的是为了替代轮循机制,将组件之间的耦合性降低。观察者模式里面目标类维护了所有观察者的引用,而回调里面只是维护了一个引用。

以上就是本文关于Java回调函数与观察者模式实例代码的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

您可能感兴趣的文章:

  • Java回调函数实例代码详解
  • Java通过匿名类来实现回调函数实例总结
  • 基于Java 谈回调函数
  • Java 回调函数详解及使用
  • Java经典设计模式之观察者模式原理与用法详解
  • Java编程之内置观察者模式实例详解
  • java 在观察者模式中使用泛型T的实例
  • java设计模式之观察者模式学习
时间: 2018-01-30

Java通过匿名类来实现回调函数实例总结

在C语言中,函数名可以当做函数指针传递给形参从而实现回调 void f1() { printf("f1()\n"); } void f2() { printf("f2()\n"); } void f3() { printf("f3()\n"); } void do_func(void(*f)()) { f(); } int main() { do_func(f1); do_func(f2); do_func(f3); } 在C++11中,实现回调

Java经典设计模式之观察者模式原理与用法详解

本文实例讲述了Java经典设计模式之观察者模式.分享给大家供大家参考,具体如下: 观察者模式:对象间的一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象(被观察). 以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并发生相应的变化. 观察者模式有很多实现方式:该模式必须包含观察者和被观察对象两种角色.观察者和被观察者之间存在"观察"的逻辑关系,当被观察者发生改变的时候,观察者就会观察到这样的变化,发出相应的改变. /** * 观察者接口:观察者,需要用到观察者模式的

基于Java 谈回调函数

杂谈 还是习惯,写点什么之前,都喜欢来点杂谈. 最近都在搞微信的开发,终于在昨晚进入测试阶段了,好快就测出 bug 来,但也好快修复了.这也让我更担心. 虽说是进入内测阶段,但那代码的结构也真太难看了,还得好好重构一下.迟点得写写关于这微信公众号的开发文章.下次再详谈. 今天开始了三天半的小长假,但我还是坚守在学校.有点不知道为了什么. 刚给 wp 装了个 markdown 插件,爽歪歪!! 在写这篇文章的时候,还是用着 wordpress 的,但在发表的时候,已经换成 hexo 了.原因:没有

java设计模式之观察者模式学习

1.什么是观察者模式 简单情形:有A.B.C.D等四个独立的对象,其中B.C.D这三个对象想在A对象发生改变的第一时间知道这种改变,以便做出相应的响应或者对策. 上面的这种情形,就是观察者模式. 当然可以有多个观察者,多个被观察者. 观察者与被观察者也不是对立的,一个对象可以观察其他对象,也可以被其他对象观察. 2.观察者模式的应用 为了更好的理解什么是观察者模式,下面我举一些可能用到该模式的情形或例子: (1)周期性任务.比如linux中的周期性任务命令crontab命令,win7下的定时关机

Java 回调函数详解及使用

Java 回调函数详解 前言: C语言中回调函数解释: 回调函数(Callback Function)是怎样一种函数呢? 函数是用来被调用的,我们调用函数的方法有两种: 直接调用:在函数A的函数体里通过书写函数B的函数名来调用之,使内存中对应函数B的代码得以执行.这里,A称为"主叫函数"(Caller),B称为"被叫函数"(Callee). 间接调用:在函数A的函数体里并不出现函数B的函数名,而是使用指向函数B的函数指针p来使内存中属于函数B的代码片断得以执行--听

Java回调函数实例代码详解

首先说说什么叫回调函数? 在WINDOWS中,程序员想让系统DLL调用自己编写的一个方法,于是利用DLL当中回调函数(CALLBACK)的接口来编写程序,使它调用,这个就 称为回调.在调用接口时,需要严格的按照定义的参数和方法调用,并且需要处理函数的异步,否则会导致程序的崩溃. 这样的解释似乎还是比较难懂,这里举个简 单的例子: 程序员A写了一段程序(程序a),其中预留有回调函数接口,并封装好了该程序.程序员B要让a调用自己的程序b中的一个方法,于是,他通过a中的接口回调自己b中的方法.目的达到

Java编程之内置观察者模式实例详解

本文实例讲述了Java内置观察者模式.分享给大家供大家参考,具体如下: 之前也简单地写过观察者模式(又称为发布-订阅模式)小例子,现在项目中也常用到该模式.今天贴一下如何使用Java内置的观察者模式. 主要使用到的Java API就两个类: Observer接口:观察者对象,监听被观察者对象数据变化,一是数据发生变化 ,就做出相应地啥响应. Observable类:被观察者对象,提供添加及移出观察者对像方法,数据发生哟完成时并通知所有已经添加进来的观察者对象. 被观察者代码示例: //Obser

java 在观察者模式中使用泛型T的实例

被观察者 public class Observable<T> { List<Observer> observers = new ArrayList<Observer>(); boolean changed = false; /** * Adds the specified observer to the list of observers. If it is already * registered, it is not added a second time. *

java从字符串中提取数字的简单实例

随便给你一个含有数字的字符串,比如: String s="eert343dfg56756dtry66fggg89dfgf"; 那我们如何把其中的数字提取出来呢?大致有以下几种方法,正则表达式,集合类,还有就是String类提供的方法. 1 String类提供的方法: package 测试练习; import Java.util.*; public class get_StringNum { /** *2016.10.25 */ public static void main(Strin

linux下用renameTo方法修改java web项目中文件夹名称的实例

经测试,在Linux环境中安装tomcat,然后启动其中的项目,在项目中使用java.io.File.renameTo(File dest)方法可行. 之前在本地运行代码可以修改,然后传到Linux服务器上一直无法实现功能,自己一直在捣鼓,以为是window环境和Linux环境不同的原因导致,后面发现在项目中使用renameTo方法修改文件夹名称不行是因为之前改了java web项目中的js,在js中传入值到后台,后台根据值来修改文件夹名称.由于没清除缓存导致js中的代码没有刷新,所以一直出现错

Java 判断字符串中是否包含中文的实例详解

Java 判断字符串中是否包含中文的实例详解 Java判断一个字符串是否有中文是利用Unicode编码来判断,因为中文的编码区间为:0x4e00--0x9fbb, 不过通用区间来判断中文也不非常精确,因为有些中文的标点符号利用区间判断会得到错误的结果.而且利用区间判断中文效率也并不高,例如:str.substring(i, i + 1).matches("[\\一-\\?]+"),就需要遍历整个字符串,如果字符串太长效率非常低,而且判断标点还会错误.这里提高 一个高效准确的判断方法,使

Java获取彩色图像中的主色彩的实例代码

本文讲述了Java获取彩色图像中的主色彩的实例代码.分享给大家供大家参考,具体如下: 一:基本思路 对于一张RGB色彩空间的彩色图像,很多时间我们想通过程序获得该图像有几种主要的色彩,但是对一般图像来说,在色彩交界处都是通过像素混合来实现自然过渡,所以直接扫描图像的像素值,得到的不同颜色值可能多达上百中,而实际上图像可能只有3-4种的主要色彩,如何去掉那些混合颜色,准确提取出来这3-4中的主色彩,根据一般图像的特征,图像在不同色彩的边界处混合不同的颜色值,此可以视为图像的边缘特性之一,因此可以根

java 获取对象中为null的字段实例代码

下面一段简单的代码给大家分享java 获取对象中为null的字段,具体代码如下所述: private static String[] getNullPropertyNames(Object source) { final BeanWrapper src = new BeanWrapperImpl(source); java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors(); Set<String> emptyNames

Java Web项目中实现文件下载功能的实例教程

需求:实现一个具有文件下载功能的网页,主要下载压缩包和图片 两种实现方法: 一:通过超链接实现下载 在HTML网页中,通过超链接链接到要下载的文件的地址 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h1>通过链接下载文件&

Java使用设计模式中的工厂方法模式实例解析

工厂方法模式的定义 工厂方法(Factory Method)模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中.核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品. 它包含了如下角色: 抽象产品(Product) 具体产品(ConcreteProduct) 抽象工厂(Factory) 具体工厂(ConcreteFactory) 模式的UML

举例讲解Java设计模式编程中模板方法模式的运用实例

模板方法模式定义为: 在一个方法中定义了一个算法的骨架或者步骤,而将一些步骤延迟到子类中去实现.模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某一些步骤. 模板方法在基类中定义了一个操作的流程顺序,能够保证该步骤按序进行,有一些步骤的具体实现在基类中已经声明,而将一些变化的步骤的具体实现交给了子类去实现,从而就达到了延迟一些步骤到子类中,模板方法一个最大的好处就是能够设定一个业务流程能够按照一定严格的顺序执行,控制了整个算法的执行步骤. 这个方法将算法定义成一组步骤,其中凡是想让

Java的JDBC中Statement与CallableStatement对象实例

JDBC Statement对象实例 以下是利用以下三种查询以及打开和关闭说明的例子: boolean execute(String SQL) : 返回一个布尔值true,如果ResultSet对象可以被检索,否则返回false.使用这个方法来执行SQL DDL语句,或当需要使用真正的动态SQL. int executeUpdate(String SQL) : 返回受影响的SQL语句执行的行数.使用此方法来执行,而希望得到一些受影响的行的SQL语句 - 例如,INSERT,UPDATE或DELE