informaticaPC

Patrones de Diseño Software

Proxy

Este patrón se basa en proporcionar un objeto que haga de intermediario (proxy) de otro, para controlar el acceso a él.

Patrón Proxy en UML

Existen diferentes tipos de proxy:

  • Proxy remoto: proporciona un representante local de un objeto situado en otro espacios de direcciones (en otro dispositivo conectado en red).
  • Proxy virtual: usados para crear objetos costosos sólo cuando se soliciten.
  • Proxy de protección: permiten controlar el acceso a un objeto cuando es accesible o no, dependiendo de determinados permisos.
  • Referencia inteligente: un sustito de un puntero, que realiza operaciones adicionales en el momento de accederse al objeto.

Veamos un ejemplo de Proxy virtual en el que abrimos un documento que contiene una imagen, la cual se cargará y mostrará cuando el usuario haga scroll.

Main.java:

package estructurales.proxy.proxy01;

public class Main
{
    public static void main( String[] args )
    {
        // Abrimos un documento que puede contener una sola imagen
        Documento doc = new Documento( "Presupuesto.doc");

        try     // Necesario al usar Thread
        {
            // Pausamos la ejecución del programa durante 3 segundos
            Thread.sleep( 3000 );

            // Simulamos que el usuario hace scroll
            doc.hacerScroll();
        }
        catch( Exception e )
        {
            System.out.println("Ha ocurrido un error");
        }
    }
}

Documento.java:

package estructurales.proxy.proxy01;

public class Documento
{
    private String nombreDoc;
    private String texto;

    private ImagenProxy imgProxy;

    // ---------------------------

    public Documento( String nombreDoc )
    {
        this.setNombreDoc( nombreDoc );
        this.cargarContenido();
        this.mostrar();
    }

    // ---------------------------

    public String getNombreDoc()
    {
        return this.nombreDoc;
    }

    // ---------------------------

    public void setNombreDoc( String nombreDoc )
    {
        this.nombreDoc = nombreDoc;
    }

    // ---------------------------

    public void cargarContenido()
    {
        // Aquí cargaríamos el archivo y obtendríamos su contenido

        this.texto = "Texto del documento";
        this.imgProxy = new ImagenProxy( "imagen.jpg" );

        System.out.println("Documento cargado en memoria");
    }

    // ------------------------

    public void mostrar()
    {
        System.out.println("Mostrando el contenido...\n");
    }

    // ------------------------

    // Supongamos que este método es un evento que se lanza al hacer scroll
    public void hacerScroll()
    {
        System.out.println("El usuario ha hecho scroll...");

        imgProxy.mostrarImagen();
    }
}

Imagen.java (Sujeto en el diagrama anterior):

package estructurales.proxy.proxy01;

public interface Imagen
{
    public void mostrarImagen();
}

ImagenReal.java (SujetoReal en el diagrama anterior):

package estructurales.proxy.proxy01;

public class ImagenReal implements Imagen
{
    private String nombre;

    // ---------------------------

    public ImagenReal( String nombre )
    {
        this.nombre = nombre;
    }

    // ---------------------------

    @Override
    public void mostrarImagen()
    {
        System.out.println("Mostrando imagen: [" + nombre + "]" );
    }
}

ImagenProxy.java (Proxy en el diagrama anterior):

package estructurales.proxy.proxy01;

public class ImagenProxy implements Imagen
{
    private ImagenReal imagen = null;
    private String nombreImagen = "";


    // ---------------------------

    public ImagenProxy( String nombreImagen )
    {
        this.nombreImagen = nombreImagen;
    }

    // ---------------------------

    @Override
    public void mostrarImagen()
    {
        if(this.imagen == null)
        {
            this.imagen = new ImagenReal( nombreImagen );
        }

        this.imagen.mostrarImagen();
    }
}

Al ejecutarlo obtendríamos como resultado:

Ejemplo

EXPLICACIÓN:

  • Al inicio del programa cargamos un Documento y transcurridos unos segundos simulamos que el usuario hace scroll en el mismo.
  • La clase Documento guarda una referencia a ImageProxy, instanciándose al cargar el documento con el nombre de la imagen que corresponda.
  • La clase ImagenProxy guarda una referencia de ImagenReal, devolviendo ésta cuando lo solicite el documento.
Información

Para usar este patrón en lenguaje Java podemos utilizar la interface InvocationHandler.

Primera página Anterior Siguiente Última página
Usamos cookies para ofrecerte una experiencia mejorada, el continuar navegando supone que aceptas su uso