动态代理设计模式(一)

317 阅读2分钟

这是我参与2022首次更文挑战的第14天,活动详情查看:2022首次更文挑战

\

一. 什么是代理模式

1.1 概念

代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用

也就是说客户端并不直接调用实际的对象,而是通过调用代理,来间接的调用实际的对象。

通俗的来讲代理模式就是我们生活中常见的中介。

1.2 为什么不直接调用, 而要间接的调用对象呢?

一般是因为客户端不想直接访问实际的对象, 或者不方便直接访问实际对象,因此通过一个代理对象来完成间接的访问。

代理模式的UML图

代理类和真正实现都实现了同一个接口, 并且他们有相同的方法. 这样对于客户端调用来说是透明的.

二. 什么情况下使用动态代理

想在访问一个类时做一些控制, 在真实调用目标方法之前或者之后添加一些操作. 我们想买房, 但是买房的手续实在太复杂, 索性都交给中介公司. 中介公司就是代理, 我们的直接目的是买到房子, 中介公司在买房前后增加一些处理操作.

来看看代码实现

/**
 * 买房接口
 */
public interface IBuyHouse {
    public void buyHouse();
}

/**
 * 真正买房的人
 */
public class RealBuyHouse implements IBuyHouse{

    private String name;

    public RealBuyHouse(String name) {
        this.name = name;
    }

    @Override
    public void buyHouse() {
        System.out.println(this.name + "买房子");
    }
}

/**
 * 代理买房
 */
public class ProxyBuyHouse implements IBuyHouse{

    private IBuyHouse buyHouse;

    public ProxyBuyHouse(IBuyHouse buyHouse) {
        this.buyHouse = buyHouse;
    }

    @Override
    public void buyHouse() {
        beforeBuyHouse();

        buyHouse.buyHouse();

        afterBuyHouse();
    }

    public void beforeBuyHouse() {
        System.out.println("买房前操作--选房");
    }

    public void afterBuyHouse() {
        System.out.println("买房后操作--交税");
    }

}

public class Client {
    public static void main(String[] args) {
        IBuyHouse buyHouse = new RealBuyHouse("张三");

        IBuyHouse proxyBuyHouse = new ProxyBuyHouse(buyHouse);
        proxyBuyHouse.buyHouse();
    }
}

我们看到, 代理做的事情, 是代替主体完成买房操作, 所以, 类内部有一个主体实体对象.

代理模式有三种角色

Real Subject:真实类,也就是被代理类、委托类。用来真正完成业务服务功能;

Proxy:代理类。将自身的请求用 Real Subject 对应的功能来实现,代理类对象并不真正的去实现其业务功能;

Subject:定义 RealSubject 和 Proxy 角色都应该实现的接口

通俗来说,代理模式的主要作用是扩展目标对象的功能,比如说在目标对象的某个方法执行前后你可以增加一些额外的操作,并且不用修改这个方法的原有代码。如果大家学过 Spring 的 AOP,一定能够很好的理解这句话。