`

05 Proxy 模式(二)

 
阅读更多

转自:http://www.riabook.cn/doc/designpattern/

Design Pattern: Proxy 模式(二)

 

延续 Proxy模式(一) 的议题,来看看实现代理的两种方式:Static Proxy与Dynamic Proxy。严格来说这是属于模式的实现方式,不过藉由实例可以更了解Proxy模式的应用。

先来看个例子,这个例子是记录(log)动作,程式中很常需要为某些动作或事件作下记录,以便在事后检视或是作为除错时的资讯,一个最简单的例子如下:
HelloSpeaker.java

import java.util.logging.*; 

public class HelloSpeaker { 
    private Logger logger = 
               Logger.getLogger(this.getClass().getName()); 

    public void hello(String name) { 
        logger.log(Level.INFO, "hello method starts....");

        System.out.println("Hello, " + name); 

        logger.log(Level.INFO, "hello method ends...."); 
    } 
} 

 

HelloSpeaker在执行hello()方法时,您希望能记录该方法已经执行及结束,最简单的作法就是如上在执行的前后加上记录动作,然而 Logger介入了HelloSpeaker中,记录这个动作并不属于HelloSpeaker,这使得HelloSpeaker增加了非业务上需要的逻 辑在当中。

想想如果程式中这种记录的动作到处都有需求,上面这种写法势必造成必须复制记录动作的程式码,使得维护记录动作的困难度加大。如果不只有记录动作,有一些 非物件本身职责的相关动作也混入了物件之中(例如权限检查、事务管理等等),会使得物件的负担更形加重,甚至混淆了物件的职责,物件本身的职责所占的程式 码,或许远小于这些与物件职责不相关动作的程式码。

怎么办,用下面的方法或许好一些,先定义一个介面,然后实作该介面:
IHello.java

public interface IHello { 
    public void hello(String name); 
} 

 

HelloSpeaker.java

public class HelloSpeaker implements IHello { 
    public void hello(String name) { 
        System.out.println("Hello, " + name); 
    } 
} 

 

接下来实作一个代理物件HelloProxy:
HelloProxy.java

import java.util.logging.*; 

public class HelloProxy implements IHello { 
    private Logger logger = 
              Logger.getLogger(this.getClass().getName()); 
    private IHello helloObject; 

    public HelloProxy(IHello helloObject) { 
        this.helloObject = helloObject; 
    } 

    public void hello(String name) { 
        logger.log(Level.INFO, "hello method starts...."); 

        helloObject.hello(name); 

        logger.log(Level.INFO, "hello method ends...."); 
    } 
}

 

执行时可以如此:
IHello helloProxy = new HelloProxy(new HelloSpeaker());
helloProxy.hello("Justin");

代理物件HelloProxy将代理真正的HelloSpeaker来执行hello(),并在其前后加上记录的动作,这使得 HelloSpeaker在撰写时不必介入记录动作,HelloSpeaker可以专心于它的职责。

这是Static Proxy的基本范例,然而如您所看到的,代理物件的一个介面只服务于一种类型的物件,而且如果要代理的方法很多,势必要为每个方法进行代理, Static Proxy在程式规模稍大时就必定无法胜任。

Java在JDK 1.3之后加入协助开发Dynamic Proxy功能的类别,我们不必为特定物件与方法撰写特定的代理,使用Dynamic Proxy,可以使得一个handler服务于各个物件,首先,一个handler必须实现 java.lang.reflect.InvocationHandler:
LogHandler.java

import java.util.logging.*; 
import java.lang.reflect.*; 

public class LogHandler implements InvocationHandler { 
    private Logger logger = 
               Logger.getLogger(this.getClass().getName()); 
    private Object delegate; 

    public Object bind(Object delegate) { 
        this.delegate = delegate; 
        return Proxy.newProxyInstance(
                 delegate.getClass().getClassLoader(), 
                 delegate.getClass().getInterfaces(), 
                 this); 
    }
 
    public Object invoke(Object proxy, 
                         Method method, 
                         Object[] args) throws Throwable {
        Object result = null; 
        try { 
            logger.log(Level.INFO, 
                         "method starts..." + method); 
            result = method.invoke(delegate, args); 
            logger.log(Level.INFO, 
                         "method ends..." + method); 
        } catch (Exception e){ 
            logger.log(Level.INFO, e.toString()); 
        } 
        return result; 
    } 
} 

 

InvocationHandler的invoke()方法会传入被代理物件的方法名称与执行参数实际上要执行的方法交由method.invoke (),并在其前后加上记录动作,method.invoke()传回的物件是实际方法执行过后的回传结果。

Dynamic Proxy必须宣告介面,实作该介面,例如:
IHello.java

public interface IHello { 
    public void hello(String name); 
} 

 

 HelloSpeaker.java

public class HelloSpeaker implements IHello { 
    public void hello(String name) { 
        System.out.println("Hello, " + name); 
    } 
} 

 

java.lang.reflect.Proxy的newProxyInstance()依要代理的物件、介面与handler产生一个代理物件,我们可 以使用下面的方法来执行程式:
LogHandler logHandler = new LogHandler();
IHello helloProxy = (IHello) logHandler.bind(
new HelloSpeaker());
helloProxy.hello("Justin");

LogHandler不在服务于特定物件与介面,而HelloSpeaker也不用插入任何有关于记录的动作,它不用意识到记录动作的存在。

分享到:
评论

相关推荐

    Proxy 模式学习代码

    Proxy模式是一种设计模式,它允许我们为一个对象创建一个代理对象,这个代理对象在客户端和目标对象之间起到中介的作用。这种模式在软件工程中广泛应用,主要用于控制对真实对象的访问,提供额外的功能,如日志、...

    简单工厂模式,工厂方法模式,抽象工厂模式和Proxy模式

    到工厂方法到抽象工厂,这几种都带有“工厂”的模式,总是容易叫人迷糊,我仔细研究了下,然后用简单的例子做类比,列出了自己的通俗理解和比较,大部分是自己的体会,感觉理的比较清楚,末尾提了下Proxy模式。

    设计模式C++学习之代理模式(Proxy)

    代理模式是一种设计模式,它是结构型模式之一,主要用于在客户端和目标对象之间建立一个代理对象,以便控制对目标对象的访问。在C++中,代理模式可以用来为其他对象提供一种代理以控制对这个对象的访问,或者增加...

    设计模式之代理模式proxy.zip

    JDK动态代理基于接口实现,它要求目标对象必须实现至少一个接口,然后通过Proxy类和InvocationHandler接口来创建并控制代理对象。当我们调用代理对象的方法时,实际执行的是InvocationHandler的invoke方法,这样可以...

    C++ Proxy模式

    Proxy模式是软件设计模式中的一个关键元素,属于结构型模式的一种。在C++中,Proxy模式主要用于为其他对象提供一种代理以控制对这个对象的访问。这种模式的核心思想是通过创建一个代理对象来充当目标对象的中介,...

    Proxy模式

    Proxy模式是一种设计模式,它在软件工程中扮演着重要的角色,允许我们为其他对象提供一个替代接口,从而控制对原对象的访问。这种模式的主要目的是为了增加灵活性、添加额外功能或者在访问对象时提供安全控制。在...

    从房屋买卖看 java proxy 模式

    标题中的“从房屋买卖看 java proxy 模式”暗示了我们将通过一个具体的场景来探讨 Java 中的代理(Proxy)模式。在软件设计中,代理模式是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。在...

    设计模式之代理模式proxy

    **设计模式之代理模式(Proxy Pattern)** 设计模式是软件工程中的一种最佳实践,它是在特定情境下解决常见问题的模板。代理模式是其中一种行为设计模式,它的核心思想是为一个对象提供一个替身或者代理,以控制对...

    C#面向对象设计模式纵横谈(13):Proxy 代理模式(结构型模式)

    ### C#面向对象设计模式纵横谈(13):Proxy 代理模式(结构型模式) #### 重要概念:代理模式 代理模式是一种常用的结构型设计模式,它通过为另一个对象提供一个代理,来控制对该对象的访问。这种模式在软件工程中...

    Proxy 代理模式

    Proxy代理模式是设计模式中的一种,它在Java中扮演着重要的角色,特别是在处理远程调用、安全性、缓存以及日志记录等方面。代理模式的基本思想是为一个对象提供一个替身或者占位符,以便控制对这个对象的访问。在这...

    Proxy代理模式经典实例(绝对OOP)

    在Java中,Proxy模式主要依赖于Java的动态代理机制,这通常涉及到`java.lang.reflect.Proxy`和`java.lang.reflect.InvocationHandler`两个核心接口。`Proxy`类用于生成代理对象,而`InvocationHandler`接口定义了...

    基于Proxy模式的分布式MySQL数据库中间件设计源码

    MySQL数据库中间件:基于C语言开发,包含59个文件,包括22个C源文件...该项目是一个分布式MySQL数据库中间件,采用Proxy模式设计,基于核心业务对象切分,旨在提供高效的数据库查询和处理能力,适用于分布式系统环境。

    设计模式之代理模式Proxy

    代理模式是设计模式中的一种结构型模式,它在对象交互中起到了中介的作用,允许通过代理对象来控制对原对象的访问。代理模式的核心思想是为一个对象提供一个替身,以便增加新的功能或者控制对原对象的访问。这种模式...

    ABAP 调用ABAP PROXY

    - 使用批处理调用:对于大量数据传输,可以考虑使用批处理模式减少网络传输次数。 - 缓存管理:合理使用缓存策略,减少不必要的服务调用。 - 错误重试机制:针对可能的网络问题,设计适当的错误重试逻辑。 ### 安全...

    C#面向对象设计模式纵横谈(13):Proxy 代理模式(结构型模式) (Level 300)

    在IT领域,面向对象设计模式是软件开发中的重要概念,它们是解决常见设计问题的可重用解决方案。本文将深入探讨C#中的一个关键设计模式——代理模式,它属于结构型模式的一种,适用于管理和控制对象的访问。我们将从...

    c++-设计模式之代理模式(Proxy)

    代理模式(Proxy Pattern)是一种结构型设计模式,用于为其他对象提供一种代理以控制对这个对象的访问。代理模式通常用于保护、延迟加载、记录请求等场景,可以在不改变原有对象的情况下为其增加新的功能。 代理...

    proxy.rar java三种代理模式源码

    这个"proxy.rar"压缩包中包含了这三种代理模式的源代码示例,以及对泛型的应用。 1. 静态代理: 静态代理是最基础的代理形式,它通过创建一个代理类来实现目标接口,并在代理类中调用目标对象的方法。这种方式需要...

    代理模式 Proxy Pattern

    ### 代理模式 Proxy Pattern #### 概念定义 代理模式是一种结构型设计模式,它允许程序员为某对象创建一个代理对象来控制对该对象的访问。简单来说,就是在不修改原始类的基础上,通过引入代理对象来扩展类的行为...

    Proxy Pattern 代理模式

    Proxy Pattern 代理模式 采用JAVA实现,可以下载看看。

Global site tag (gtag.js) - Google Analytics