代理模式

静态代理模式
静态代理要求一个接口定义一个对应的代理类,例如演员接口有对应的演员代理类,影星接口有对应的影星代理类,这里可能会造成类爆炸问题

package staticproxy;

/**
 * 演员类
 * @author 17976
 *
 */
public interface Actor {
    public void aciting();
}
package staticproxy;
/**
 * 演员的具体实现类:迪丽热巴
 * @author 17976
 *
 */
public class Dlirb implements Actor{

    @Override
    public void aciting() {
        System.out.println("热巴出演三生三世枕上书");
    }

}
package staticproxy;
/**
 * 演员的代理类:
 * 嘉行公司
 * @author 17976
 *
 */
public class JiaHang implements Actor{

    private Actor target;//代理的目标对象

    public JiaHang(Actor target) {
        super();
        this.target = target;
    }

    public JiaHang() {
        super();
    }

    @Override
    public void aciting() {
        System.out.println("签订演艺合同。。。。。");//在具体的代理对象被执行前进行的一些预处理工作。
        this.target.aciting();//由具体的代理的目标对象去实现
        System.out.println("嘉行收取演出费用");
    }

}
package staticproxy;
/**
 * 嘉行帮热巴签了三生三世枕上书
 * @author 17976
 *
 */
public class StaticproxyTest {
    public static void main(String[] args) {
        Actor dilirb=new Dlirb();
        Actor proxy=new JiaHang(dilirb);
        proxy.aciting();//嘉行帮热巴签了三生三世枕上书这部剧
    }
}
/**
 * 运行结果:
        签订演艺合同。。。。。
        热巴出演三生三世枕上书
        嘉行收取演出费用
 */

动态代理:
动态代理可以有效的避免一个接口对应一个代理类问题,通过回调处理类动态的获取到需要进行代理的目标对象。需要实现具体的业务逻辑时调用

 newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException`

也可以动态地选择代理对象,回调处理类,接口,以实现不同的业务逻辑,增加了灵活性。
JDK的动态代理需要有对应的接口;CGLib可以没有对应的接口
JDK的动态代理是依靠反射机制实现的。JDK反射包中定义了一个InvocationHandler的接口用于实现代理对象执行任何方法时的方法回调
·public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
proxy要代理的目标对象
method要调用方法的某个Method对象
args调用方法是要传入方法的参数

package dynamicproxy;

/**
 * 演员类
 * @author 17976
 *
 */
public interface Actor {
    public void acting();
}
package dynamicproxy;
/**
 * 演员的具体实现类:迪丽热巴
 * @author 17976
 *
 */
public class Dlirb implements Actor{

    @Override
    public void acting() {
        System.out.println("热巴出演三生三世枕上书");
    }

}
package dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
 * 嘉行的回调处理类
 * @author 17976
 *
 */
public class JiaHangHander implements InvocationHandler {
    private Actor target;//具体的代理目标:迪丽热巴

    public JiaHangHander(Actor target) {
        super();
        this.target = target;
    }

    /**
     * proxy:要传入的代理目标对象
     * method:调用方法的method对象
     * args:调用方法时传入的参数
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object res=null;
        String methodName=method.getName();
        if("acting".equals(methodName)) {
            System.out.println("签订演艺合同。。。。。");
            //调用目标对象的方法
            res=method.invoke(target, args);
            //对应的后置处理
            System.out.println("嘉行收取演艺费用。");
        }
        return res;
    }

}
package dynamicproxy;

import java.lang.reflect.Proxy;

public class DynamicproxyTest {
    public static void main(String[] args) {
        Actor dilirb=new Dlirb();
        Actor proxy=(Actor)Proxy.newProxyInstance(Actor.class.getClassLoader(), 
                new Class[] {Actor.class}, new JiaHangHander(dilirb));
        proxy.acting();

    }
}
/**
 * 运行结果:
 *  签订演艺合同。。。。。
    热巴出演三生三世枕上书
    嘉行收取演艺费用。
 * 
 */

和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。
和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以访问控制
关于适配器模式:设计模式:适配器模式|菜鸟教程 - CSDN博客 https://blog.csdn.net/lory17/article/details/62224270
总结
代理模式在很多情况下都非常有用,特别是你想强行控制一个对象的时候,比如:延迟加载,监视状态变更的方法等等
1、“增加一层间接层”是软件系统中对许多复杂问题的一种常见解决方法。在面向对象系统中,直接使用某些对象会带来很多问题,作为间接层的proxy对象便是解决这一问题的常用手段。
2、具体proxy设计模式的实现方法、实现粒度都相差很大,有些可能对单个对象作细粒度的控制,有些可能对组件模块提供抽象代理层,在架构层次对对象作proxy。
3、proxy并不一定要求保持接口的一致性,只要能够实现间接控制,有时候损及一些透明性是可以接受的。例如上面的那个例子,代理类型ProxyClass和被代理类型LongDistanceClass可以不用继承自同一个接口,正像GoF《设计模式》中说的:为其他对象提供一种代理以控制这个对象的访问。代理类型从某种角度上讲也可以起到控制被代理类型的访问的作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值