`
lettoo
  • 浏览: 35079 次
  • 性别: Icon_minigender_1
  • 来自: 合肥
博客专栏
58ccff5b-5ca6-387a-9c99-a277f31a9e51
我和Java数据库操作的那...
浏览量:9463
社区版块
存档分类
最新评论

复习:代理模式

阅读更多

    代理模式是常用的Java 设计模式,它的特征是代理类与委托类有同样的接口,如图1所示。代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。


图1:Proxy模式

 

按照代理类的创建时期,代理类可分为两种。

  • 静态代理类:由程序员创建或由特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
  • 动态代理类:在程序运行时,运用反射机制动态创建而成。

 

静态代理类的实现:

 

1. 定义一个IService接口

package cn.lettoo.proxy;

public interface IService {

    void execute();
}

 

2. 具体的实现类:

package cn.lettoo.proxy;

public class PrintService implements IService {

    public void execute() {
        System.out.println("The Print Service works.");
    }
}

 

3. 代理类:

package cn.lettoo.proxy;

public class PrintServiceProxy implements IService {

    IService printSerivce;

    public PrintServiceProxy(IService service) {
        this.printSerivce = service;
    }

    public void setPrintSerivce(IService printSerivce) {
        this.printSerivce = printSerivce;
    }

    public void execute() {
        this.beforePrint();
        this.printSerivce.execute();
        this.afterPrint();
    }

    private void beforePrint() {
        System.out.println("Before print.");
    }

    private void afterPrint() {
        System.out.println("Before print.");
    }

}

    代理类的execute()方法只是调用了被代理的Service的execute方法,被代理的Service通过构造函数或者set的方式被注入到代理对象中。同时,代理对象也有一些自己的代理方法,如本例中在被代理类的execute()方法调用前后加上自己的方法。

 

4. 客户调用代码:

package cn.lettoo.proxy;

public class Client {

    public static void main(String[] args) {
        IService service = new PrintService();
        IService proxy = new PrintServiceProxy(service);

        proxy.execute();
    }
}

 

执行结果
Before print.
The Print Service works.
Before print.

 

 动态代理的实现:

 

与静态代理类对照的是动态代理类,动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。

 

Proxy类提供了创建动态代理类及其实例的静态方法。

Porxy有两种方式来生成代理对象:

方法1:

//创建InvocationHandler对象
InvocationHandler handler = newMyInvocationHandler(...);
//创建动态代理类,IService是被代理的接口
Class proxyClass = Proxy.getProxyClass(IService.class.getClassLoader(), new Class[] { IService.class });
//创建动态代理类的实例
IService proxyService = (IService) proxyClass.getConstructor(new Class[] { invocationHandler.class }).newInstance(new Object[] { handler });

方法2:

//创建InvocationHandler对象
InvocationHandler handler = newMyInvocationHandler(...);
//直接创建动态代理类的实例
IService serviceProxy = (IService) Proxy.newProxyInstance(IService.class.getClassLoader(), new Class[] { IService.class },
handler);

 

InvocationHandler 接口为方法调用接口,它声明了负责调用任意一个方法的invoke()方法:

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

 

代码实现:

1. 写一个ServiceFactory,用于生成代理对象

package cn.lettoo.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ServiceFactory {

    public static IService getServiceProxy(final IService service) {
        InvocationHandler handler = new InvocationHandler() {

            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                beforePrint();
                Object result = method.invoke(service, args);
                afterPrint();
                return result;
            }
        };

        return (IService) Proxy.newProxyInstance(IService.class.getClassLoader(), new Class[] { IService.class },
                                                 handler);
    }
    
    private static void beforePrint() {
        System.out.println("Before print.");
    }

    private static void afterPrint() {
        System.out.println("Before print.");
    }
    
}

 

2. 客户端代码:

package cn.lettoo.proxy;

public class Client {

    public static void main(String[] args) {
        IService service = new PrintService();        
        IService proxy = ServiceFactory.getServiceProxy(service);        
        proxy.execute();
    }

}

 

运行结果
Before print.
The Print Service works.
Before print.
 

 

    也许有人要问,采用动态代理有什么好处?那么我告诉你,你不需要为每个IService的实现类都去写一个Proxy类了(前提是代理方法是一样的),假如,我现在有另外一个IService的实现类如下:

package cn.lettoo.proxy;

public class AnotherService implements IService {

    public void execute() {
        System.out.println("I am another service.");
    }

}

 

    现在客户端只要这样写:

    public static void main(String[] args) {
        IService service = new AnotherService();        
        IService proxy = ServiceFactory.getServiceProxy(service);        
        proxy.execute();
    }

 

运行结果
Before print.
I am another service.
Before print.
 

    可以看到,不需要单独再为AnotherService写一个代理类了,动态代理类会帮助我们去实现的。

  • 大小: 2.9 KB
分享到:
评论

相关推荐

    设计模式总复习2

    10. 代理模式:代理模式为其他对象提供一种代理以控制对这个对象的访问。它可以用于远程代理、虚拟代理、缓存代理等。 11. 观察者模式:观察者模式定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,...

    复习提纲之设计模式总结1

    - **代理**(Proxy):代理模式为其他对象提供一种代理以控制对这个对象的访问,通常用于远程代理、虚拟代理、权限控制等。 - **享元**(Flyweight):享元模式减少内存中对象的数量,通过共享大量细粒度对象来...

    软件设计模式--填空题+简答题(复习7).rar

    2. **设计模式分类**:设计模式通常分为三类:创建型模式(如工厂方法、抽象工厂、单例、建造者、原型)、结构型模式(如适配器、桥接、装饰、组合、代理、外观、享元)和行为型模式(如责任链、命令、解释器、迭代...

    软件设计模式与体系结构(期末复习2)简答题背诵.rar

    常见的设计模式有三大类:创建型模式(如单例模式、工厂模式、抽象工厂模式)、结构型模式(如适配器模式、装饰器模式、代理模式)和行为型模式(如观察者模式、策略模式、职责链模式)。理解并熟练运用这些模式,...

    设计模式复习题.doc

    - 代理模式 - 适配器模式 2. 设计模式的基本要素: - 名字 - 意图 - 问题 - 解决方案 - 参与者与协作者 - 实现 - 一般性构造 3. 设计模式的应用场景: - 使用命令模式来参数化客户请求 - 使用策略模式...

    软件设计模式总复习.pdf

    结构型模式包括:适配器、桥接、组合、装饰、外观、享元、代理模式等,它们主要用于描述如何组合对象以获得更大的结构。 行为型模式包括:职责链、命令、解释器、迭代器、中介者、备忘录、观察者、状态、策略、模板...

    设计模式解析复习提纲

    - **结构型模式**:包括适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式和代理模式。 - **行为型模式**:包括职责链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式...

    软件体系结构与设计模式期末复习.docx

    例如组合模式、适配器模式、装饰者模式、桥接模式和代理模式等。 3. **行为型模式**:关注于对象之间的责任分配。如迭代器模式、访问者模式、状态模式、观察者模式等。 #### 四、示例代码解析 以简单的工厂模式为...

    java设计模式选择题复习

    - **代理模式** - **迭代器模式** - **观察者模式** - **协调者模式** - **模板方法模式** - **策略模式** - **责任链模式** - **命令模式** - **空对象模式** - **解释器模式** #### 面向对象的设计原则 - **开闭...

    设计模式复习题.docx

    9. 代理模式:结构型模式,为其他对象提供一种代理以控制对这个对象的访问,可以用于增加安全性、控制访问等。 10. 适配器模式:结构型模式,将不兼容的接口转换为用户期望的接口,使原本不兼容的类可以协同工作。 ...

    软件设计模式与体系结构(期末复习1).rar

    常见的设计模式分为三大类:创建型模式(如单例模式、工厂方法模式、抽象工厂模式等)、结构型模式(如适配器模式、装饰器模式、代理模式等)和行为型模式(如观察者模式、策略模式、责任链模式等)。这些模式为我们...

    C#设计模式作业1、3.rar

    代理模式为其他对象提供一种代理以控制对这个对象的访问。在C#中,动态代理(如System.Reflection.Emit命名空间中的动态类型生成)和接口代理(通过实现相同接口的方式)是常见的实现方式,常用于权限控制、性能...

    设计模式课件大全

    设计模式10-代理模式、结构型模式大复习 设计模式11-行为模式-责任链、命令模式 设计模式12-解释器模式 设计模式13-迭代器模式 设计模式14-中介者模式、备忘录模式 设计模式15-观察者模式、状态模式 设计模式16-策略...

    软件设计模式复习题.doc

    这类模式包括适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式和代理模式。 ### 2. 设计模式的分类 设计模式通常分为三类: - **创建型模式**:这些模式用于创建对象的过程,目的是隐藏对象的创建...

    复习反射利用反射机制和AOP代理模式

    reflection是一系列的API,用于表示或者处理当前JVM中的类,接口和对象. java.lang.reflect/java.lang.Class 在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

    设计模式PPT

    结构型模式:这些模式关注如何组合对象和类,以创建更大的结构,例如适配器模式(Adapter)、桥接模式(Bridge)、组合模式(Composite)、装饰器模式(Decorator)、外观模式(Facade)、享元模式(Flyweight)和...

    java设计模式选择题复习题.doc

    这份复习题主要涉及了设计模式的不同方面,包括优缺点、分类、实际应用以及与其他模式的区别。 首先,工厂模式是一种创建型设计模式,它提供了创建对象的抽象接口,使得客户端代码无需知道具体创建的对象是哪个类的...

    《JAVA设计模式》期末考试复习.docx

    7. 结构型模式(Structural Patterns):关注类和对象的组合,如外观模式(Facade Pattern)、桥接模式(Bridge Pattern)、组合模式(Composite Pattern)、代理模式(Proxy Pattern)等。这些模式提供了创建新结构...

    《JAVA设计模式》期末考试复习资料复习进程.pdf

    13. 装饰模式是在不修改原有对象的基础上,动态地为其添加新功能,它与代理模式不同,代理模式更多是控制对对象的访问。 14. 不应该强迫客户依赖它们不用的方法,这是接口隔离原则的体现,强调接口应精简,避免提供...

Global site tag (gtag.js) - Google Analytics