代理设计模式

前言:

    网上有那么多写设计模式的博客为什么还要写设计模式呢?因为我不会,而且如果只是看看别人写的往往自己理解的很浅,需通过自己写一写加深影响。

一、什么是代理模式

    为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

二、代理模式的组成

 抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
 代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
 真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用

三、模式结构

1、静态代理

抽象角色:

public interface ProxyInf {
    int addUser(int num);
}

代理角色:

public class ProxyPerson implements ProxyInf {
    private final Administrator admin;
    public ProxyPerson (Administrator admin){
        this.admin = admin;
    }
    @Override
    public int addUser(int num) {
        return admin.addUser(num);
    }
}

真实角色:

public class Administrator implements ProxyInf{
    private int totalNum = 100 ;
    @Override
    public int addUser(int num) {
        return totalNum +num ;
    }
    public void deleteUser(int num){
        totalNum  -= num ;
    }
}

可以做到在不修改目标对象的功能前提下,对目标功能扩展.
缺点:因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多.同时,一旦接口增加方法,目标对象与代理对象都要维护

2、动态代理
动态代理有别于静态代理,是根据代理的对象,动态创建代理类。可以避免静态代理中代理类接口过多的问题。动态代理是通过反射来实现的,借助Java自带的java.lang.reflect.Proxy,通过固定的规则生成。
动态代理的代码和静态差不多,区别在于代理角色。
代理角色:

public class ProxyPerson implements InvocationHandler {
    private final Object object;
    public ProxyPerson(Object object){
        this.object= object;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(proxy, args);
        return result;
    }
}

调用:

ProxyInf  proxyInf= new Administrator();
ProxyPerson proxyPerson = new ProxyPerson(proxyInf);
ClassLoader classLoader = proxyInf.getClass().getClassLoader();
ProxyInf proxyInstance =
                (ProxyInf)Proxy.newProxyInstance(classLoader, new Class[]{ProxyInf.class}, proxyPerson);
proxyInstance.addUser();

Proxy类的静态方法newProxyInstance()方法生成了一个对象,这个对象实现了数组中指定的接口。没错,返回值proxyInstance 是ProxyInf接口的实现类。你不要问这个类是哪个类,你只需要知道proxyInstance 是ProxyInf接口的实现类就可以了。

动态代理就是在运行时生成一个类,这个类会实现你指定的一组接口,而这个类没有.java文件,是在运行时生成的,你也不用去关心它是什么类型的,你只需要知道它实现了哪些接口即可。

Proxy类的newInstance()方法有三个参数:
  

  • ClassLoader loader:它是类加载器类型,你不用去理睬它,你只需要知道怎么可以获得它就可以了:MyInterface.class.getClassLoader()就可以获取到ClassLoader对象,没错,只要你有一个Class对象就可以获取到ClassLoader对象; 

  • Class[] interfaces:指定newProxyInstance()方法返回的对象要实现哪些接口,没错,可以指定多个接口,例如上面例子只我们只指定了一个接口:Class[] cs = {ProxyInf.class};  

  • InvocationHandler h:它是最重要的一个参数!它是一个接口!它的名字叫调用处理器!它只有一个方法,即invoke()方法!它是对代理对象所有方法的唯一实现。也就是说,无论你调用代理对象上的哪个方法,其实都是在调用InvocationHandler的invoke()方法。
      
    methd.invoke(proxy, args)方法,第一个参数需要把原来的具体实现类作为参数传递进去。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值