Modo de agente del patrón de diseño de Java (7)

No pierda los estribos a voluntad En la vida, es imposible que una persona se haga amiga de todos los que conoce. Un verdadero amigo no puede ser forzado, y Dios no estipula quién debe ser amigo de quién. Todo debe ser reacio a hacerlo. Todo en la vida puede ser reacio. Sólo el "amor" no puede ser reacio, y la amistad es lo mismo.

Aprendizaje de patrones de diseño ,
escribiré en un blog sobre 23 patrones de diseño en un futuro cercano , así que estad atentos ~ —9/01/2021

definición

Proporcione un proxy para que otros objetos controlen el acceso a este objeto. En algunos casos, un objeto no es adecuado o no puede referirse directamente a otro objeto, y el objeto proxy puede desempeñar un papel intermediario entre el cliente y el objeto de destino.

Enciclopedia de Baidu

Clasificación de roles

  • Rol abstracto: un método comercial implementado por una interfaz o clase abstracta que declara un rol real.
  • Rol del agente: Realice el rol abstracto, que es el agente del rol real. El método abstracto se realiza a través del método de lógica empresarial del rol real, y puede adjuntar sus propias operaciones.
  • Rol real: implementar roles abstractos, definir la lógica empresarial que se implementará mediante roles reales, para que los roles de los agentes llamen

análisis

Supongamos que quiero alquilar una casa, primero debo ir a una agencia para ver la casa y luego elegir una casa adecuada para alquilar;

¿De dónde viene la casa? Debe ser el propietario, ¿no?

Aquí el propietario es una persona que necesita un agente y el agente es la casa, así que deje que el agente de la casa sea un agente, deje que el agente nos ayude a alquilarla.

beneficio:

  • El arrendador no ha cambiado nada, pero la casa está representada por el agente, y el agente nos alquilará la casa después de adquirirla, y cobrará una tarifa de agente, etc.

UML类图(1.1):


análisis:

  • El papel real de HouseMaster se refiere aquí al propietario.
  • El papel abstracto de la casa se refiere a la casa aquí
  • El rol del agente HouseProxy aquí se refiere al intermediario

Implementación de proxy estático:

IHouse (casa):

public interface IHouse {
    
    
    void showHouse();
}

HouseMaster (anfitrión):

public class HouseMaster implements IHouse {
    
    

    @Override
    public void showHouse() {
    
    
        Log.i("代理模式:", "我是房东,我要出租房");
    }
}

HouseProxy (intermediario):

public class HouseProxy {
    
    

    IHouse house;
    //吧房子交给中介 (吧IHouse 接口组合到 HouseProxy 上)
    public HouseProxy( IHouse house) {
    
    
        this.house = house;
    }

    public void showHouse(){
    
    
        house.showHouse();//房东的房子
    }

}

Usar código:

//创建代理类 传入需要代理的类
HouseProxy houseProxy = new HouseProxy(new HouseMaster());

houseProxy.showHouse();

Log图(2.1):


Tal vez todos sigan fascinados por el modelo de agencia, te lo explicaré en detalle

Ahora, solo usamos HouseProxy (intermediario) para ver la casa del arrendador A, también puede hacer otras operaciones, por ejemplo, podemos dejar que nos lleve a ver otras casas, y también podemos darle propina al agente:

Clase HouseProxy (intermediario):

public class HouseProxy {
    
    

    IHouse house;
    public HouseProxy( IHouse house) {
    
    
        this.house = house;
    }

    public void showHouse(){
    
    
        money();//收取消费
        house.showHouse();//房东的房子
        seeHouse();//带用户看房
    }
    public void money(){
    
    
        Log.i("代理模式:","我是中介,我要收取消费");
    }
    public void seeHouse(){
    
    
        Log.i("代理模式:","我是中介,我带用户看房");
    }
}

Log图(2.2):


房东并没有发生变化,变化的只是中介
比如说在项目中,一个类用到了很多地方现在让这个这个类前面输出一句话,
咋们是不是就可以不在改变原有代码的基础上来达到这句话的显示呢?

Resumen del modo proxy estático:

ventaja:

  • Sin cambios al código original, cumpliendo con el principio de apertura y cierre (cerrado por modificación)
  • El código público se entrega a la clase de agentes para realizar la división del trabajo.
  • No se preocupe por otros asuntos que no sean de su responsabilidad y complete una transacción completa a través del agente posterior El resultado incidental es que la programación es simple y clara.

Desventajas:

  • Una clase necesita crear una clase de proxy, la cantidad de código se duplicará y la eficiencia del desarrollo se reducirá

Modo de proxy dinámico

Proxy dinámico significa: la clase de proxy puede cambiar con el cambio del proxy. En

pocas palabras, quiero que A sea proxy, solo A proxy, quiero que B sea proxy de B, sin crear muchas clases de proxy

Roles:

  • Controlador de llamadas InvocationHandler
  • Apoderado

¿Qué es InvocationHandler?

JDK1.8CHW图(3.1):


Código de extracción de descarga JDK1.8CHW : lfoz

InvocationHandler es una interfaz implementada por el controlador de invocación de la instancia de proxy .


InvocationHandler es una interfaz que debe reescribirse para
invocar el método (proxy de objeto, método de método, objeto [] args)

