sheng的学习笔记-设计模式-代理模式

原理图:

sheng的学习笔记-设计模式-代理模式_第1张图片

 代理模式的定义:由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。


至少在以下集中情况下可以用 Proxy 模式解决问题:
        1)创建开销大的对象时候,比如显示一幅大的图片,我们将这个创建的过程交给代理
去完成, GoF 称之为虚代理( Virtual Proxy);
        2)为网络上的对象创建一个局部的本地代理, 比如要操作一个网络上的一个对象( 网
络性能不好的时候,问题尤其突出),我们将这个操纵的过程交给一个代理去完成, GoF 称
之为远程代理( Remote Proxy);
        3) 对对象进行控制访问的时候, 比如在 Jive 论坛中不同权限的用户(如管理员、 普通
用户等) 将获得不同层次的操作权限, 我们将这个工作交给一个代理去完成, GoF 称之为保
护代理( Protection Proxy)。

根据代理的创建时期,代理模式分为静态代理和动态代理。

  • 静态:由程序员创建代理类或特定工具自动生成源代码再对其编译,在程序运行前代理类的 .class 文件就已经存在了。
  • 动态:在程序运行时,运用反射机制动态创建而成

静态代理:

package design.proxy;

//抽象主题
interface Subject {
    void Request();
}
package design.proxy;

class ProxyTest {
    public static void main(String[] args) {
        Proxy proxy = new Proxy();
        proxy.Request();
    }
}


//真实主题
class RealSubject implements Subject {
    public void Request() {
        System.out.println("访问真实主题方法...");
    }
}

//代理
public class Proxy implements Subject {
    private RealSubject realSubject;

    public void Request() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        preRequest();
        realSubject.Request();
        postRequest();
    }

    public void preRequest() {
        System.out.println("访问真实主题之前的预处理。");
    }

    public void postRequest() {
        System.out.println("访问真实主题之后的后续处理。");
    }
}

结果:

访问真实主题之前的预处理。
访问真实主题方法...
访问真实主题之后的后续处理。

静态代理总结:

优点:可以做到在符合开闭原则的情况下对目标对象进行功能扩展。

缺点:我们得为每一个服务都得创建代理类,工作量太大,不易管理。同时接口一旦发生改变,代理类也得相应修改。可以用动态代理解决这些问题

动态代理:

类图如下:

sheng的学习笔记-设计模式-代理模式_第2张图片

 代码:

package design.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DynamicProxy implements InvocationHandler {
    private Object object;

    public DynamicProxy(final Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("动态代理 访问真实主题之前的预处理");
        Object result = method.invoke(object, args);
        System.out.println("动态代理 访问真实主题之后的后续处理");
        return result;
    }

    public static void main(String[] args) {
        Subject subject = new RealSubject1();  // 此处只需要用工厂模式,就可以根据业务参数动态提供不同的真实主题
        Subject realSubject = (Subject) Proxy.newProxyInstance(Subject.class.getClassLoader(), new
                Class[]{Subject.class}, new DynamicProxy(subject));
        realSubject.Request();

        subject = new RealSubject2();
        realSubject = (Subject) Proxy.newProxyInstance(Subject.class.getClassLoader(), new
                Class[]{Subject.class}, new DynamicProxy(subject));
        realSubject.Request();
    }
}

//真实主题
class RealSubject1 implements Subject {
    public void Request() {
        System.out.println("访问真实主题1方法...");
    }
}

//真实主题
class RealSubject2 implements Subject {
    public void Request() {
        System.out.println("访问真实主题2方法...");
    }
}

结果:

动态代理 访问真实主题之前的预处理
访问真实主题1方法...
动态代理 访问真实主题之后的后续处理
动态代理 访问真实主题之前的预处理
访问真实主题2方法...
动态代理 访问真实主题之后的后续处理

参考文章:

设计模式---代理模式 - Dan_Go - 博客园

代理模式(代理设计模式)详解

你可能感兴趣的:(设计模式,java,代理模式)