【设计模式】代理模式(结构型)

代理模式:

代理模式给某一个对象提供一个代理对象,并由代理对象控制对源对象的引用。代理就是一个人或一个机构代表另一个人或者一个机构采取行动。某些情况下,客户不想或者不能够直接引用一个对象,代理对象可以在客户和目标对象直接起到中介的作用。客户端分辨不出代理主题对象与真实主题对象。代理模式可以并不知道真正的被代理对象,而仅仅持有一个被代理对象的接口,这时候代理对象不能够创建被代理对象,被代理对象必须有系统的其他角色代为创建并传入。

代理结构图:

 

需求:

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没什么区别,而这正是代理模式的优点之一)

具体流程是这样的:

  1. Client向Stub发送方法调用请求(Client以为Stub就是Server)
  2. Stub接到请求,通过Socket与服务端的Skeleton通信,把调用请求传递给Skeleton
  3. Skeleton接到请求,调用本地Server(听起来有点奇怪,这里Server相当于Service)
  4. Server作出对应动作,把结果返回给调用者Skeleton
  5. Skeleton接到结果之后通过Socket发送给Stub
  6. 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();
  }
}

---------------------------------------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值