agente de patrón de diseño java

¿Qué es el modo proxy?

De hecho, "agente" significa lo mismo que "agente" en la vida. En pocas palabras, significa que lo que desea hacer no se puede hacer directamente por algunas razones y debe ser implementado por otra persona "en nombre de". Hay muchos ejemplos, así que no daré ninguno. La cuestión es entender qué hace y cómo lo hace. En cuanto a cuándo usarlo, tú decides.

proxy estático

Primero, obtengamos una comprensión preliminar del modo proxy a través de un ejemplo simple de un proxy estático.
Escenario: es como un cazatalentos que recluta personas para una empresa. La empresa es el "rol real" que recluta personas, y el cazatalentos es el "rol de agente" que se encarga de reclutar personas.

El contenido del agente se abstrae en una interfaz.

La empresa y el headhunter deben ponerse de acuerdo mutuamente sobre el alcance de la responsabilidad de la agencia (específicamente qué cosas se harán).

/**
 * 描述:定义代理的具体内容
 * <p>作者: aliyu
 * <p>创建时间: 2021-10-15 10:44 上午
 */
public interface HireSomeone {
    
    

    /**
     * 雇佣
     */
    public void hire();
}

personaje real

La persona que realmente gestiona la solicitud es la empresa. En última instancia, la interfaz de contenido proxy debe ser implementada por la propia empresa.

/**
 * 描述:公司招聘,实际招聘人
 * <p>作者: aliyu
 * <p>创建时间: 2021-10-15 10:37 上午
 */
public class CompanyHire implements HireSomeone{
    
    

    @Override
    public void hire() {
    
    
        System.out.println("我是实际执行雇佣的人");
    }
}

rol de agente

El rol de agente contiene referencias a objetos reales, de modo que las solicitudes se pueden convertir en objetos reales para su procesamiento y las operaciones se pueden adjuntar antes y después (por ejemplo: la persona que busca trabajo aceptó unirse al trabajo y el cazatalentos necesita para enviarle un correo electrónico de aceptación. Esta operación, el cazatalentos De hecho, no se puede manejar. Por lo tanto, el cazatalentos necesita reclutar a los recursos humanos de la empresa específica, y el personal de recursos humanos completará esta operación. Al mismo tiempo, el cazatalentos, como intermediario, puede añadir algunas cosas a los intercambios entre las dos partes).

/**
 * 描述:代理角色
 * <p>作者: aliyu
 * <p>创建时间: 2021-10-15 10:54 上午
 */
public class ProxyHire implements HireSomeone{
    
    

    /**
     * 传入实际操作的角色“公司”
     */
    private CompanyHire companyHire;

    public ProxyHire(CompanyHire companyHire) {
    
    
        this.companyHire = companyHire;
    }

    @Override
    public void hire() {
    
    
        //实际操作是由真实角色“公司”完成的
        companyHire.hire();
    }
}

El objeto proxy de prueba completa el proxy:

/**
 * 描述:模拟通过调用代理对象,实际调用真实对象的过程
 * <p>作者: aliyu
 * <p>创建时间: 2021-10-15 10:57 上午
 */
public class TestProxy {
    
    
    
    public static void main(String[] args) {
    
    
        //实例化"实际对象"
        CompanyHire companyHire = new CompanyHire();
        //传入"代理"
        ProxyHire proxyHire = new ProxyHire(companyHire);
        //点进去看代码,可以发现"雇佣"操作实际是由传入"真实对象"完成的。
        proxyHire.hire();
    }
}

proxy dinámico

Cada clase de proxy debe implementar la interfaz de contenido del proxy. Si se agregan métodos a la interfaz, la clase de proxy también debe modificarse en consecuencia. En segundo lugar, cada objeto de interfaz de la clase proxy corresponde a un objeto real. Si hay muchos objetos reales, la clase proxy estática estará muy inflada y será difícil de manejar. Como se muestra abajo:

public class ProxyHire implements HireSomeone{
    
    

    private CompanyHire companyHire;
......

public class ProxyHire2 implements HireSomeone{
    
    

    private CompanyHire2 companyHire2;
......

public class ProxyHire3 implements HireSomeone{
    
    

    private CompanyHire3 companyHire3;
......

Al mismo tiempo, también podemos encontrar que dicho código en realidad se repite. ¿Hay alguna manera de no escribir tantas clases de proxy? Esto hace surgir agentes dinámicos.
Los proxies dinámicos se diferencian de los estáticos en que crean dinámicamente clases de proxy basadas en los objetos del proxy. De esta manera, puede evitar el problema de demasiadas clases de proxy en servidores proxy estáticos. El proxy dinámico es un método de implementación que se implementa mediante reflexión y se genera mediante reglas fijas con la ayuda del propio java.lang.reflect.Proxy de Java.

nueva una clase de proxy dinámica:

/**
 * 描述:动态代理类
 * <p>作者: aliyu
 * <p>创建时间: 2021-10-15 2:09 下午
 */
public class DynamicProxyHire implements InvocationHandler {
    
    

