`
dr2tr
  • 浏览: 138695 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Design Patterns -- Proxy

阅读更多

1。代理的分类:

  • 远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局域代表对象。这个不同的地址空间可以是在本机器中,也可是在另一台机器中。远程代理又叫做大使(Ambassador)。
  • 虚拟(Virtual)代理:根据需要创建一个资源消耗较大的对象,使得此对象只在需要时才会被真正创建。
  • Copy-on-Write代理:虚拟代理的一种。把复制(克隆)拖延到只有在客户端需要时,才真正采取行动。
  • 保护(Protect or Access)代理:控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限。
  • Cache代理:为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。
  • 防火墙(Firewall)代理:保护目标,不让恶意用户接近。
  • 同步化(Synchronization)代理:使几个用户能够同时使用一个对象而没有冲突。
  • 智能引用(Smart Reference)代理:当一个对象被引用时,提供一些额外的操作,比如将对此对象调用的次数记录下来等。

2。代理的结构:

代理模式的类图如下图所示:

代理模式所涉及的角色有:

抽象主题角色(Subject):声明了真实主题和代理主题的共同接口,这样一来在任何使用真实主题的地方都可以使用代理主题。

代理主题(Proxy)角色:代理主题角色内部含有对真是主题的引用,从而可以在任何时候操作真实主题对象;代理主题角色提供一个与真实主题角色相同的接口,以便可以在任何时候都可以替代真实主体;控制真实主题的应用,负责在需要的时候创建真实主题对象(和删除真实主题对象);代理角色通常在将客户端调用传递给真实的主题之前或之后,都要执行某个操作,而不是单纯的将调用传递给真实主题对象。

真实主题角色(RealSubject)角色:定义了代理角色所代表的真实对象。

3。以《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();

 

4。动态代理类

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类)也可以动态改变,从而实现了非常灵活的动态代理关系。

分享到:
评论

相关推荐

    Packt.Go.Design.Patterns.2017

    Structural Patterns - Proxy, Facade, Decorator, and Flyweight Design Patterns Chapter 5. Behavioral Patterns - Strategy, Chain of Responsibility, and Command Design Patterns Chapter 6. Behavioral ...

    Spring 5 Design Patterns

    You will then learn to use Proxy patterns in Aspect Oriented Programming and remoting. Moving on, you will understand the JDBC template patterns which will look at abstracting the database access. ...

    design-patterns-spring-boot:Spring引导中的设计模式

    git clone https://github.com/indrekru/design-patterns-spring-boot.git 您需要在您的环境中安装Maven: Mac(自制): brew install maven Ubuntu: sudo apt-get install maven 正在安装 在环境中安装了Maven...

    Head First Design Patterns

    you want to learn the 'secret language' of Design Patterns so that you can hold your own with your co-worker (and impress cocktail party guests) when he casually mentions his stunningly clever use of ...

    Design.Patterns.Explained.Simply

    We've tried hard to avoid both of these categories with Design Patterns Explained Simply. This book is fast and simple way to get the idea behind each of the 29 popular design patterns. The book is ...

    Design Patterns Elements of Reusable Object-Oriented Software

    • How Design Patterns Solve Design Problems • How to Select a Design Pattern • How to Use a Design Pattern A Case Study: Designing a Document Editor • Design Problems • Document Structure ...

    Beginning SOLID Principles and Design Patterns for ASP.NET Developers.pdf

    ■Chapter 6: Structural Patterns: Façade, Flyweight, and Proxy ■Chapter 7: Behavioral Patterns: Chain of Responsibility, Command, Interpreter, and Iterator ■Chapter 8: Behavioral Patterns: Mediator...

    Learning Python Design Patterns(PACKT,2013)

    Then you will move on to learn about two creational design patterns which are Singleton and Factory, and two structural patterns which are Facade and Proxy. Finally, the book also explains three ...

    Apress.Pro.Design.Patterns.in.Swift

    Pro Design Patterns in Swift shows you how to harness the power and flexibility of Swift to apply the most important and enduring design patterns to your applications, taking your development ...

    Learning Python Design Patterns 2nd 2016第2版 无水印pdf 0分

    After this, we'll look at how to control object access with proxy patterns. It also covers observer patterns, command patterns, and compound patterns. By the end of the book, you will have enhanced ...

    《Java Design Patterns》高清完整英文PDF版

    Chapter 4: Proxy Patterns Chapter 5: Decorator Patterns Chapter 6: Template Method Patterns Chapter 7: Strategy Patterns (Or, Policy Patterns) Chapter 8: Adapter Patterns Chapter 9: Command Patterns ...

    Selenium Design Patterns and Best Practices 最新 原版

    Stabilize your tests by using patterns such as the Action Wrapper and Black Hole Proxy patterns In Detail Selenium WebDriver is a global leader in automated web testing. It empowers users to ...

    Head First Design Patterns 英文原版

    of Design Patterns so that you can hold your own with your co-worker (and impress cocktail party guests) when he casually mentions his stunningly clever use of Command, Facade, Proxy, and Factory in ...

    Selenium Design Patterns and Best Practices(PACKT,2014)

    Selenium WebDriver is a global leader in automated web testing. It empowers users to perform complex ...Stabilize your tests by using patterns such as the Action Wrapper and Black Hole Proxy patterns

    design patterns elements of reusable object-oriented software

    ★第1章至第11章陆续介绍了设计模式:Strategy、Observer、Decorator、Abstract Factory、Factory Method、Singleton、Command、Adapter、Facade、TemplatMethod、Iterator、Composite、State、Proxy。 ★第12章介绍...

    Head First Design Patterns 高清英文版

    第1章到第11章陆续介绍的设计模式为Strategy、Observer、Decorator、Abstract Factory、Factory Method、Singleton,Command、Adapter、Facade、TemplateMethod、Iterator、Composite、State、Proxy。最后三章比较...

    Head First Design Patterns 英文版 Head First设计模式

    《Head First Design Patterns》编辑推荐:强大的写作阵容。《Head First Design Patterns》作者Eric Freeman;ElElisabeth Freeman是作家、讲师和技术顾问。Eric拥有耶鲁大学的计算机科学博士学位,E1isabath拥有...

Global site tag (gtag.js) - Google Analytics