代理模式是对象的结构模式,代理模式给某一个对象提供一个代理对象,并由代理对象控制原对象的引用。换言之,就是一个人或者一个机构代表另一个人或者另一个机构采取行动。在一些情况下,一个客户不想或不能直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
一、代理的种类
①远程代理:为一个位于不同的地址空间的对象提供一个局域代表对象。这个不同的地址空间可以是本机器中,也可是在另一台机器中。
②虚拟代理:根据需要创建一个资源消耗较大的对象,使得此对象只在需要时才会被真正创建。
③copy-on-write代理:虚拟代理中的一种。把复制(克隆)拖延到只有在客户端需要时,才真正采取行动。
④保护代理:控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限。
⑤cache代理:为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。
⑥防火墙代理:保护目标,不让恶意用户接近。
⑦同步化代理:使几个用户能够同时使用一个对象而没有冲突。
⑧智能引用代理:当一个对象呗引用是,提供一些额外的操作,比如讲对此对象调用的次数记录下来。
二、代理模式的结构
代理模式所涉及的角色有:
①抽象主题角色:声明了真实主题和代理主题的共同接口,这样一来在任何可以使用真实主题的地方都可以使用代理主题;
②代理主题(proxy)角色:代理主题角色内部含有对真实主题的引用,从而可以在任何时候操作真实主题对象;代理主题角色提供一个与真实主题角色相同的接口,以便可以在任何时候都可以替代真实主题;控制对真实主题的引用,负责在需要的时候创建真实主题对象(和删除真实主题对象);代理角色通常在将客户端调用传递给真实的主题之前或者之后,都要执行某个操作,而不是单纯的将调用传给真实主题对象。
③真实主题角色:定义了代理角色所代表的真实对象。
实例类图如下:
示例代码如下:
//抽象主题的源代码 public abstract class Subject { //声明一个抽象的请求方法 public abstract void request(); } //真是主题角色源代码 public class RealSubject extends Subject{ public RealSubject(){} //实现请求方法 public void request(){ System.out.println("From real subject"); } } //代理主题角色的源代码 public class ProxySubject extends Subject{ private RealSubject realSubject; public ProxySubject(){} @Override public void request() { preRequest(); if(realSubject == null){ this.realSubject = new RealSubject(); } realSubject.request(); postRequest(); } //请求前的操作 private void preRequest(){ //something you want to do before requesting } //请求后的操作 private void postRequest(){ //something you want to do after requesting } } //调用代理主题 Subject subject = new ProxySubject(); subject.request();
从上面的代理主题类的示意性源代码可以看出代理模式是怎样工作的。首先,代理主题并不改变主题的接口,因为模式的用意是不让客户端感觉到代理的存在;其次,代理使用委派将客户端的调用委派给真实的主题对象,换言之,代理主题起到的是一个传递请求的作用;最后,代理主题在传递请求之前和之后都可以执行特定的操作,而不是单纯传递请求。
三、动态代理
在java提供的反射基础上,衍生出来了动态代理。动态代理具有更强的灵活性,因为它不用在我们设计实现的时候就指定某一个代理类来代理哪一个被代理对象,我们可以把这种指定延迟到程序运行时由JVM来实现。
我们知道,所谓代理,就是需要代理类和被代理类有相同的对外接口或者说成服务,所以代理类一般都必须实现了所有被代理类已实现的接口,因为接口就是制定了一系列对外服务的标准。动态代理正因为有这样灵活的特性,所以我们在设计动态代理类(DynamicProxy)时不用显式地让它实现与真实主题类(RealSubject)相同的接口(interface),而是把这种实现推迟到运行时。
下面看一下动态代理实现的实例代码:
//抽象主题类,这里不能用abstract抽象类,一定要是interface interface AbstractSubject { public void request(); } // 真实主题类,即被代理类 class RealSubject implements AbstractSubject { public void request() { System.out.println("RealSubject's request() ..."); } } // 动态代理类,实现InvocationHandler接口 class DynamicProxy implements InvocationHandler { // 被代理类的实例 Object obj = null; // 将被代理者的实例传进动态代理类的构造函数中 public DynamicProxy(Object obj) { this.obj = obj; } /** * 覆盖InvocationHandler接口中的invoke()方法 * * 更重要的是,动态代理模式可以使得我们在不改变原来已有的代码结构 * 的情况下,对原来的“真实方法”进行扩展、增强其功能,并且可以达到 * 控制被代理对象的行为,下面的before、after就是我们可以进行特殊 * 代码切入的扩展点了。 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { /* * before :doSomething(); */ Object result = method.invoke(this.obj, args); /* * after : doSomething(); */ return result; } } // 测试类 public class Client { public static void main(String[] args) { // 被代理类的实例 AbstractSubject realSubject = new RealSubject(); // 获得被代理类的类加载器,使得JVM能够加载并找到被代理类的内部结构,以及已实现的interface ClassLoader loader = realSubject.getClass().getClassLoader(); // 获得被代理类已实现的所有接口interface,使得动态代理类的实例 Class<?>[] interfaces = realSubject.getClass().getInterfaces(); // 用被代理类的实例创建动态代理类的实例,用于真正调用处理程序 InvocationHandler handler = new DynamicProxy(realSubject); /* * loader : 被代理类的类加载器 * interfaces :被代理类已实现的所有接口,而这些是动态代理类要实现的接口列表 * handler : 用被代理类的实例创建动态代理类的实例,用于真正调用处理程序 * * return :返回实现了被代理类所实现的所有接口的Object对象,即动态代理,需要强制转型 */ //获得代理的实例 AbstractSubject proxy = (AbstractSubject) Proxy.newProxyInstance( loader, interfaces, handler); proxy.request(); //打印出该代理实例的名称 System.out.println(proxy.getClass().getName()); } }
输出内容为:RealSubject's request() ...
总体来说,我们可以按照下面的步骤创建动态代理对象:
①指明一系列的接口来创建一个代理对象;
②创建一个调用处理器对象;
③将这个代理指定为某个其他对象的代理对象;
④在调用处理器的invoke()方法中采取代理,一方面将调用传递真实对象,另一方面执行各种需要做的操作;
相关推荐
### 代理模式 Proxy Pattern #### 概念定义 代理模式是一种结构型设计模式,它允许程序员为某对象创建一个代理对象来控制对该对象的访问。简单来说,就是在不修改原始类的基础上,通过引入代理对象来扩展类的行为...
**设计模式之代理模式(Proxy Pattern)** 设计模式是软件工程中的一种最佳实践,它是在特定情境下解决常见问题的模板。代理模式是其中一种行为设计模式,它的核心思想是为一个对象提供一个替身或者代理,以控制对...
全部高质量代理模式proxy的java源程序 java.proxy,代理模式源码,设计模式,apache开源项目源码commons-proxy-1.0-src 各种代理模式操作的工具类源码以及代理模式案例源码,你会从中得到意想不到的效果! apache...
代理模式是一种常用的设计模式,它在软件开发中扮演着重要的角色。代理模式允许我们为一个对象创建一个代理,这个代理对象在客户端和目标对象之间起到中介的作用,可以增强或控制对目标对象的访问。代理模式的主要...
代理模式是设计模式中的一种结构型模式,它在对象交互中起到了中介的作用,允许通过代理对象来控制对原对象的访问。代理模式的核心思想是为一个对象提供一个替身,以便增加新的功能或者控制对原对象的访问。这种模式...
在`proxy-learn`这个压缩包中,应该包含了这两种代理模式的详细示例代码,供初学者参考学习。对于初学者来说,理解并掌握代理模式是提升编程能力的重要步骤,它能帮助我们更好地理解和应用面向对象设计原则。
代理模式是一种设计模式,它是结构型模式之一,主要用于在客户端和目标对象之间建立一个代理对象,以便控制对目标对象的访问。在C++中,代理模式可以用来为其他对象提供一种代理以控制对这个对象的访问,或者增加...
代理模式(Proxy Pattern)是一种结构型设计模式,用于为其他对象提供一种代理以控制对这个对象的访问。代理模式通常用于保护、延迟加载、记录请求等场景,可以在不改变原有对象的情况下为其增加新的功能。 代理...
代理模式是一种设计模式,属于结构型模式之一,其主要目的是为其他对象提供一个代理,以控制对该对象的访问。在实际应用中,代理模式能够帮助我们实现如下的功能: 1. 远程代理:代理对象可以代表一个位于远程系统...
代理模式是设计模式的一种,它的主要目的是在不改变原有对象的基础上,为一个对象提供额外的功能或者控制对这个对象的访问。在Android开发中,代理模式的应用尤为常见,尤其在处理复杂的业务逻辑、网络请求、界面...
在这些模式中,代理模式(Proxy Pattern)是一种常用的结构型设计模式,它允许我们为一个对象创建一个代理,该代理对象在客户端和目标对象之间起到中介的作用,可以增加额外的功能或控制访问。 代理模式分为两种...
代理模式也是平时比较常用的设计模式之一,代理模式其实就是提供了一个新的对象,实现了对真实对象的操作,或成为真实对象的替身.在日常生活中也是很常见的.例如A要租房,为了省麻烦A会去找中介,中介会替代A去筛选房子,A...
2、代理模式PROXY PATTERN 3、单例模式SINGLETON PATTERN 4、多例模式MULTITION PATTERN 5、工厂方法模式FACTORY METHOD PATTERN 6、抽象工厂模式ABSTRACT FACTORY PATTERN 7、门面模式FACADE PATTERN 8、适配器...
代理模式是一种设计模式,它允许我们为一个对象创建一个代理对象,这个代理对象在客户端和目标对象之间起到中介的作用,可以实现额外的功能,比如监控、权限控制、事务管理等,而客户端无需关心这些细节。...
Proxy代理模式是面向对象设计模式中的重要组成部分,它在软件工程中扮演着关键角色,尤其在Java编程中。代理模式的主要目的是为一个对象提供一个替身或者占位符,以便控制对这个对象的访问。这种设计模式允许我们...
观察者模式 Observer:Swing中的事件模型 工厂模式 Factory:在JDK中遍地都是,比如JDBC、JNDI等,是...Strategy:java.util.Comparator就用到了它 代理模式 Proxy:学习Spring IoC容器必须掌握的模式 <br>
这个"proxy.rar"压缩包中包含了这三种代理模式的源代码示例,以及对泛型的应用。 1. 静态代理: 静态代理是最基础的代理形式,它通过创建一个代理类来实现目标接口,并在代理类中调用目标对象的方法。这种方式需要...
在代理模式中,有三个关键角色:真实目标(Real Subject)、代理(Proxy)和客户端(Client)。真实目标是代理所代表的对象,它执行实际的工作。代理则扮演真实目标的替身,它持有对真实目标的引用,并且在客户端与...
代理模式是一种设计模式,它允许我们为一个对象创建一个代理对象,这个代理对象可以在原对象进行某些操作之前或之后添加额外的功能。代理模式的核心在于,它提供了一种方式来间接访问或控制目标对象,增加了系统的...