设计模式-代理模式-Proxy

代理(Proxy)顾名思义:为避免2者之间直接接触,委托方寻求第三方(代理方)帮忙处理一些委托方的需求。最经典的例子就是打官司:委托方就是被代理方,律师就是代理方,律师的职责就是避免原被告直接接触。

一、使用场景

如果2者之间需要通信,且2者之间必须解耦,需引入一个三方类来预处理通信、和通信结果处理。这个三方类就是代理类。
代理类能完全控制对委托对象的直接访问,也可以保护委托对象不被直接访问,同时也预留了通信处理空间,在设计上有更大的灵活性。

二、静态代理方式

1、被代理者
/**
 * 作者: Created by AdminFun
 * 邮箱: [email protected]
 * 创建: 2019/1/4
 * 修改: 2019/1/4
 * 版本: v1.0.0
 * 描述: 被代理者
 */
public class CS35Info implements ICar {

    @Override
    public double getPrice() {
        return 90000;
    }

    @Override
    public String getModel() {
        return "长安CS35";
    }
}
2、静态代理
/**
 * 作者: Created by AdminFun
 * 邮箱: [email protected]
 * 创建: 2019/1/4
 * 修改: 2019/1/4
 * 版本: v1.0.0
 * 描述: 静态代理
 * <p>
 * 静态代理的写法和装饰器有点类似,区别在于:
 * 1、代理的构造传入的是实例,而装饰器构造传入的是抽象
 * 2、代理想要控制实例的访问权限,而装饰意在控制对象的行为
 */
public class ProxyStatic implements ICar {

    private CS35Info cs35Info;

    public ProxyStatic(CS35Info cs35Info) {
        this.cs35Info = cs35Info;
    }

    @Override
    public double getPrice() {
        return cs35Info.getPrice();
    }

    @Override
    public String getModel() {
        return cs35Info.getModel();
    }
}
3、调用
/**
 * 作者: Created by AdminFun
 * 邮箱: [email protected]
 * 创建: 2019/1/4
 * 修改: 2019/1/4
 * 版本: v1.0.0
 */
public class ProxyTest {

    public static void main() {
        // 静态代理
        ProxyStatic proxyStatic = new ProxyStatic(new CS35Info());
        Log.d("common", "静态代理:" + proxyStatic.getModel());
    }
}

三、动态代理

被代理方还是上面的被代理类,这里不再重写。

1、动态代理
/**
 * 作者: Created by AdminFun
 * 邮箱: [email protected]
 * 创建: 2019/1/4
 * 修改: 2019/1/4
 * 版本: v1.0.0
 * 描述:动态代理
 * 动态代理和静态代理的区别
 * 1、静态代理需要代理方和委托方都实现相同的接口,接口方法变动后,双方都要随着变动,代码维护成本增加。
 * 2、动态代理是利用反射机制,可代理任何对象,且不需要维护成本。
 */
public class ProxyDynamic implements InvocationHandler {

    private Object target;//被代理的对象

    public ProxyDynamic(Object obj) {
        this.target = obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(target, args);
    }
}
2、调用
/**
 * 作者: Created by AdminFun
 * 邮箱: [email protected]
 * 创建: 2019/1/4
 * 修改: 2019/1/4
 * 版本: v1.0.0
 */
public class ProxyTest {

    public static void main() {
        // 动态代理
        final ICar car = new CS35Info();
        // 方式1
        ICar proxy = (ICar) Proxy.newProxyInstance(
                car.getClass().getClassLoader(),
                car.getClass().getInterfaces(),
                new ProxyDynamic(car)
        );
        // 方式2
        ICar proxy1 = (ICar) Proxy.newProxyInstance(
                car.getClass().getClassLoader(),
                car.getClass().getInterfaces(),
                new InvocationHandler() {

                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        return method.invoke(car, args);
                    }
                });

        Log.d("common", "动态代理:" + proxy1.getModel());
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_33720452/article/details/87394445