`
VerRan
  • 浏览: 451519 次
  • 性别: Icon_minigender_1
  • 来自: 陕西.西安
社区版块
存档分类
最新评论

代理模式(转)

阅读更多
代理模式(Proxy pattern) 转
 
1. 代理模式
代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式一般涉及到三个角色:
抽象角色:声明真实对象和代理对象的共同接口;
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。
以下以《Java与模式》中的示例为例:
抽象角色:
abstract public class Subject {
   abstract public void request();
真实角色:实现了Subject的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() { }

    public void request() { //该方法封装了真实对象的request方法
        preRequest();
        if( realSubject == null ) {
            realSubject = new RealSubject();
        }
        realSubject.request(); //此处执行真实对象的request方法
        postRequest();
    }

    private void preRequest() {
        //something you want to do before requesting
    }
    private void postRequest() {
        //something you want to do after requesting
    }
}
客户端调用:
Subject sub=new ProxySubject();
Sub.request();
由以上代码可以看出,客户实际需要调用的是RealSubject类的request()方法,现在用ProxySubject来代理 RealSubject类,同样达到目的,同时还封装了其他方法(preRequest(),postRequest()),可以处理一些其他问题。
另外,如果要按照上述的方法使用代理模式,那么真实角色必须是事先已经存在的,并将其作为代理对象的内部属性。但是实际使用时,一个真实角色必须对应一个代理角色,如果大量使用会导致类的急剧膨胀;此外,如果事先并不知道真实角色,该如何使用代理呢?这个问题可以通过Java的动态代理类来解决。
 
2.动态代理类
Java动态代理类位于Java.lang.reflect包下,一般主要涉及到以下两个类:
(1). Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method, Object[] args)。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,如上例中的request(),args为该方法的参数数组。这个抽象方法在代理类中动态实现。

(2).Proxy:该类即为动态代理类,作用类似于上例中的ProxySubject,其中主要包含以下内容:
Protected Proxy(InvocationHandler h):构造函数,估计用于给内部的h赋值。
Static Class getProxyClass (ClassLoader loader, Class[] interfaces):获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。
Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)。
 
所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些 interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。
在使用动态代理类时,我们必须实现InvocationHandler接口,以第一节中的示例为例:
抽象角色(之前是抽象类,此处应改为接口):
public interface Subject {
   abstract public void request();
}
具体角色RealSubject:
public class RealSubject implements Subject{
  public RealSubject(){}
  public void request(){
    System.out.println("From real subject.");
  }
}

代理处理器:
import java.lang.reflect.Method;
import java.lang.reflect.InvocationHandler;
public class DynamicSubject implements InvocationHandler {
  private Object sub;
  public DynamicSubject() {}
  public DynamicSubject(Object obj) {
    sub = obj;
  }
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   System.out.println("before calling " + method);
   method.invoke(sub,args);
   System.out.println("after calling " + method);
   return null;
 }
}
 
该代理类的内部属性为Object类,实际使用时通过该类的构造函数DynamicSubject(Object obj)对其赋值;此外,在该类还实现了invoke方法,该方法中的
method.invoke(sub,args);
其实就是调用被代理对象的将要被执行的方法,方法参数sub是实际的被代理对象,args为执行被代理对象相应操作所需的参数。通过动态代理类,我们可以在调用之前或之后执行一些相关操作。
客户端:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class Client {
static public void main(String[] args) throws Throwable {
   RealSubject rs = new RealSubject(); //在这里指定被代理类
   InvocationHandler ds = new DynamicSubject(rs);
   Class cls = rs.getClass();
   //以下是一次性生成代理
   Subject subject = (Subject) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(),ds );
   subject.request();
}
程序运行结果:
before calling public abstract void Subject.request()
From real subject.
after calling public abstract void Subject.request()
通过这种方式,被代理的对象(RealSubject)可以在运行时动态改变,需要控制的接口(Subject接口)可以在运行时改变,控制的方式(DynamicSubject类)也可以动态改变,从而实现了非常灵活的动态代理关系。
分享到:
评论

相关推荐

    设计模式:创建型之原型(深浅拷贝)、单例(饿汉式与懒汉式),三大工厂模式 结构型之适配器模式,代理模式(三大代理)

    代理模式可以隐藏真是对象的实现细节,使客户端无需知晓真实对象的工作方式和结构。 通过代理类来间接访问真实类,可以在不修改真实类的情况下,对其进行扩展、优化或添加安全措施。 代理模式实现起来简单,易于...

    论文研究-基于代理模式的oneM2M与OCF间协议转换方案 .pdf

    基于代理模式的oneM2M与OCF间协议转换方案,高祥,李永华,oneM2M和OCF是当前应用非常广泛的物联网协议,两种协议的互联互通具有重要的意义。本文以代理模式为基础,提出了oneM2M和OCF在资源模型

    java设计模式【之】Cglib动态代理【源码】【场景:帮爸爸买菜】

    * 代理模式 * 在开发者的角度来看,创建一个代理对象,提供给用户使用,避免用户直接访问真正的对象 * 在用户角度来看,就是普通的类方法调用 * * 作用 * 1.保护被代理对象 * 2.增强被代理对象 * 3.完全...

    Delphi模式编程第一分卷

    15.3.1 代理模式在数据库程序中的应用 15.3.2 范例小结 第四部分 行为型模式编程 第16章 责任链模式(Chain of Responsibility) 16.1 模式解说 16.2 结构和用法 16.2.1 模式结构 16.2.2 代码模板 16.2.3 ...

    Delphi模式编程第二分卷

    15.3.1 代理模式在数据库程序中的应用 15.3.2 范例小结 第四部分 行为型模式编程 第16章 责任链模式(Chain of Responsibility) 16.1 模式解说 16.2 结构和用法 16.2.1 模式结构 16.2.2 代码模板 ...

    JavaScript模式中文[pdf] 百度云

    第1章 简介  模式  JavaScript:基本概念 ... 代理模式  中介者模式  观察者模式  小结  第8章 DOM和浏览器模式  关注分离  DOM脚本  事件  长期运行脚本  远程脚本  配置JavaScript  载入策略

    Java设计模式.docx

    工厂模式:工厂模式是一种创建型模式,它定义了一个用于创建对象的接口,让子类决定实例化哪个类。 单例模式:单例模式是一种创建型模式,它...代理模式:代理模式是一种行为型模式,它允许控制对另一个对象的访问。

    尚硅谷设计模式源码笔记课件.zip

    结构型模式:适配器模式(3种实现)、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式(3种实现)。行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、...

    设计模式(23种)与设计原则(6种)

    12)代理模式(Proxy) 13)职责链模式(Chain of Responsibility) 14)命令模式(Command) 15)解析器模式(Interpreter) 16)迭代器模式(Iterator) 17)中介模式(Mediator) 18)备忘录模式(Memento) 19)...

    Java设计模式 版本2

    设计模式之代理模式,请求的链式处理——职责链模式,请求发送者与接收者解耦——命令模式,自定义语言的实现——解释器模式,遍历聚合对象中的元素——迭代器模式,协调多个对象之间的交互——中介者模式,撤销功能...

    23种设计模式入门到精通详解.txt

    代理模式:为其他对象提供一个代理以便控制这个对象的访问。 亨元(蝇量)模式:通过共享技术来有效的支持大量细粒度的对象。 外观模式:对外提供一个统一的方法,来访问子系统中的一群接口。 桥接模式:将抽象...

    Head First 设计模式 JAVA源码

    第十二讲:代理模式 第十三讲:外观模式 第十四讲:组合模式 第十五讲:桥接模式 第十六讲:适配器模式 第十七讲:解释器模式 第十八讲:中介者模式 第十九讲:职责链模式 第二十讲:迭代模式 第二十一讲:...

    GoF 的 23 种设计模式

    代理(Proxy)模式:为某对象提供一种代理以控制对该对象的访问。即客户端通过代理间接地访问该对象,从而限制、增强或修改该对象的一些特性。 适配器(Adapter)模式:将一个类的接口转换成客户希望的另外一个接口...

    Java23种设计模式详解,看这一个就够了

    Java设计模式共有23种,分别为:抽象工厂模式、建造模式、工厂方法模式、原型模式、单例模式、外观模式、适配器模式、桥接模式、组合模式、装饰模式、享元模式、代理模式、命令模式、解释器模式、访问者模式、迭代子...

    JavaScript模式 斯托扬·斯特凡洛夫 著

    前言 第1章 简介 模式 JavaScript:基本概念 ECMAScript ...代理模式 中介者模式 观察者模式 小结 第8章 DOM和浏览器模式 关注分离 DOM脚本 事件 长期运行脚本 远程脚本 酉己置JavaScript 载入策略 小结

    深入浅出设计模式(中文版)

    4.7ProxyPattern(代理模式) 154 4.7.1定义 154 4.7.2几个现实中的实例 156 4.7.3C#实例——数学代理 158 4.7.4Java实例——Socket回声 160 4.7.5优势和缺陷 165 4.7.6应用情景 165 第5章GoF-...

    深入浅出设计模式(中文版电子版)

    4.7ProxyPattern(代理模式) 154 4.7.1定义 154 4.7.2几个现实中的实例 156 4.7.3C#实例——数学代理 158 4.7.4Java实例——Socket回声 160 4.7.5优势和缺陷 165 4.7.6应用情景 165 第5章GoF-...

    12种常用设计模式C#代码示例

    OO基础:抽象,封装,多态,继承。 设计原则(OO原则)汇总 1、封装变化:找出应用中可能变化之处,把它们独立出来,不要和那些不需要...12,代理模式:为另一个对象提供一个替身或者占位符以控制对这个对象的访问。

    【高清PDF下载】ChatGPT Simple Cheatsheet速查表-Prompt编写模式-如何将思维框架赋予机器.pdf

    文档为 prompt 的编写,总结了四种基础模式:特定指令(By specific),指令模板(Instruction Template),代理模式(By proxy),示例模式(By demonstration),并为每种模式设计了模板,直接套用就可以玩转 AI!

Global site tag (gtag.js) - Google Analytics