`

采用Client/Server模型理解回调callback

阅读更多
关于回调早就听说过,但是不曾理解过,周日的上午外面阳光灿烂,我却在这里琢磨回调,苦逼的程序员啊!不知道哪位先哲说过:你能看见多远的过去,你就能看见多远的未来。所以今天我们将采用渐进式的来学习回调:

定义:如果对象A调用对象B称为【顺调】,那么在对象A调用对象B之后,对象B再调用对象A,这时对象B对对象A的调用称为【回调】

第一种:对象A和对象B相互直接调用

Client类:

package com.cdl.callback.http0;

/**
 * 功能:为了便于描述,把Client称作对象A
 *
 * @author ocaicai@yeah.net
 * @date 2012-4-22 上午10:45:30 
 */
public class Client {

	public static void main(String[] args) {
		Server server = new Server();
		//A调用B,将自己传递过去,以便于B直接回调
		server.doRequest(new Client());
	}

	public void doResponse(boolean result) {
		if(result){
			System.out.println("Client Side:服务器响应成功!");
		}else{
			System.out.println("Client Side:服务器响应失败!");
		}
	}

}



Server类:

package com.cdl.callback.http0;

import java.util.Random;

/**
 * 功能:为了便于描述,把Server称作对象B<BR>
 * 定义:如果对象A调用对象B称为【顺调】,<BR>
 * 那么在对象A调用对象B之后,对象B再调用对象A,这时对象B对对象A的调用称为【回调】<BR>
 * 
 * @author ocaicai@yeah.net
 * @date 2012-4-22 上午10:46:05
 */
public class Server {

	/**
	 * 由于client是对象A调用对象B时传递过来的参数<BR>
	 * 所以对象B对client的使用可以看作是对象B对对象A的调用,即是回调:对象B再调用对象A
	 * 
	 * @param client
	 *            对象A调用对象B时传递过来的参数
	 */
	public void doRequest(Client client) {
		boolean result = getDoRequestResult();
		client.doResponse(result);
	}

	private boolean getDoRequestResult() {
		System.out.println("Server Side:服务器正在处理客户端的请求...");
		int status = Math.abs(new Random().nextInt());
		return status % 2 == 0 ? false : true;
	}
}



运行结果1:
Server Side:服务器正在处理客户端的请求...
Client Side:服务器响应成功!

运行结果2:
Server Side:服务器正在处理客户端的请求...
Client Side:服务器响应失败!


第二种:借助第三方隔离Client和Server,避免它们之间的直接相互依赖

第三方ICallBack接口:

package com.cdl.callback.http1;

/**
 * 功能:回调接口<BR>
 * 借助第三方隔离Client和Server,避免它们之间的直接相互依赖<BR>
 * 
 * @author ocaicai@yeah.net
 * @date 2012-4-22 上午10:07:18
 */
public interface ICallBack {

	public void onSuccess();

	public void onFailure();

}



Client类:

package com.cdl.callback.http1;

/**
 * 功能:为了便于描述,把Client称作对象A
 * 
 * @author ocaicai@yeah.net
 * @date 2012-4-22 上午10:45:30
 */
public class Client {

	public static void main(String[] args) {
		Server server = new Server();
		//如果直接传递自己,这样的依赖性太大,所以采用接口
		server.doRequest(new ICallBack() {

			@Override
			public void onSuccess() {
				System.out.println("Client Side:服务器响应成功!");
			}

			@Override
			public void onFailure() {
				System.out.println("Client Side:服务器响应失败!");
			}
		});
	}

}



Server类:

package com.cdl.callback.http1;

import java.util.Random;

/**
 * 功能:为了便于描述,把Server称作对象B<BR>
 * 定义:如果对象A调用对象B称为【顺调】,<BR>
 * 那么在对象A调用对象B之后,对象B再调用对象A,这时对象B对对象A的调用称为【回调】<BR>
 * 
 * @author ocaicai@yeah.net
 * @date 2012-4-22 上午10:46:05
 */
public class Server {

	/**
	 * 由于callBack是对象A调用对象B时传递过来的参数<BR>
	 * 所以对象B对callBack的使用可以看作是对象B对对象A的调用,即是回调:对象B再调用对象A
	 * 
	 * @param callBack
	 *            对象A调用对象B时传递过来的参数
	 */
	public void doRequest(ICallBack callBack) {
		boolean result = getDoRequestResult();
		if (result)
			callBack.onSuccess();
		else
			callBack.onFailure();
	}

	private boolean getDoRequestResult() {
		System.out.println("Server Side:服务器正在处理客户端的请求...");
		int status = Math.abs(new Random().nextInt());
		return status % 2 == 0 ? false : true;
	}
}



运行结果1:
Server Side:服务器正在处理客户端的请求...
Client Side:服务器响应失败!

运行结果2:
Server Side:服务器正在处理客户端的请求...
Client Side:服务器响应成功!


第三种:第三方接口可能需要负责传递数据,为了通用性采用泛型(广泛使用的类型)

ICallBack接口:

package com.cdl.callback.http2;

/**
 * 功能:回调接口,加上了一个泛型 <BR>
 * 借助第三方隔离Client和Server,避免它们之间的直接相互依赖<BR>
 * 
 * @author ocaicai@yeah.net
 * @date 2012-4-22 上午10:07:18
 */
public interface ICallBack<T> {

	public void onSuccess(T result);

	public void onFailure();

}



Client类:

package com.cdl.callback.http2;

/**
 * 功能:为了便于描述,把Client称作对象A
 * 
 * @author ocaicai@yeah.net
 * @date 2012-4-22 上午10:45:30
 */
public class Client {

	public static void main(String[] args) {
		Server server = new Server();
		server.doRequest(new ICallBack<String>() {

			@Override
			public void onSuccess(String result) {
				System.out.println("Client Side:服务器响应成功!");
				System.out.println(result);
			}

			@Override
			public void onFailure() {
				System.out.println("Client Side:服务器响应失败!");
			}
		});
	}

}



Server类:

package com.cdl.callback.http2;

import java.util.Random;

/**
 * 功能:为了便于描述,把Server称作对象B<BR>
 * 定义:如果对象A调用对象B称为【顺调】,<BR>
 * 那么在对象A调用对象B之后,对象B再调用对象A,这时对象B对对象A的调用称为【回调】<BR>
 * 
 * @author ocaicai@yeah.net
 * @date 2012-4-22 上午10:46:05
 */
public class Server {

	/**
	 * 由于callBack是对象A调用对象B时传递过来的参数<BR>
	 * 所以对象B对callBack的使用可以看作是对象B对对象A的调用,即是回调:对象B再调用对象A
	 * 
	 * @param callBack
	 *            对象A调用对象B时传递过来的参数
	 */
	public void doRequest(ICallBack<String> callBack) {
		boolean result = getDoRequestResult();
		if(result)
			callBack.onSuccess("服务器Message:谢谢客户端的访问!");
		else
			callBack.onFailure();
	}

	private boolean getDoRequestResult() {
		System.out.println("Server Side:服务器正在处理客户端的请求...");
		int status = Math.abs(new Random().nextInt());
		return status % 2 == 0 ? false : true;
	}
}



运行结果1:
Server Side:服务器正在处理客户端的请求...
Client Side:服务器响应成功!
服务器Message:谢谢客户端的访问!


运行结果2:
Server Side:服务器正在处理客户端的请求...
Client Side:服务器响应失败!







.
分享到:
评论

相关推荐

    回调函数使用说明

    在这个例子中,`ServerFunction` 接受一个客户端的回调函数 `client_callback`,并在处理数据后不仅调用客户端的回调函数,还定义了一个服务器端的回调函数 `server_callback` 来响应客户端的操作。 ##### 3. 事件...

    回调函数在软件设计中的应用

    例如,在需要实现事件驱动的编程模型时,回调函数可以作为一个很好的解决方案。通过将事件处理逻辑抽象出来作为回调函数,可以使得主程序更加简洁,易于维护。 ##### 3.3 实现复杂的程序间通信 除了上述应用之外,...

    重叠IO模型之OverLapped完成例程模型WSACompletionRoutineServer VS2010

    // 系统在WSARecv收到信息后,自动调用此函数,并传入参数--回调函数 void CALLBACK CompletionRoutine(DWORD dwError, DWORD dwTrans, LPWSAOVERLAPPED lpOverlap, DWORD nFlags) { LP_PER_IO_OPERATION_DATA ...

    基于远程回调和网络通信c#实例

    本实例重点探讨了基于C#的远程回调(Remote Callback)和Remoting技术,同时涉及到了多线程以及异步传输等核心概念。 首先,远程回调是一种设计模式,它允许服务器在完成某个操作后主动调用客户端的方法,而不是...

    Microsoft Wirting Style Guide

    这份指南还可能提供对一些编程术语的定义,例如“backend, back-end”(后端)、“Boolean”(布尔类型)、“callback”(回调函数)和“Cascading Style Sheets (CSS)”(层叠样式表),这些术语对于软件开发和网页...

    03_Server端实现1

    在ROS (Robot Operating System) 中,服务(Service)是一种客户端-服务器模型,允许节点之间进行同步通信,其中一个节点作为服务的提供者(Server),另一个节点作为请求者(Client)。本篇将详细介绍如何在ROS中...

    CSRMesh蓝牙开发Android

    模型分为服务器模型(Server Model)和客户端模型(Client Model),服务器模型负责接收和响应消息,客户端模型则负责发送请求和接收响应。常见的模型有灯控模型、温控模型等,开发者可以根据需求选择或自定义模型。...

    Aerospike C Client.zip

    开发者可以通过`as_log_set_level()`和`as_log_set_callback()`设置日志级别和回调函数,以便在代码运行过程中获取详细的诊断信息。 总之,Aerospike C客户端是一个强大的工具,它为C语言开发者提供了直接与...

    计算机专业英语词汇(软考自用)

    17. **回调函数(Callback Function)**:当特定事件发生时,被系统或另一函数调用的函数。 18. **高速缓存(Cache)**:存储最近或频繁使用的数据,以提高访问速度。 19. **客户/服务器架构(Client/Server Architecture...

    藏经阁-HBase在阿里搜索推荐中的应用.pdf

    * 异步与吞吐:使用 non-blocking client 和 protobuf 的 non-blocking Stub/RpcCallback 实现 callback 回调,提高异步处理和吞吐能力 * GC 与毛刺:实现读路径 E2E 的 offheap,降低 Full 和 CMS gc 频率,提高读...

    libwebsockets-2.3-stable

    例如,可以编写一个`LWS_CALLBACK_SERVER_WRITEABLE`回调函数来发送数据给客户端,或者一个`LWS_CALLBACK_CLIENT_CONNECTION_ERROR`回调来处理连接失败的情况。 对于客户端,`libwebsockets`同样提供了创建连接、...

    如何在C#中实现OPC数据访问

    5. 注册回调函数以处理异步操作的结果。 6. 调用`AsyncRead()`或`AsyncWrite()`方法发起异步读写操作。 #### 5、采用自动化接口实现过程 自动化接口提供了更简便的编程模型,使开发人员可以更容易地实现OPC数据访问...

    android基础 - 读取PHP

    创建RequestQueue,然后根据需求创建JsonObjectRequest或StringRequest,设置PHP的URL,以及请求成功或失败的回调函数。 ```java RequestQueue queue = Volley.newRequestQueue(this); JsonObjectRequest ...

    ACE开发指南(初级).

    - **Callback**:回调函数。 - **Hook Method**:挂钩方法。 - **Handle**:句柄。 - **Template**:模板。 - **Daemon**:守护进程。 - **Override/Overwrite**:覆盖。 - **Overload**:重载。 #### 2. ACE简介及...

    node-dnode-ez-源码.rar

    调用过程涉及到消息的打包、发送和解包,以及回调结果的处理。 4. **事件驱动编程** dnode-ez使用`events`模块实现事件驱动编程,当连接建立、断开或有数据传输时,会触发相应的事件,用户可以通过监听这些事件来...

    nodejs实战第二季

    - **单线程**:Node.js采用单线程模型,避免了多线程带来的复杂性。 - **非阻塞I/O**:Node.js使用非阻塞I/O调用,这意味着函数调用不会等待I/O操作完成,而是直接返回控制流。 - **模块化**:Node.js支持模块化...

    基于MQTT的兼职系统设计1

    - **业务处理**:使用MQTT的发布订阅模式,通过`ClientCallBack`和`MessageCallBack`处理客户端和服务端的消息回调。 - **数据存储**:数据存放在内存中,不与数据库交互,使用`ArrayList`动态数组和静态变量存储...

    单点登录源码

    | ├── zheng-upms-client -- 集成upms依赖包,提供单点认证、授权、统一会话管理 | ├── zheng-upms-rpc-api -- rpc接口包 | ├── zheng-upms-rpc-service -- rpc服务提供者 | └── zheng-upms-server -- ...

    adroid socket 通信

    在回调函数中,你可以处理客户端的数据。 ```javascript server.on('connection', (socket) =&gt; { console.log('New client connected'); socket.on('data', (data) =&gt; { // 处理接收到的数据 }); socket.on...

Global site tag (gtag.js) - Google Analytics