其他分享
首页 > 其他分享> > 代理模式

代理模式

作者:互联网

动态代理

需要了解两个类

Pros:

================================== 分隔线 ===================================

https://www.cnblogs.com/daniels/p/8242592.html

代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介。

举个例子来说明:假如说我现在想买一辆二手车,虽然我可以自己去找车源,做质量检测等一系列的车辆过户流程,但是这确实太浪费我得时间和精力了。我只是想买一辆车而已为什么我还要额外做这么多事呢?于是我就通过中介公司来买车,他们来给我找车源,帮我办理车辆过户流程,我只是负责选择自己喜欢的车,然后付钱就可以了。用图表示如下:

为什么要用代理模式?

分类

按照代理创建的时期来进行分类的话, 可以分为两种:静态代理、动态代理。

静态代理

原先房东亲自出租房子

// 租房
public interface Rent {
    void rent();
}
// 房东
public class Landlord implements Rent {
    public void rent() {
        System.out.println("房东出租房子");
    }
}
// 房东亲自出租房子
public static void main(String[] args) {
    Landlord landlord = new Landlord();
    landlord.rent();
}

让代理出租房子

// 代理
public class Proxy implements Rent {
    private final Landlord landlord;

    public Proxy(Landlord landlord) {
        this.landlord = landlord;
    }

    // 代理帮助房东租房,并且还可以在租房的基础上增强一些功能
    public void rent() {
        System.out.println("代理打广告推销房子");
        landlord.rent();
    }
}
// 让代理出租房子
public static void main(String[] args) {
    Landlord landlord = new Landlord();
    Proxy proxy = new Proxy(landlord);
    proxy.rent();
}

Pros:

Cons:

动态代理

例子1

public interface Rent {
    void rent();
}
public class Landlord implements Rent {
    public void rent() {
        System.out.println("房东出租房子");
    }
}
import java.lang.reflect.*;

public class ProxyLandlord implements InvocationHandler {

    // 被代理的接口
    private final Rent rent;

    // 设置要被代理的角色
    public ProxyLandlord(Rent rent) {
        this.rent = rent;
    }

    // 生成得到代理类
    public Object getProxy() {
        // 第一个参数:ClassLoader
        // 第二个参数:an array of interfaces implemented by this class.
        // 第三个参数:调用处理程序
//        loader:被代理的类的类加载器;
//        interfaces:被代理类的接口数组;
//        invocationHandler:调用处理器类的对象实例。
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                rent.getClass().getInterfaces(), this);
    }

//    proxy:被代理的类的实例;
//    method:调用被代理的类的方法;
//    args:该方法需要的参数。
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("帮房东打广告");
        Object result = method.invoke(rent, args);
        System.out.println("帮房东收费");
        return result;
    }

}

测试代码

public static void main(String[] args) {
    Landlord landlord = new Landlord();
    ProxyLandlord proxyLandlord = new ProxyLandlord(landlord);
    Rent r = (Rent) proxyLandlord.getProxy();
    r.rent();
}

结果

帮房东打广告
房东出租房子
帮房东收费

例子2

public interface Rent {
    void rent();
}
public class Landlord implements Rent {
    public void rent() {
        System.out.println("房东出租房子");
    }
}
public class DynamicProxy implements InvocationHandler {

    private Object object;

    public void setObject(Object object) {
        this.object = object;
    }

    public Object getProxy() {
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                object.getClass().getInterfaces(),this);
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(object, args);
        this.log(method.getName());    // 使用反射获取方法的名字
        return result;
    }

    // 例如代理要添加功能
    public void log(String function) {
        System.out.println("房子被" + function + "了");
    }

}
public static void main(String[] args) {
    Landlord landlord = new Landlord();
    DynamicProxy dynamicProxy = new DynamicProxy();
    // 设置代理对象
    dynamicProxy.setObject(landlord);
    // 获取代理实例
    Rent proxy = (Rent) dynamicProxy.getProxy();
    // 调用实例方法
    proxy.rent();
}

测试结果

房东出租房子
房子被rent了

标签:Landlord,void,代理,模式,rent,landlord,public
来源: https://www.cnblogs.com/jumpig/p/14829878.html