Java 实现代理(Proxy)模式

参考链接: http://blog.csdn.net/jjwwmlp456/article/details/39896015

类图


  1. /** 
  2.  * 游戏者接口 
  3.  *  
  4.  */  
  5. public interface IGamePlayer {  
  6.   
  7.     // 登录游戏  
  8.     public void login(String user, String password);  
  9.   
  10.     // 杀怪,网络游戏的主要特色  
  11.     public void killBoss();  
  12.   
  13.     // 升级  
  14.     public void upgrade();  
  15.   
  16. }  
  1. /** 
  2.  * 游戏者 
  3.  * 
  4.  */  
  5. public class GamePlayer implements IGamePlayer {  
  6.   
  7.     private String name = "";  
  8.   
  9.     // 通过构造函数传递名称  
  10.     public GamePlayer(String _name) {  
  11.         this.name = _name;  
  12.     }  
  13.   
  14.     // 打怪,最期望的就是杀老怪  
  15.   
  16.     public void killBoss() {  
  17.   
  18.         System.out.println(this.name + " 在打怪!");  
  19.   
  20.     }  
  21.   
  22.     // 进游戏之前你肯定要登录吧,这是一个必要条件  
  23.     public void login(String user, String password) {  
  24.         System.out.println("登录名为" + user + " 的角色 " + this.name + "登录成功!");  
  25.     }  
  26.   
  27.     // 升级,升级有很多方法,花钱买是一种,做任务也是一种  
  28.     public void upgrade() {  
  29.         System.out.println(this.name + " 又升了一级!");  
  30.     }  
  31.   
  32. }  

  1. /** 
  2.  * 客户端 对被代理对象不可见 
  3.  */  
  4. public class GamePlayerProxy implements IGamePlayer {  
  5.   
  6.     private IGamePlayer gamePlayer = null;//被代理对象  
  7.   
  8.     // 通过构造函数传递要对谁进行代练  
  9.     public GamePlayerProxy(String username) {  
  10.         this.gamePlayer = new GamePlayer(username);  
  11.     }  
  12.   
  13.     // 代练杀怪  
  14.     public void killBoss() {  
  15.         this.gamePlayer.killBoss();  
  16.     }  
  17.   
  18.     // 代练登录  
  19.     public void login(String user, String password) {  
  20.         this.gamePlayer.login(user, password);  
  21.     }  
  22.   
  23.     // 代练升级  
  24.     public void upgrade() {  
  25.         this.gamePlayer.upgrade();  
  26.     }  
  27.   
  28. }  

  1. /* 
  2.  * 客户端 对被代理对象不可见 
  3.  */  
  4. public class GamePlayerProxy2 implements IGamePlayer {  
  5.   
  6.     private IGamePlayer gamePlayer = null;//被代理对象  
  7.   
  8.     // 通过构造函数传递要对谁进行代练  
  9.     public GamePlayerProxy2(String username) {  
  10.         this.gamePlayer = new GamePlayer(username);  
  11.     }  
  12.   
  13.     // 代练杀怪  
  14.     public void killBoss() {  
  15.         this.gamePlayer.killBoss();  
  16.     }  
  17.   
  18.     // 代练登录  
  19.     public void login(String user, String password) {  
  20.         System.out.println("登录时间是:" + new Date().toLocaleString());  
  21.         this.gamePlayer.login(user, password);  
  22.     }  
  23.   
  24.     // 代练升级  
  25.     public void upgrade() {  
  26.         this.gamePlayer.upgrade();  
  27.         System.out.println("升级时间是:" + new Date().toLocaleString());  
  28.     }  
  29.   
  30. }  

  1. /* 
  2.  * 客户端 对被代理对象不可见 
  3.  */  
  4. public class GamePlayerProxy3 {  
  5.   
  6.     private IGamePlayer gamePlayer;  
  7.     // 通过构造函数传递 被代练(代理)对象  
  8.     public GamePlayerProxy3(IGamePlayer gamePlayer) {  
  9.          this.gamePlayer = gamePlayer;  
  10.          System.out.println("我是一名代练,我玩的角色是别人的,可以动态传递进来");  
  11.     }  
  12.       
  13.     public IGamePlayer getProxy() {  
  14.         return (IGamePlayer) Proxy.newProxyInstance(this.getClass().getClassLoader(),   
  15.                 new Class[]{IGamePlayer.class}, new MyInvocationHandler());  
  16.     }  
  17.   
  18.     private class MyInvocationHandler implements InvocationHandler {  
  19.       
  20.         @Override  
  21.         public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
  22.             if (method.getName().equals("login")) {  
  23.                 System.out.println("登录时间是:" + new Date().toLocaleString());  
  24.             } if (method.getName().equals("upgrade")) {  
  25.                 System.out.println("升级时间是:" + new Date().toLocaleString());  
  26.             }  
  27.             method.invoke(gamePlayer, args);  
  28.             return null;  
  29.         }  
  30.           
  31.     }  
  32. }  

  1. /* 
  2.  * 代理模式:为其他对象提供一种代理以控制对这个对象的访问。 
  3.  *      在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用 
  4.  * 优点 
  5.  (1).职责清晰 
  6.  真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。 
  7.  (2).代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了的作用和保护了目标对象的作用。 
  8.  (3).高扩展性 
  9.  模式结构 
  10.  一个是真正的你要访问的对象(目标类),一个是代理对象,真正对象与代理 
  11.  对象实现同一个接口,先访问代理类再访问真正要访问的对象。 
  12.   
  13.  在装饰器模式和代理模式之间还是有很多差别的。装饰器模式关注于在一个对象上动态的添加方法,然而代理模式关注于控制对对象的访问。 
  14.  换句话 说,用代理模式,代理类(proxy class)可以对它的客户隐藏一个对象的具体信息。因此,当使用代理模式的时候,我们常常在一个代理类中创建一个对象的实例。 
  15.  并且,当我们使用装饰器模 式的时候,我们通常的做法是将原始对象作为一个参数传给装饰者的构造器。 
  16. 我们可以用另外一句话来总结这些差别:使用代理模式,代理和真实对象之间的的关系通常在编译时就已经确定了,而装饰者能够在运行时递归地被构造。     
  17.  */  
  18. public class Test {  
  19.     public static void main(String[] args) {  
  20.         /* 
  21.          * 普通的静态代理: 客户端不知道被代理对象,由代理对象完成其功能的调用 
  22.          */  
  23.         IGamePlayer proxy = new GamePlayerProxy("X");  
  24.         System.out.println("开始时间是:" + new Date().toLocaleString());  
  25.         proxy.login("zhangSan""abcd");  
  26.         proxy.killBoss();  
  27.         proxy.upgrade();  
  28.         System.out.println("结束时间是:" + new Date().toLocaleString());  
  29.           
  30.         System.out.println();  
  31.           
  32.         /* 
  33.          * 代理对象 增强了 被代理对象的功能 
  34.          */  
  35.         IGamePlayer proxy2 = new GamePlayerProxy2("M");  
  36.         proxy2.login("lisi""efg");  
  37.         proxy2.killBoss();  
  38.         proxy2.upgrade();  
  39.           
  40.         System.out.println();  
  41.           
  42.         /* 
  43.          * 动态代理:使用jdk提供的InvocationHandler,反射调用被代理对象的方法 
  44.          *  结合java.reflect.Proxy 产生代理对象 
  45.          * 动态传入被代理对象构造InvocationHandler,在handler中的invoke时可以增强被代理对象的方法的功能 
  46.          * 或者说:(面向切面:)在什么地方(连接点), 执行什么行为(通知) 
  47.          * GamePlayerProxy3中是方法名为login时通知开始时间,upgrade时通知结束时间 
  48.          */  
  49.         GamePlayerProxy3 dynamic = new GamePlayerProxy3(new GamePlayer("Y"));  
  50.         IGamePlayer dynamicPlayer = dynamic.getProxy();  
  51.         dynamicPlayer.login("wangwu""1234");  
  52.         dynamicPlayer.killBoss();  
  53.         dynamicPlayer.upgrade();  
  54.         /* 
  55.          * 面向切面: 一些相似的业务逻辑需要加在众多的地方,那们就可以把它提取到切面中, 切面也就是事务切面:如日志切面、权限切面、业务切面 
  56.          */  
  57.     }  
  58. }  

打印:

  1. 开始时间是:2014-10-8 17:19:05  
  2. 登录名为zhangSan 的角色 X登录成功!  
  3. X 在打怪!  
  4. X 又升了一级!  
  5. 结束时间是:2014-10-8 17:19:05  
  6.   
  7. 登录时间是:2014-10-8 17:19:05  
  8. 登录名为lisi 的角色 M登录成功!  
  9. M 在打怪!  
  10. M 又升了一级!  
  11. 升级时间是:2014-10-8 17:19:05  
  12.   
  13. 我是一名代练,我玩的角色是别人的,可以动态传递进来  
  14. 登录时间是:2014-10-8 17:19:05  
  15. 登录名为wangwu 的角色 Y登录成功!  
  16. Y 在打怪!  
  17. 升级时间是:2014-10-8 17:19:05  
  18. Y 又升了一级!  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值