频道栏目
首页 > 程序开发 > 软件开发 > Java > 正文
JAVA设计模式之代理模式的代码实例讲解
2017-11-18 09:50:33         来源:Emma_Joans的博客  
收藏   我要投稿

代理模式

代理模式是对象的结构模式,给一个对象提供一个代理对象,由代理对象控制对原对象的引用。


代理的种类

- 远程(Remote)代理:

为一个位于不同的地址空间的对象提供一个局域代表对象。这个不同的空间地址可以是在本机器中,也可以是在另一台机器中。

- 虚拟代理:

根据需要创建一个资源消耗较大的对象,使得此对象在真正需要时才会被创建。

- Copy-on-Write 代理:

虚拟代理的一种,把复制拖延到只有在客户端需要时,才真正采取行动。

- 保护代理:

控制对一个对象的访问,如果需要,可以给不同的用户踢动不同级别的使用权限。

- Cache代理:

为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。

- 防火墙代理:

保护目标,不让恶意用户接近。

- 同步化代理:

使几个用户能否同时使用一个对象而没有给冲突。

- 智能引用代理:

当一个对象被引用时,提供一些额外的操作,比如讲对象的调用次数记录下来。


代理模式的结构

代理模式所涉及的角色有:

1. 抽象主题角色

声明了真实主题和代理主题之间的共同接口,这样一来在任何可以只用真实主题的地方都可以只用代理主题。

/**
 * 抽象主题
 * @author wuqiong
 *
 */
public abstract class Subject {
    public abstract void request();
}

2. 代理主题角色

代理主题角色内部包含了对真实主题的引用,从而可以在任何时候操作真实主题对象。代理角色通常在客户端真正调用的真实主题之前或者之后,执行某个操作,而不是单独的将调用传递给真实的角色。

/**
 * 代理主题角色
 * @author wuqiong
 *
 */
public class ProxySubject extends Subject {

    private RealSubject realSubject = new RealSubject();

    @Override
    public void request() {
        preRequest();
        realSubject.request();
        afterRequest();
    }

    public void preRequest() {
        System.out.println("request方法执行之前执行");
    }

    public void afterRequest() {
        System.out.println("request方法执行之后执行");
    }

}

3. 真实主题角色

定义了代理角色所代表的真实对象。

/**
 * 真实主题
 * @author wuqiong
 *
 */
public class RealSubject extends Subject {

    @Override
    public void request() {
        System.out.println("真实主题request方法执行");
    }
}

测试执行结果:

public class ProxyTest {

    public static void main(String[] args) {
        ProxySubject ps = new ProxySubject();
        ps.request();
    }
}

打印结果

request方法执行之前执行
真实主题request方法执行
request方法执行之后执行

从上面的代理主题类的代码可以看出代理模式是怎么样工作的,首先,代理模式并不改变主题的接口,因为模式的用意并不是让客户端感受到代理的存在。其次,代理使用委派将客户端的调用委派给真实的主题对象,代理主题在其中起到了传递请求的左右。最后,代理主题在传递请求之前和之后都可以执行特定的代码,而不是单纯的执行请求。


代理模式的时序

当客户端向代理主题发出请求时,代理主题接受到请求的同事,先执行一个preRequest()操作,然后才把请求传递给真实的主题。真实主题执行之后,又执行了afterRequest()方法,才将控制返回给客户端。

简而言之,就是代理模式将一个中间层插入到了客户端和主题角色之间,从而提供了许多灵活性。


Java2.0对代理模式的支持

JDK1.3以来,java语言通过java.lang.reflect在库中提供下面三个类直接支持代理模式:

Proxy InvocationHandler

Method

代码示例:

public class ProxyTest {

    public static void main(String[] args) {
        // 真实主题,list接口
        List arrayList = new ArrayList();

        // 代理对象
        /*
         * java.lang.reflect.Proxy:提供了和动态代理有关的方法
         * static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) 
         * 返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。 
         *  参数:
         *      ClassLoader loader:传递类加载器,加载类到内存中,创建class文件对象;可以传递本类的类加载器
         *      Class[] interfaces:传递ArrayList实现的接口List/Collection的Class文件对象
         *      InvocationHandler h:创建一个InvocationHandler的实现类,重写接口中的方法invoke,对集合的方法进行判断
         *       如果调用add方法,没有对集合进行修改,则允许执行
         *   返回值类型:
         *      Object:返回被代理后的List集合
        */
        List newProxyList = (List) Proxy.newProxyInstance(arrayList.getClass().getClassLoader(), arrayList.getClass().getInterfaces(),new InvocationHandler() {

            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                System.out.println("before代码执行了....");
                String name = method.getName();

                if(name.equals("add")) {
                    method.invoke(proxy, args);
                }

                System.out.println("after代码执行了....");

                return null;

            }
        });

        newProxyList.add("1");
    }
}
点击复制链接 与好友分享!回本站首页
上一篇:Java中final 关键字
下一篇:JAVA随机数讲解、计算机原理、switch选择结构
相关文章
图文推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站