    /**
     * 传入的是object,就可以满足不同真实对象的传入
     */
    private Object object;

    public DynamicProxyHire(Object object) {
    
    
        this.object = object;
    }

    /**
     * 当在与其关联的代理实例上调用方法时,将在调用处理程序上调用此方法。
     * 简单来说就是通过动态代理类执行真实对象方法时,会进入这里。
     * @param proxy 真实对象
     * @param method 通过代理对象调用的方法(通过反射获得)
     * @param args  参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
        //调用真实对象的方法
        Object result = method.invoke(this.object, args);
        return result;
    }
}

Prueba de proxy completo a través de objetos proxy dinámicos

public class TestDynamicProxy {
    
    
    
    public static void main(String[] args) {
    
    
        //我们要代理的真实对象
        CompanyHire companyHire = new CompanyHire();
        //我们要代理哪个真实对象,就将该对象传进去,最后是通过该真实对象来调用其方法的
        InvocationHandler handler = new DynamicProxyHire(companyHire);
        //第一个参数 ,我们这里使用handler这个类的ClassLoader对象来加载我们的代理对象
        ClassLoader classLoader = handler.getClass().getClassLoader();
        //第二个参数,我们这里为代理对象提供的接口是真实对象所实现的接口,表示我要代理的是该真实对象,这样我就能调用这组接口中的方法了
        Class<?>[] interfaces = companyHire.getClass().getInterfaces();
        //第三个参数handler, 我们这里将这个代理对象关联到了上方的 InvocationHandler 这个对象上
        //表示当前的InvocationHandler实现实例对象
        HireSomeone hireSomeone = (HireSomeone) Proxy.newProxyInstance(classLoader, interfaces, handler);
        hireSomeone.hire();
    }
}

Ventajas y desventajas del modelo proxy

Ventaja 1: carga diferida

"Cuando se inicia el sistema, los métodos que consumen más recursos se separan mediante el modo proxy, lo que puede acelerar la velocidad de inicio del sistema y reducir el tiempo de espera del usuario. Cuando el usuario realmente consulta la operación, la clase de proxy se cargará los datos reales por separado
. La clase de consulta de la base de datos completa la solicitud del usuario. Este proceso utiliza el modo proxy para realizar la carga diferida. La teoría es comprensible, pero ¿cómo se implementa? Encontré un ejemplo.

Interfaz de proxy abstracta:
Insertar descripción de la imagen aquí
Rol real:
Insertar descripción de la imagen aquí
Rol de proxy:
Insertar descripción de la imagen aquí
ps: Resulta que solo necesita configurar el objeto real entrante = nulo. Luego, cuando realmente se llama al método, se crea una instancia del objeto real. Esto juega el papel de carga diferida.
URL de ejemplo: https://www.cnblogs.com/klyjb/p/11522968.html

Ventaja 2-Acoplamiento reducido y fácil mantenimiento

El trabajo de verificación se realiza antes de llamar al objeto real. Si se agregan nuevas funciones, se puede modificar el objeto proxy en lugar del objeto real. La agregación de objetos reemplaza la herencia y reduce el acoplamiento.

El llamado "trabajo de verificación que se puede realizar antes de llamar al objeto real" se debe a que es el método para llamar al objeto real en el método del objeto proxy, y no es difícil agregarle algunas líneas de código de verificación.

    @Override
    public void hire() {
    
    
        //这里可以加入校验代码
        //实际操作是由真实角色完成的
        companyHire.hire();
        //执行完后也可以加入代码,实现某些特殊的需求
    }

"Si se agrega una nueva función, puede modificar el objeto proxy en lugar del objeto real": esta oración probablemente sea lo mismo que agregar verificación antes de llamar al objeto real, pero el contenido agregado es diferente.
En resumen, esto se puede hacer, pero nunca me he encontrado con tal escenario y no puedo explicarlo claramente.

defecto

Cada clase de proxy debe implementar la interfaz de contenido del proxy. Si se agregan métodos a la interfaz, la clase de proxy también debe modificarse en consecuencia.

otro

Supongo que te gusta

Origin blog.csdn.net/mofsfely2/article/details/120777762
Recomendado
Clasificación