Patrón Proxy Remoto

El patrón Proxy en específico, tiene múltiples usos y por ende puede ser implementado de varias maneras. Una de ellas es poder acceder a recursos remotos. En otras palabras, poder acceder a objetos que no existen dentro de la misma máquina virtual (JVM). Esto se conoce como patrón proxy remoto.

Las variaciones del patrón Proxy son las siguientes:

  • Proxy Remoto: se utiliza para acceder recursos (objetos) que no están dentro de la misma máquina virtual.
  • Proxy Virtual: se utiliza para crear objetos que son muy costosos en memoria.
  • Proxy Protegido: se utiliza para acceder a recursos que requieren cierto control de acceso.

En este post, vamos a analizar en detalle el patrón Proxy Remoto.

En el post anterior vimos como podíamos manejar diferentes estados para una cotización. Ahora bien, resulta ser que la compañía cuenta con varios puntos de venta en diferentes terminales (computadoras) y el supervisor de ventas necesita un reporte básico de las cotizaciones que están siendo procesadas en cada terminal.

Veamos un diagrama de ejemplo.

Diagrama de ejemplo de la aplicación

El reporte debe contener el estado actual de la cotización, la terminal en la que esta siendo procesada y además el nombre del agente encargado de la cotización.

El problema que tenemos con esta solicitud es que cada terminal es independiente y tiene su propia memoria en donde almacena la información de cada cotización por aparte.

La aplicación que vayamos a instalar en la máquina del supervisor no va a poder acceder a las instancias que fueron creadas en cada terminal. En otras palabras, solo podríamos crear el reporte si el supervisor crea una cotización desde su computadora.

Para solucionar este problema podemos hacer uso del patrón Proxy Remoto, que nos permite acceder a recursos que no comparten la misma máquina virtual o no están en el mismo servidor (por eso se le llama remoto).

Veamos un ejemplo que ilustra la función general de este patrón.

Diagrama de ejemplo que muestra el funcionamiento del patrón proxy remoto

En el diagrama anterior, la memoria de la computadora del supervisor tiene nuestra clase que se encargará de generar los reportes para cada terminal. Además contará con el Proxy, que es el que se encargará de acceder a la memoria de la terminal específica. Para la clase encargada de los reportes le es indiferente a quien se llame, esta clase pensará que esta accediendo a un recurso local.

Una vez que logremos acceder a la memoria de la terminal, nuestra clase Proxy se encargará de realizar el proceso necesario para obtener la información que necesitamos y retornarla a la clase que crea el reporte.

Esperen un momento…¿Acceder a la memoria de la terminal? ¿Cómo podemos acceder a otra memoria (JVM) desde una computadora? Podríamos pensar que vamos a requerir clases adicionales para manejar la conexión a la red y luego establecer una comunicación entre la computadora del supervisor y las diferentes terminales, etc.

En realidad, todo lo anterior es cierto, pero para nuestro ejemplo vamos a utilizar RMI (Remote Method Invocation) que significa, llamado de métodos remoto. Este framework nos permite realizar exactamente lo que necesitamos, localizar objetos en máquinas virtuales remotas y hacer uso de sus métodos.

Java RMI

Antes de continuar, veamos un resumen de RMI. Este framework nos permite realizar llamadas a métodos remotos. La ventaja es que no tenemos que preocuparnos por los detalles de cómo lograr conectarse a otra JVM, es decir, toda la lógica de redes o de I/O ya viene por defecto.

Además, provee toda la infraestructura necesaria para poder realizar llamadas a los métodos remotos, como por ejemplo, el buscador de direcciones para obtener los objetos dentro de esa dirección.

En RMI existen diferentes componentes:

  • Stub: es el encargado de comunicar al cliente con el objeto que se encarga de realizar el trabajo, es decir, nuestro objeto Proxy.
  • Skeleton: es el encargado de recibir la solicitud del Stub, transformarla y llamar al método que hace el trabajo necesario.
  • Servicio: es el objeto que utiliza el Skeleton para realizar el trabajo necesario.

En otro post detallaré un poco más el uso de RMI y cómo implementarlo, pero por ahora basta con saber que lo utilizamos para acceder objetos que existen en otras máquinas virtuales.

Ahora que ya tenemos claro los conceptos básicos de RMI, veamos el diagrama que ilustra el uso de RMI y este patrón.

Diagrama de ejemplo del patrón proxy remoto

El diagrama anterior nos muestra como el cliente (Supervisor) puede acceder a los objetos del servidor (TerminalA) para obtener la información necesaria.

El libro Head First Design Patterns define el patrón Proxy Remoto de la siguiente manera: Este patrón ofrece un sustituto o reemplazo para que otro objeto controle el acceso a él.

Este patrón se utiliza para crear un objeto que controla el acceso a otro objeto, el cual puede ser remoto, muy costoso de inicializar o crear, o que necesita ser accedido de manera segura.

Este es el diagrama sugerido para este patrón:

Diagrama de clases sugerido del patrón proxy remoto
  • Subject: es la interfaz que implementan RealSubject y Proxy, de esta manera, la clase Proxy puede reemplazar a RealSubject en cualquier cliente.
  • RealSubject: es la clase que se encarga de realizar todo el trabajo, es la clase que contiene la información que requiere el cliente.
  • Proxy: es la clase encargada de recibir las solicitudes del cliente y utilizar a RealSubject para suplirlas.

El resultado de ejecutar el código de ejemplo del servidor es el siguiente.

Resultado de ejecutar el código de ejemplo de la terminal

El resultado de ejecutar el código de ejemplo del cliente es el siguiente.

Resultado de ejecutar el código de ejemplo del cliente

Como podemos ver, pare el cliente (Supervisor), es transparente el llamado a cada InvoicePreview para obtener la información del Agente, la terminal y el estado actual aún cuando las instancias de InvoicePreview están en otra maquina/terminal.

Para ejecutar este ejemplo, solamente ejecuto el código de la clase que funciona como el servidor usando cualquier IDE y luego desde línea de comando en una terminal nueva, ejecuto el código del cliente.

El código de ejemplo lo pueden descargar aquí.

En el próximo post vamos a discutir el Patrón llamado Proxy Virtual.

Recordá suscribirte aquí para recibir las últimas actualizaciones todas las semanas.

Referencias:
Libro Head First Design Patterns. Versión digital.

Leave a Reply

Your email address will not be published. Required fields are marked *