设计模式之代理模式

本文深入探讨了代理模式的概念,包括静态代理和动态代理的原理及应用。通过实例代码展示了如何使用代理模式来增强功能,实现中介隔离,以及遵循开闭原则。适用于希望了解或应用代理模式的软件开发者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、代理模式简述

代理模式为另一个对象提供一个替身或者占位符以控制对这个对象的访问。在代理模式中,我们创建具有现有对象的对象,以便实现系统控制功能。在外界访问的时候,我们可以添加自己的需求。比如说Spring框架里的AOP、JDK里的Dynamic Proxy、Cglib等。代理模式在各种开发框架和中间件中被广泛使用,比如RPC,数据库访问等。

为什么要用代理模式?
中介隔离作用:在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。
开闭原则,增加功能:代理类除了是客户类和委托类的中介之外,我们还可以通过给代理类增加额外的功能来扩展委托类的功能,这样做我们只需要修改代理类而不需要再修改委托类,符合代码设计的开闭原则。代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后对返回结果的处理等。代理类本身并不真正实现服务,而是同过调用委托类的相关方法,来提供特定的服务。真正的业务功能还是由委托类来实现,但是可以在业务功能执行的前后加入一些公共的服务。例如我们想给项目加入缓存、日志这些功能,我们就可以使用代理类来完成,而没必要打开已经封装好的委托类。

代理模式可分为静态代理和动态代理。

2、静态代理

类图如下:

代码:

/**
 * 接口
 */
public interface DataDao {
    
    void insert();
    void update();
    void delete();
}

/**
 * 实现类
 */
public class DataDaoImpl implements DataDao {

    @Override
    public void insert() {
        System.out.println("insert");
    }

    @Override
    public void update() {
        System.out.println("update");
    }

    @Override
    public void delete() {
        System.out.println("delete");
    }
}

/**
 * 代理类
 */
public class DataDaoProxy implements DataDao{
    private DataDao dataDao;

    public DataDaoProxy(DataDao dataDao) {
        this.dataDao = dataDao;
    }

    @Override
    public void insert() {
        dataDao.insert();
        System.out.println("log");
    }

    @Override
    public void update() {
        dataDao.update();
        System.out.println("log");
    }

    @Override
    public void delete() {
        dataDao.delete();
        System.out.println("log");
    }
}

3、动态代理

动态代理常见的有JDK动态代理和cglib动态代理。

JDK的动态代理是通过反射来实现的。

/**
 * JDK代理
 */
public class JDKProxy {

    public static void main(String[] args) {

        final DataDao dataDao = new DataDaoImpl();

        DataDao dataDaoProxy = (DataDao) Proxy.newProxyInstance(dataDao.getClass().getClassLoader(),
                dataDao.getClass().getInterfaces(), new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("before method call ");
                        Object object = method.invoke(dataDao, args);
                        System.out.println("after method call ");
                        return object;
                    }
                });
        dataDaoProxy.update();
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值