Explicación del método de invocación:

  • Parámetro uno (proxy de objeto): la instancia de proxy que llama al método
  • Parámetro dos (método de método): la clase declarada del objeto de método será la interfaz declarada por el método, y puede ser la superinterfaz de la clase de proxy heredando la interfaz de proxy del método. (No importa si no entiendes aquí)
  • Parámetro tres (Object [] args): la matriz de objetos que contiene la llamada al método que pasa los valores de parámetro de la instancia de proxy, o nulo si el método de interfaz no tiene parámetros. Los parámetros de tipos primitivos están contenidos en instancias de clases contenedoras primitivas apropiadas, como java.lang.Integer o java.lang.Boolean.

Esta es la explicación en jdk: no importa si la explicación del método aquí no es clara.

JDK1.8CHW图(3.2):

¿Qué es Proxy?

JDK1.8CHW图(3.3):


Proxy proporciona métodos estáticos para crear instancias y clases de proxy dinámicos y también es la superclase de todas las clases de proxy dinámicas creadas por estos métodos. (Palabras oficiales)

Tengo entendido: Proxy es obtener una instancia del proxy

Definitivamente no desea leer tantas palabras. En pocas palabras: Proxy trabaja con InvocationHandler para completar la generación automática de clases de proxy.

Si obtiene la instancia de proxy:

Proxy.newProxyInstance(
		ClassLoader loader,
        Class<?>[] interfaces,
        InvocationHandler h);

Análisis del parámetro Proxy.newProxyInstance:

  • Parámetro 1: la ubicación de la clase cargada
  • Parámetro dos: interfaz proxy
  • Parámetro 3: Representarse a sí mismo: InvocationHandler

Código:

ProxyInvocationHandler 类:

public class ProxyInvocationHandler implements InvocationHandler {
    
    

    Object object;

    //参数一:object 具体接口的实现类
    public ProxyInvocationHandler(Object object) {
    
    
        this.object = object;
    }

    //生成代理类  返回的是被代理的接口 (返回的是object接口)
    public Object getProxy(){
    
    
        /**
         * this.getClass().getClassLoader() 加载类所在位置
         * object.getClass().getInterfaces() 代理的接口
         * this  表示本身:InvocationHandler
         */
       return Proxy.newProxyInstance(
			       this.getClass().getClassLoader(),
			       object.getClass().getInterfaces(),
			       this
	     	 );
    }

    /**
     * @param proxy 调用该方法的代理实例
     * @param method  所述方法对应于调用代理实例上的接口方法的实例。 方法对象的声明类将是该方法声明的接口,它可以是代理类继承该方法的代理接口的超级接口。
     * @param args 包含的方法调用传递代理实例的参数值的对象的阵列,或null如果接口方法没有参数。
     *             原始类型的参数包含在适当的原始包装器类的实例中,例如java.lang.Integer或java.lang.Boolean 。
     * @return
     * @throws Throwable
     */
    @Override  //处理代理实例,返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
        Object invoke = method.invoke(object, args);
        return  invoke;
    }
}

utilizar:

//需要代理 真实角色
HouseMaster houseMaster = new HouseMaster();

//代理类生成器  传入需要代理的类
ProxyInvocationHandler pit =
			 new ProxyInvocationHandler(houseMaster);

//生成代理类 (必须返回接口)
IHouse proxy = (IHouse) pit.getProxy();

//输出租房子
proxy.showHouse();

Log图(2.3):


HouseMaster (clase de proxy) genera automáticamente la IHouse (interfaz) correspondiente a través del mecanismo de reflexión de la clase ProxyInvocationHandler (controlador de llamadas)

Nota:


Utilice el mecanismo de reflexión de InvocationHandler para obtener el método llamado actualmente:

public class ProxyInvocationHandler implements InvocationHandler {
    
    

	.....
	
    @Override  //处理代理实例,返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
        msg(method.getName());
        Object invoke = method.invoke(object, args);
        return  invoke;
    }

    public void msg(String msg){
    
    
        Log.i("代理模式","代理了"+ msg +"方法");
    }
}

流程图(4.1):


Aquí está el nombre del método showHouse () obtenido

Log图(2.4):

Ahora, este ProxyInvocationHandler es una clase de proxy pública, pasada en una clase que necesita un proxy, y luego se puede devolver un objeto de la clase de proxy a través de getProxy () (siempre que la clase de proxy pasada implemente la clase de proxy devuelta)

ventaja:

  • Sin cambios al código original, cumpliendo con el principio de apertura y cierre (cerrado por modificación)
  • El código público se entrega a la clase de agentes para realizar la división del trabajo.
  • El agente de proxy dinámico es una interfaz, generalmente un negocio correspondiente
  • Un proxy dinámico puede utilizar como proxy múltiples interfaces, siempre que implemente la misma interfaz. En comparación con el proxy estático, cada clase de proxy necesita crear una clase de proxy, que es más flexible

Si realmente no entiende este artículo, puede usarlo, ¡porque el código dinámico es relativamente fijo!

Solo sepa que cada clase juega un papel correspondiente y será utilizada.

  • Controlador de llamadas ProxyInvocationHandler (utilizado para generar automáticamente clases de proxy)

  • El papel real de HouseMaster (necesita estar representado (este artículo se refiere al propietario que alquila la casa))

  • I Papel abstracto de la casa (aquí se refiere a la casa)

  • pit.getProxy () devuelve el rol abstracto (aquí se refiere a regresar a la casa)

  • proxy.showHouse (); implementación específica (referida al alquiler de una casa)

Proyecto completo

Ir a la página de inicio de Patrones de diseño / Principios de diseño

La originalidad no es fácil, tus gustos son tu mayor apoyo para mí, por favor, me gustaría apoyarme ~

Supongo que te gusta

Origin blog.csdn.net/weixin_44819566/article/details/112390541
Recomendado
Clasificación