A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© java_dream 中级黑马   /  2014-9-5 17:36  /  2519 人查看  /  13 人回复  /   6 人收藏 转载请遵从CC协议 禁止商业使用本文


代理模式的定义:对其他对象提供一种代理以控制对这个对象的访问。




       代理模式的主要作用是为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。代理类和目标类需实现相同接口。

       代理模式的思想是为了提供额外的处理或者不同的操作而在实际对象与调用者之间插入一个代理对象。这些额外的操作通常需要与实际对象进行通信。

       按照代理类的创建时机,代理类分为2种:静态代理和动态代理

       静态代理类:
      由程序员创建或由特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
      应用场景(转摘中国IT实验室)——比如在玩“极品飞车”这款游戏,如果游戏者手中的金钱达到了一定的数量就可以到车店买一部性能更高的赛车,那                                    么个卖车的“车店”就一个典型的“汽车厂家”的“代理”,他为汽车厂家“提供卖车的服务”给有需求的人士。   新建一个买车接口:
  1. package proxy;

  2. public interface BuyCar {
  3.        
  4.         public void buyCar(int money);

  5. }
复制代码
   新建一个people人类,具有买车的行为,所以实现接口BuyCar:
  1. <blockquote><font face="宋体"><span style="line-height: 25px; white-space: normal;">package proxy;</span></font>
复制代码
   people类不能拥有车,必须经过proxy代理类的认证,符合条件之后才可以拥有车辆,新建一个代理,这个代理类来考察当前的people是否有资格进行买车:
  1. <font face="宋体"><span style="line-height: 25px;">package proxy;

  2. public class ProxyBuyCar implements BuyCar{
  3.        
  4.         private People people;

  5.         public People getPeople() {
  6.                 return people;
  7.         }

  8.         public void setPeople(People people) {
  9.                 this.people = people;
  10.         }

  11.         @Override
  12.         public void buyCar(int money) {
  13.                 if(people.getCash()>=money){
  14.                         System.out.println(people.getUsername()+"  花了"+money+"块   买了新车   交易结束");
  15.                 }else{
  16.                         System.out.println(people.getUsername()+"  金钱不够,继续比赛");
  17.                 }
  18.         }

  19. }</span></font>
复制代码
  最后创建一个客户端,用来模拟买车的行为:
  1. <font face="宋体"><span style="line-height: 25px;">package proxy;

  2. import java.lang.reflect.Constructor;
  3. import java.lang.reflect.Proxy;

  4. public class ProxyTest {

  5.         public static void main(String[] args) throws Exception {
  6.                 People p1 = new People();
  7.                 p1.setCash(40000);
  8.                 p1.setUsername("玩家1");

  9.                 People p2 = new People();
  10.                 p2.setCash(9000);
  11.                 p2.setUsername("玩家2");
  12.                
  13.                 ProxyBuyCar pb = new ProxyBuyCar();
  14.                
  15.                 pb.setPeople(p1);
  16.                 pb.buyCar(10000);
  17.                
  18.                 pb.setPeople(p2);
  19.                 pb.buyCar(10000);
  20.         }

  21. }</span></font>
复制代码
  运行结果:
  1. <font face="宋体"><span style="line-height: 25px;">玩家1  花了10000块   买了新车   交易结束
  2. 玩家2  金钱不够,继续比赛</span></font>
复制代码
    这个例子中,people对象不能直接拥有车子,为了增加验证people金钱数量而提供一个代理对象。      动态代理类:在程序运行时,运用反射机制动态创建而成。  使用java动态代理机制实现上面的场景:实现InvocationHandler接口,并重写invoke()方法:
  1. package proxy;

  2. import java.lang.reflect.InvocationHandler;
  3. import java.lang.reflect.Method;

  4. public class MyInvocationHandler implements InvocationHandler{
  5.         private People target;
  6.         public void setTarget(People target){
  7.                 this.target = target;
  8.         }
  9.        
  10.         @Override
  11.         public Object invoke(Object proxy, Method method, Object[] args)
  12.                         throws Throwable {
  13.                 Object result = null;
  14.                 int money = (Integer)args[0];
  15.                 if(target.getCash()>=money){
  16.                         result = method.invoke(target, money);
  17.                 }else{
  18.                         System.out.println(target.getUsername()+"  金钱不够,继续比赛");
  19.                 }
  20.                 return result;
  21.         }

  22. }
