一. 代理模式
Provide a surrogate or placeholder for another object to control access to it. 這是'四人幫'的書中對代理的高度概括. 代理模式,其實是為其他對象找供一種代理以控制對這個對象的訪問. 如:程序的快捷方式,老板的秘書等等,都是實現代理的功能.
二. 代理模式所涉及的角色:
1.抽象主题角色:声明了真实主题与代理主题的共同接口(共有的特性)
2.代理主题角色:含有对真实主题角色的引用(操作真实主体对象),代理角色通常在将客户端调用传递给真实主题对象的之前或者之后都会执行某些操作(方法),而不是只单纯的返回真实的对象。
3.真实主题角色:定义了代理角色所代表的真实对象。
三. 遠程代理的UML類圖如下:
四. 完整示例代碼如下:
1. 遠程接口[服務器端]
package structuralPattern.proxy.rmi.proxy1;
import java.rmi.Remote;
import java.rmi.RemoteException;
/**
* @ClassName: MyRemote
* @Description:遠程接口[服務器端]
* @author Liyongbin
* @date 2011-2-8 上午08:05:06
* @version V1.0
*/
public interface MyRemote extends Remote {
//返回值對象(String),經過網絡,必須是Serializable類型
public String sayHello()throws RemoteException;
}
2. 遠程服務[服務器端]
package structuralPattern.proxy.rmi.proxy1;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
/**
* @ClassName: MyRemoteImpl
* @Description:遠程服務[服務器端]
* @author Liyongbin
* @date 2011-2-8 上午08:29:35
* @version V1.0
*/
public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote {
private static final long serialVersionUID = 3889961927313297841L;
//端口號
public static final int DEF_PORT = 1099;
//無參構造器
protected MyRemoteImpl() throws RemoteException {}
//遠程方法
@Override
public String sayHello() throws RemoteException {
return "Server says:'Hey'";
}
/**
* 用RMI Registry註冊此服務
* @param args
*/
public static void main(String[] args) {
int port = DEF_PORT;
//可以註冊在起動時(命令行)輸入的端口號
try {
if (args.length > 0) {
port = Integer.parseInt(args[0]);
}
MyRemote Service = new MyRemoteImpl();
//注冊一個端口號
LocateRegistry.createRegistry(port);
//綁定服務//host:port/servername
String url = "//:" + port + "/RemoteHello";
Naming.rebind(url, Service);
//Naming.rebind("rmi://:"+ port +"/RemoteHello", Service);
System.out.println("Server is run!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
3.:[客戶端]
package structuralPattern.proxy.rmi.proxy1;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
/**
* @ClassName: MyRemoteClient
* @Description:[客戶端]
* @author Liyongbin
* @date 2011-2-8 上午08:34:41
* @version V1.0
*/
public class MyRemoteClient {
private static final int DEF_PORT = 1099;
private static final String DEF_IP = "127.0.0.1";
public static void main(String[] args) {
new MyRemoteClient().go();
}
public void go() {
try {
// 用來指出服務運行位置的主機名和IP地址,注:RemoteHello必須是註冊時用的名字.
String url = "rmi://" + DEF_IP + ":" + DEF_PORT + "/RemoteHello";
MyRemote Service = (MyRemote) Naming.lookup(url);
String str = Service.sayHello();
System.out.println("Clent:"+str);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
}
}
4. 先運行: 2. 遠程服務[服務器端]
結果: Server is run!
再運行: 3. [客戶端]
結果: Clent:Server says,'Hey'