博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
代理 模式
阅读量:4644 次
发布时间:2019-06-09

本文共 3098 字,大约阅读时间需要 10 分钟。

概述:

  代理模式:为另一个对象提供一个替身(或占位符),以控制对该对象的访问;

  使用代理模式创建代理对象,让代理对象控制某对象的访问,被代理的对象可以是远程(或创建开销大、需要安全控制的)对象。

要点:

  • 代理角色内部含有对真实角色的引用:从而可以在任何时候操作真实角色对象
  • 代理角色真实角色实现同一接口:以便可以在任何时候都可以替代真实角色,负责在需要的时候创建(删除)真实角色对象。
  • 代理角色通常在将客户端调用传递给真实主题之前(或之后),都要执行某个操作(如检验参数),而非单纯将调用传递给真实角色对象。

一、uml类图

二、(静态)代理 模式的实现

1,主题角色

package static_proxy;//主题角色(抽象)public interface IBuyCar {  public void buyCar();}

  

2,目标角色

 View Code

3,代理角色

1 package static_proxy; 2  3 public class BuyCarProxy implements IBuyCar{ 4     private Customer customer;//接收买车客户 5  6     public BuyCarProxy(Customer customer){ 7         this.customer=customer;//接收买车客户 8     } 9 10     @Override11     public void buyCar() {
//实现为客户买车12 customer.buyCar();13 }14 15 }
View Code

4,测试

1 package static_proxy; 2  3 public class Main { 4     public static void main(String[] args) { 5         Customer customer = new Customer(); 6         customer.setCash(120000); 7          8         BuyCarProxy buyCarProxy = new BuyCarProxy(customer); 9         buyCarProxy.buyCar();10     }11 }
View Code

三、(动态)代理 模式的实现(通过 jdk)

  JDK提供的动态代理需要实现InvocationHandler接口的invoke方法(此方法为整个代理的入口)。

  方法签名:

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable

  第一个参数proxy:代理对象

  第二个参数目method:目标方法

  第三个参数args:目标方法的参数

  问题:若使用(静态)代理,则当目标接口需要增加新的方法时,则对应的代理类也需要进行相应的改动,维护工程比较大。故需要(动态)代理

  (静态-》动态)目标接口以及目标实现不需要改变,但BuyCarProxy(静态代理类)修改为实现InvocationHandler的处理类:

  1,静态代理类 修改 为   

1 package dynamic_proxy; 2  3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5  6 public class ProxyHandler implements InvocationHandler{ 7     Object  target; 8      9     public ProxyHandler(Object  target) {10         this.target=target;11     }12   //验证参数(代理对象处理目标对象前)13     public void before(String param){14         System.out.println("参数检验:" + param);15     }16     @Override17     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {18         this.before(null);19         20         return method.invoke(this.target, args);21     }22     23     24 }
View Code

  2,测试类(即使增加实现的方法,也不用修改代理)

1 package dynamic_proxy; 2  3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Proxy; 5  6 public class Main { 7     public static void main(String[] args) { 8          //我们要代理的真实对象 9         Customer customer = new Customer();10         //我们要代理哪个真实对象,就将该对象传进去,最后是通过该真实对象来调用其方法的11         InvocationHandler handler = new ProxyHandler(customer);12 13         /*14          * 通过Proxy的newProxyInstance方法来创建我们的代理对象,我们来看看其三个参数15          * 第一个参数 handler.getClass().getClassLoader() ,我们这里使用handler这个类的ClassLoader对象来加载我们的代理对象16          * 第二个参数customer.getClass().getInterfaces(),我们这里为代理对象提供的接口是真实对象所实行的接口,表示我要代理的是该真实对象,这样我就能调用这组接口中的方法了17          * 第三个参数handler, 我们这里将这个代理对象关联到了上方的 InvocationHandler 这个对象上18          */19         IBuyCar buyCar = (IBuyCar) Proxy.newProxyInstance(handler.getClass().getClassLoader(), customer.getClass().getInterfaces(), handler);20         buyCar.search();21         buyCar.buyCar();22     }23 }
View Code

 

  

转载于:https://www.cnblogs.com/listened/p/8047046.html

你可能感兴趣的文章
CodeForces743E. Vladik and cards 二分+状压dp
查看>>
GO语言面向对象
查看>>
1111评论
查看>>
CodeForces 546E - Soldier and Traveling(最大流)
查看>>
linux下(Window当然也可以)解决idea创建maven项目导入过慢问题
查看>>
如何设计一个完美的权限管理模块
查看>>
layer---口碑极佳的web弹层组件
查看>>
自己的一些简要学习点
查看>>
HTPJ 1268 GCD
查看>>
细说程序员最后归宿
查看>>
hdu2063 匈牙利算法 二分最大匹配模版题
查看>>
工作中的一些经验小结
查看>>
百度地图JavaScript API如何在同一页面显示多个地图?
查看>>
揭秘快速提升alexa排名的18种有效方法-2 -#来秀美#
查看>>
计算机专业及软件开发推荐书籍
查看>>
《Java程序设计》 课程教学
查看>>
Lambda--持续学习中
查看>>
简单谈谈面向对象和面向过程的区别
查看>>
Intellij IDEA 配置Tomcat远程调试
查看>>
python3 进程和线程(一)
查看>>