设计模式之代理模式(三种)

代理模式

  • 六大设计原则
  • 代理模式是什么
  • 应用场景
  • 静态代理
  • 动态代理(在运行时,创建目标类,可以调用和扩展目标类的方法)
    • JDK动态代理
    • Cglib动态代理

六大设计原则

  1. 单一职责(一个类干一件事)
  2. 接口原则(接口方法都能用到)
  3. 依赖倒转(接口编程) --用到
  4. 里氏替换(继承性的重写改变了,复用性差)
  5. 开闭原则(扩展开放、修改关闭) --用到
  6. 迪米特法则(一个类对其他类保持最少的了解) --用到

代理模式是什么

代理模式:为其它对象提供一种代理以控制对这个对象的访问控制;在某些情况下,客户不想或者不能直接引用另一个对象,这时候代理对象可以在客户端和目标对象之间起到中介的作用

应用场景

统计每个 api 的请求耗时
统一的日志输出
校验被调用的 api 是否已经登录和权限鉴定
Spring的 AOP 功能模块就是采用动态代理的机制来实现切面编程

静态代理

优点:解耦(客户端不知道具体的实现是什么,只需注重业务代码是实现)
缺点:静态代理方式需要为每个接口实现一个代理类,而这些代理类中的代码
几乎是一致的。这在大型系统中将会产生很大的维护问题。

抽象主题类

public interface Subject {
    /**
     * 接口方法
     */
    public void SMethod();
}

具体实现类

public class SmallSubject implements Subject {

    @Override
    public void SMethod() {
        //业务处理逻辑
    }
}

代理类(每个代理对象都需一个代理类实现代理)

public class Proxy implements Subject {

    /**
     * 要代理的实现类
     */
    private Subject subject = null;

    /**
     * 默认代理自己
     */
    public Proxy() {
        this.subject = new Proxy();
    }

    public Proxy(Subject subject) {
        this.subject = subject;
    }

    /**
     * 构造函数,传递委托者
     *
     * @param objects 委托者
     */
    public Proxy(Object... objects) {
    }

    /**
     * 实现接口方法 可以增强方法
     */
    @Override
    public void SMethod() {
        this.before();
        this.subject.SMethod();
        this.after();
    }

    /**
     * 预处理
     */
    private void before() {
        //do something
    }

    /**
     * 后处理
     */
    private void after() {
        //do something
    }
}

客户端类

public class Client {
    public static void main(String[] args) {
        Subject subject = new SmallSubject();
        Proxy proxy = new Proxy(subject);
        proxy.SMethod();
    }
}

动态代理(在运行时,创建目标类,可以调用和扩展目标类的方法)

JDK动态代理

所谓的jdk代理指的是借助jdk所提供的相关类来实现代理模式,其主要有两个类:InvocationHandler和Proxy。在实现代理模式时,只需要实现InvocationHandler接口即可,
要实现动态代理的首要条件:被代理类必须实现一个接口,才能被代理
优点:动态代理的应用使我们的类职责更加单一,复用性更强。代理逻辑与业务逻辑是互相独立的,没有耦合

JDK代理对象

public class JdkProxy implements InvocationHandler {
    /**
     * 目标对象
     */
    private Object target;

    /**
     * 绑定关系,也就是关联到哪个接口(与具体的实现类绑定)的哪些方法将被调用时,执行invoke方法。
     *
     * @param target 绑定具体的代理实例
     */

    public JdkProxy(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(target, args);
        return result;
    }
}

客户端

public class ProxyClient {

    public static void main(String[] args) {
        UserInterface user = new OverUser();
        JdkProxy jdkProxy = new JdkProxy(user);
        OverUser proxyUser = (OverUser) Proxy.newProxyInstance(user.getClass().getClassLoader(), user.getClass().getInterfaces(), jdkProxy); 
        proxyUser.getName();
    }
}

Cglib动态代理

Cglib代理是功能最为强大的一种代理方式,因为其不仅解决了静态代理需要创建多个代理类的问题,还解决了jdk代理需要被代理对象实现某个接口的问题。

public class CglibProxy implements MethodInterceptor {

  @Override
  public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    Object result = methodProxy.invokeSuper(o, objects);
    return result;
  }
}

客户端

public class Test {
    public static void main(String[] args) {
        OverUser user = new OverUser();

        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(OverUser.class);
        enhancer.setCallback(intermediary);

        OverUser rentProxy = (OverUser) enhancer.create();
        rentProxy.getName();
    }
}

你可能感兴趣的:(设计模式)