复制代码
最后创建一个客户端,用来模拟买车的行为:
  1. package proxy;

  2. import java.lang.reflect.Constructor;
  3. import java.lang.reflect.Proxy;

  4. public class ProxyTest {

  5.         public static void main(String[] args) throws Exception {
  6.                 People p1 = new People();
  7.                 p1.setCash(40000);
  8.                 p1.setUsername("玩家1");

  9.                 People p2 = new People();
  10.                 p2.setCash(9000);
  11.                 p2.setUsername("玩家2");

  12.                 MyInvocationHandler mh = new MyInvocationHandler();

  13.                 mh.setTarget(p1);
  14.                 BuyCar proxy = (BuyCar) Proxy.newProxyInstance(p1.getClass()
  15.                                 .getClassLoader(), p1.getClass().getInterfaces(), mh);
  16.                 proxy.buyCar(10000);

  17.                 mh.setTarget(p2);
  18.                 BuyCar proxy2 = (BuyCar) Proxy
  19.                                 .newProxyInstance(BuyCar.class.getClassLoader(),
  20.                                                 new Class[] { BuyCar.class }, mh);
  21.                 proxy2.buyCar(10000);
  22.         }

  23. }
复制代码
运行结果:
  1. 玩家1  花了10000块   买了新车   交易结束
  2. 玩家2  金钱不够,继续比
复制代码
   静态代理与动态代理本质是一致的,只是代理类的创建时机不一样。另外,一般代理类会保留目标对象的引用,由代理类来访问目标对象,从而控制对目标对象的访问。
   这个例子也体现了代理模式的思想: 是为了提供额外的处理或者不同的操作而在实际对象与调用者之间插入一个代理对象。







13 个回复

倒序浏览
还在为进黑马努力中!! 今天刚好看完一遍 张老师的讲解 很多知识点有点迷惑 . 楼主的帖子让我在复习下.思路清晰多了. 谢谢楼主分享....发现第一次坐沙发..嘿嘿!!!
回复 使用道具 举报
姠佐メ亾佑つ 发表于 2014-9-11 18:18
还在为进黑马努力中!! 今天刚好看完一遍 张老师的讲解 很多知识点有点迷惑 . 楼主的帖子让我在复习下.思 ...

谢谢,加油!
回复 使用道具 举报
自己总结的还是找的资料?
回复 使用道具 举报
xiayoutianxia 发表于 2014-9-11 19:52
自己总结的还是找的资料?

算是总结吧,是从不同的资料整合到一起的
回复 使用道具 举报
楼主辛苦~~~~
回复 使用道具 举报
楼主 这是博客吧  感觉很好 相当收益
回复 使用道具 举报
水了个淼 发表于 2014-9-12 10:44
楼主 这是博客吧  感觉很好 相当收益

这是看到有同学问道代理与动态代理的问题,才觉得应该总结一下的
回复 使用道具 举报
楼主辛苦了
回复 使用道具 举报
这是你自己总结的吗?值得看看!
回复 使用道具 举报
非常不错的讲解,比高新技术视频中的例子更清晰一些
回复 使用道具 举报
贾浩田 发表于 2014-9-14 22:53
非常不错的讲解,比高新技术视频中的例子更清晰一些

写的让人看得懂就好,编辑的格式有点凌乱
回复 使用道具 举报
学习学习!
回复 使用道具 举报
讲得很详细
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马