设计模式--代理模式(proxy pattern)

模式介绍

  • 代理模式又称为委托模式,在日常生活中也很常见,比如你让同事给你带饭,找黄牛买车票等等

定义与类型

  • 定义:为其他对象提供一种代理以控制对这个对象的访问
  • 类型:结构型

** 优点**

  • 代理对象与目标对象隔离
  • 一定程度上降低了系统耦合度,扩展性好
  • 保护目标对象、增强目标对象

适用场景

  • 当无法或不想直接访问某个对象或访问某个对象困难时,可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口

UML类图

设计模式--代理模式(proxy pattern)_第1张图片
Proxy-Pattern.png

模式代码

  • 真实主题类
class RealSubject extends Subject{

    @Override
    void visit() {
        System.out.println("RealSubject");
    }
}
  • 代理类
class ProxySubject extends Subject{
    private RealSubject realSubject;
    public ProxySubject(RealSubject realSubject){
        this.realSubject = realSubject;
    }
    @Override
    void visit() {
        //通过真实主题引用对象调用真实主题中的方法
        realSubject.visit();
    }
}
  • 客户端调用
 public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();
        ProxySubject proxySubject = new ProxySubject(realSubject);
        proxySubject.visit();
    }

扩展

  • 静态代理
  • 动态代理(这里将的是JDK的动态代理,Spring提供的CGlib这里不讨论有兴趣可以去了解一下)

静态代理的代理类的对象在code阶段被创建出来(如上述代码所示),而动态代理通过反射机制动态生成代理类的对象。java给我们提供了一个便捷的动态代理接口InvocationHandler,实现该接口需要重写其调用方法invoke:

public class DynamicProxy implements InvocationHandler{
 //被代理的类引用
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return null;
    }
}

动态代理类

public class DyamicProxy implements InvocationHandler{
    //被代理的类引用
    private Object obj;

    public DyamicProxy(Object obj){
        this. obj = obj;
    }

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

        //调用被代理类对象的方法
        Object reuslt = method.invoke(obj,args);
        return reuslt;
    }
}

修改客户端代码:

 public static void main(String[] args) {
        //真实主题类
        RealSubject realSubject = new RealSubject();
        //构造一个动态代理
        DyamicProxy proxy = new DyamicProxy(realSubject);
        //获取一个真实主题类的ClassLoader
        ClassLoader loader = realSubject.getClass().get ClassLoader();
        //动态构造一个代理类
        ProxySubject proxySubject = Proxy.newProxyInstance(loader, new Class[]{ProxySubject.Class},proxy);
        proxySubject.visit();
    }

你可能感兴趣的:(设计模式--代理模式(proxy pattern))