代理模式:
代理模式给某一个对象提供一个代理对象,并由代理对象控制对源对象的引用。代理就是一个人或一个机构代表另一个人或者一个机构采取行动。某些情况下,客户不想或者不能够直接引用一个对象,代理对象可以在客户和目标对象直接起到中介的作用。客户端分辨不出代理主题对象与真实主题对象。代理模式可以并不知道真正的被代理对象,而仅仅持有一个被代理对象的接口,这时候代理对象不能够创建被代理对象,被代理对象必须有系统的其他角色代为创建并传入。
代理结构图:
需求:
1.静态代理描述
西门庆(ˇˍˇ) 想~找潘金莲么么哒,可惜怕被武松打了,就通过王婆来做代理,介绍潘金连给西门庆。后来西门庆又来找王婆的,王婆又作为代理找来了贾氏跟西门庆么么哒。
---------------------------------------------------------
-------------------------
西门庆(client)
-----------------------------
public class Ximenqing {
public static void main(String[] args) {
JFrame jfram=new JFrame("水浒传");
JTextArea jTextArea=new JTextArea();
String str="*******西门庆通过王婆找潘金莲********";
Allwomen panjiglian=new Panjinglian();
WangPo wangpo=new WangPo(panjiglian);
wangpo.show();
wangpo.kiss();
jTextArea.append(str+"\n");
jTextArea.append(wangpo.show()+"\n");
jTextArea.append(wangpo.kiss()+"\n");
String str2="*******西门庆通过王婆找贾氏********";
Allwomen jiashi=new Jiashi();
WangPo wangpo1=new WangPo(jiashi);
jTextArea.append(str2+"\n");
jTextArea.append(wangpo1.show()+"\n");
jTextArea.append(wangpo1.kiss()+"\n");
jfram.setSize(new Dimension(500, 300));
jfram.setPreferredSize(new Dimension(500, 300));
jfram.add(jTextArea);
jTextArea.setBackground(new Color(125, 175, 255));
jTextArea.setFont(new Font("楷体", 0, 20));
jfram.setDefaultCloseOperation(1);
jfram.setVisible(true);
}
}
----------------------------------
王婆(proxy)
-----------------------------------
public class WangPo implements Allwomen{
private Allwomen panjinglian=null;
public WangPo(Allwomen allwomen){
this.panjinglian=allwomen;
}
@Override
public String show() {
// TODO Auto-generated method stub
return panjinglian.show();
}
@Override
public String kiss() {
// TODO Auto-generated method stub
return panjinglian.kiss();
}
}
--------------------------------------
贾氏和潘金连(realsubject)
---------------------------------------
public class Jiashi implements Allwomen{
@Override
public String show() {
// TODO Auto-generated method stub
return "贾氏学潘金莲对西门庆抛媚眼";
}
@Override
public String kiss() {
// TODO Auto-generated method stub
return "贾氏学潘金跟西门庆连亲亲";
}
}
public class Panjinglian implements Allwomen{
@Override
public String show() {
// TODO Auto-generated method stub
return "潘金莲对西门庆抛媚眼";
}
@Override
public String kiss() {
// TODO Auto-generated method stub
return "潘金莲跟西门庆亲亲";
}
}
------------------------------------
女人(subject)
------------------------------------
public interface Allwomen {
/**
* 抛媚眼
*/
public String show();
/**
* 亲亲
*/
public String kiss();
}
---------------------------------------
结果:
-----------------------------------------------------------------------------------------------------------------------------------
动态代理:
----------------------------------------------------------
具体主题
-------------------------------------------------------------
public class GamePlayer implements IGamePlay{
@Override
public void login() {
// TODO Auto-generated method stub
System.out.println("玩家登陆");
}
}
---------------------------------------------------------
代理
--------------------------------------------------
public class GamePlayInvocationHandler implements InvocationHandler{
private Object proxyObject;
public GamePlayInvocationHandler(Object proxyObject){
this.proxyObject=proxyObject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object obj=null;
// TODO Auto-generated method stub
if("login".equals(method.getName())){
System.out.println("方法执行前");
obj=method.invoke(this.proxyObject, args);
System.out.println("方法执行后");
}
return obj;
}
}
---------------------------------------------------
主题
----------------------------------------------------
public interface IGamePlay {
public void login();
}
---------------------------------------------------
客户
-----------------------------------------------------
public class Main {
public static void main(String[] args) {
IGamePlay gamePlay=new GamePlayer();
ClassLoader cls=gamePlay.getClass().getClassLoader();
Class<?>[] clsa=gamePlay.getClass().getInterfaces();
GamePlayInvocationHandler gamePlayInvocationHandler=new GamePlayInvocationHandler(gamePlay);
IGamePlay proxy= (IGamePlay) Proxy.newProxyInstance(cls, clsa, gamePlayInvocationHandler);
proxy.login();
}
}
------------------------------------------------------
-------------------------------------------------------------
远程代理
---------------------------------------------------------------
解释一下,Stub是“桩”也有人称之为“存根”,代表了Server对象
Skeleton是“骨架”(不知道为什么叫“桩”和“骨架”,当然,也没必要知道),代表了Client
Stub明明在客户那边,为什么不是客户的代理而是服务的代理?因为客户是要与服务器交互,现在服务在远程JVM中,无法交互,所以用Stub来代表Server,调用Stub就等同于调用Server(内部通信机制对Client透明,对Client来说,调用Stub和直接调用Server没什么区别,而这正是代理模式的优点之一)
具体流程是这样的:
- Client向Stub发送方法调用请求(Client以为Stub就是Server)
- Stub接到请求,通过Socket与服务端的Skeleton通信,把调用请求传递给Skeleton
- Skeleton接到请求,调用本地Server(听起来有点奇怪,这里Server相当于Service)
- Server作出对应动作,把结果返回给调用者Skeleton
- Skeleton接到结果之后通过Socket发送给Stub
- Stub把结果传递给Client
-----------------------------------------------------------------------------------------------
-------------------------------------------
客户
-----------------------------------------
/** * @author Administrator * 西门庆(客户端) */ public class Ximenqing { public static void main(String[] args) { try { WangPo wanPo=new WangPo(); Thread.sleep(2000); Allwomen jiashi=(Allwomen) Naming.lookup("//172.20.148.1:8088/jiashi"); System.out.println(jiashi.show()); System.out.println(jiashi.kiss()); System.out.println("---------------"); Allwomen panjinglian=(Allwomen) Naming.lookup("//172.20.148.1:8088/panjinglian"); System.out.println(panjinglian.show()); System.out.println(panjinglian.kiss()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
-----------------------------------------------
真实的主题
----------------------------------------------
public class Jiashi extends UnicastRemoteObject implements Allwomen{
public Jiashi() throws RemoteException {
super();
// TODO Auto-generated constructor stub
}
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
public String show() throws RemoteException {
// TODO Auto-generated method stub
return "潘金连抛媚眼";
}
@Override
public String kiss() throws RemoteException {
// TODO Auto-generated method stub
return "潘金连亲亲";
}
}
/**
* @author Administrator
* 继承UnicastRemoteObject 自动实现stub类 有了"桩"
*/
public class Panjinglian extends UnicastRemoteObject implements Allwomen{
public Panjinglian() throws RemoteException {
super();
// TODO Auto-generated constructor stub
}
private static final long serialVersionUID = 1L;
@Override
public String show() throws RemoteException {
// TODO Auto-generated method stub
return "贾氏学潘金连抛眉眼";
}
@Override
public String kiss() throws RemoteException {
// TODO Auto-generated method stub
return "贾氏学潘金连亲亲";
}
}
----------------------------------------------
远程服务
-------------------------------------------------
-----------------------------------------------
public interface Allwomen extends Remote{
/**
* 抛媚眼
*/
public String show() throws RemoteException;
/**
* 亲亲
*/
public String kiss() throws RemoteException;
}
-------------------------------------------------
服务
---------------------------------------------------
/**
* 王婆联系潘金连跟贾氏,远程服务器
* @author Administrator
*/
public class WangPo{
public WangPo(){
new Thread(new Runnable() {
@Override
public void run() {
//启动rmi服务定义端口
try {
//LocateRegistry.createRegistry(8080);
Allwomen panjinlian=new Panjinglian();
Allwomen jiashi= new Jiashi();
System.out.println("王婆收注册费");
Naming.bind("rmi://172.20.148.1:8088/panjinglian",panjinlian);
Naming.bind("rmi://172.20.148.1:8088/jiashi",jiashi);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
}
---------------------------------------------------