`

采用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:服务器响应失败!







.
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics