Modo de agente de patrones de diseño comunes

concepto

El patrón de proxy se refiere a proporcionar un proxy para que otros objetos controlen el acceso a este objeto. Este tipo de patrón de diseño pertenece al patrón estructural. El
patrón de agencia generalmente contiene tres roles:

  • Rol del tema abstracto : la responsabilidad principal es declarar el método de interfaz común del tema real y el agente. Esta clase puede ser una interfaz o una clase abstracta
  • Rol de tema real : esta clase también se denomina clase de agente, que define el objeto real representado por el agente y es responsable del objeto comercial lógico real del sistema de ejecución.
  • Rol de tema de agente : también conocido como la clase de agente, que tiene una referencia interna al rol de tema real , por lo que tiene un poder de agencia completo para el rol de tema real . El cliente llama a los métodos del objeto proxy y también llama a los métodos del objeto proxy.

clasificación

El modo de proxy se divide en proxy estático y proxy dinámico

Proxy estático

El archivo de código de bytes de la clase de proxy ya existe antes de que se ejecute el programa y la relación entre la clase de proxy y la clase delegada se ha confirmado antes de ejecutar

1. Cree una clase de roles de tema abstracto

public interface Payment {
    
    

    String doPqy(String uid);
}

2. Crea una clase de personajes temáticos reales

public class ThirdChannelPayment implements Payment {
    
    
    public String doPqy(String uid) {
    
    
        System.out.println(uid+"->支付成功");
        return "success";
    }
}

3. Crear una clase de rol de tema de agente

public class StaticProxyDemo implements Payment{
    
    
    private Payment pay;

    public StaticProxyDemo(Payment payment) {
    
    
        this.pay=payment;
    }

    public String doPqy(String uid) {
    
    
        System.out.println(uid+"发起支付");
        return pay.doPqy(uid);
    }
}

4. Clase de prueba

public class ProxyDemo {
    
    

    public static void main(String[] args) {
    
    
        StaticProxyDemo pay=new StaticProxyDemo(new ThirdChannelPayment());
        System.out.println(pay.doPqy("Tom"));
        }
}

Resultado de la operación: el
Inserte la descripción de la imagen aquí
diagrama de clases UML es el siguiente:
Inserte la descripción de la imagen aquí

Desventaja

La interfaz de objeto de proxy solo sirve para un tipo de objeto. Si se agrega un nuevo método, todas las clases de proxy deben implementar este método, lo que aumenta el costo de mantenimiento del código.

Proxy dinámico

El código fuente de la clase de proxy dinámico se genera dinámicamente a través de la reflexión de JVM y otros mecanismos durante la ejecución del programa, y ​​la relación entre la clase de proxy y la clase delegada se confirma en tiempo de ejecución.

Proxy dinámico JDK

La premisa de usar el proxy dinámico generado por jdk es que la clase objetivo debe tener una interfaz implementada

1. Clase de proxy dinámico

public class DynamicProxy implements InvocationHandler {
    
    
    private Object target;//被代理的对象

    public Object bind(Object target){
    
    
        this.target=target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
        System.out.println("开始");
        Object result=method.invoke(target,args);
        System.out.println("结束");
        return result;
    }
}

2. Prueba

public class ProxyDemo {
    
    

    public static void main(String[] args) {
    
    
       //jdk动态代理
        DynamicProxy dp=new DynamicProxy();
        ThirdChannelPayment pay=new ThirdChannelPayment();
        Payment p=(Payment) dp.bind(pay);
        System.out.println(p.doPqy("Jam"));
    }
}

resultado de la operación:
Inserte la descripción de la imagen aquí

Agente CGLIB

La premisa de uso es que el objetivo no se puede finalizar, porque las clases modificadas finales no se pueden heredar. Se implementa de manera que las subclases generadas dinámicamente hereden el objetivo.

Clase de proxy

public class CglibProxy implements MethodInterceptor {
    
    

    private  Object target;
    

    public Object getInstance(Object target){
    
    
        this.target=target;
        Enhancer enhancer=new Enhancer();
        enhancer.setSuperclass(this.target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    
    
        System.out.println("开始啦");
        Object obj=methodProxy.invokeSuper(o,objects);
        System.out.println("付款结束");
        return obj;
    }
}

prueba

public class ProxyDemo {
    
    
    public static void main(String[] args) {
    
    
        //cglib代理
        CglibProxy cp=new CglibProxy();
        ThirdChannelPayment tp=new ThirdChannelPayment();
        Payment pay=(Payment) cp.getInstance(tp);
        System.out.println(pay.doPqy("Alia"));
    }
}

resultado de la operación:
Inserte la descripción de la imagen aquí

La diferencia entre el proxy dinámico JDK y el proxy CGLIB

  1. El proxy dinámico JDK implementa la interfaz del objeto proxy y el proxy CGLIB hereda el objeto proxy
  2. El proxy dinámico JDK y el proxy CGLIB generan códigos de bytes durante el tiempo de ejecución, el proxy dinámico JDK escribe códigos de bytes de clases directamente y el proxy CGLIB utiliza el marco ASM para escribir códigos de bytes de clases. La implementación del proxy CGLIB es más complicada y la generación de clases de proxy es menos eficiente que el proxy dinámico JDK
  3. El proxy dinámico JDK llama a los métodos de proxy a través del mecanismo de reflexión, el proxy CGLIB llama a los métodos directamente a través del mecanismo FastClass, la eficiencia de ejecución del proxy CGLIB es mayor
  4. En el marco de Spring, cuando el Bean tiene una interfaz de implementación, Sring usará el proxy dinámico JDK; cuando el Bean no implementa una interfaz, Spring elegirá el proxy CGLIB

La diferencia entre proxy estático y proxy dinámico

  1. El agente estático solo puede completar la operación del agente manualmente. Si la clase de agente agrega un método, la clase de agente debe agregarse sincrónicamente, lo que viola el principio de apertura y cierre.
  2. El proxy dinámico adopta el método de generar código dinámicamente en tiempo de ejecución, cancela la restricción de expansión en la clase de proxy y sigue el principio de apertura y cierre.

El principio de apertura y cierre: una entidad de software como clase, módulo y función debe estar abierta para extensión y cerrada para modificación.

para resumir

Si el agente dinámico desea extender la lógica mejorada de la clase objetivo, se puede combinar con el modo de estrategia y se puede completar agregando una nueva clase de estrategia sin modificar el código de la clase de agente.

Ventajas del modelo proxy:

  1. El modo proxy separa el objeto proxy del objeto objetivo real llamado, reduce el acoplamiento del sistema hasta cierto punto y tiene una buena escalabilidad
  2. Puede desempeñar un papel en la protección del objetivo.
  3. Puede mejorar la función del objeto de destino.

Desventajas del modo proxy:

  1. El modo de agente aumentará el número de clases en el diseño del sistema y aumentará la complejidad del sistema.
  2. Agregue un objeto proxy al cliente y al objeto de destino, lo que hace que la velocidad de procesamiento de la solicitud se ralentice

Supongo que te gusta

Origin blog.csdn.net/xzw12138/article/details/106640083
Recomendado
Clasificación