PATRÓN PROXY

Clasificación:

Patrón  Estructural.

Propósito:

 Es un sustituto de otro objeto, para controlar el acceso a él.

Intención:

Proporcionar un representante para controlar el acceso a un objeto, del mismo tipo.

También conocido como: 

Virtual proxy/Surrogate/Sistituto/Apoderado.

Motivación:

Una de las razones para controlar el acceso a un objeto, es aplazar el coste total de su creación e inicialización hasta que realmente se necesita para usarlo, de modo que el patrón obliga a que las llamadas a métodos de un objeto ocurran indirectamente a través de un objeto Proxy..

Aplicabilidad:

 Un proxy remoto proporciona un representante local de un objeto remoto.  Un proxy virtual crea objetos costosos sólo cuando es necesario. Un proxy de protección controla el acceso al objeto original.  Una referencia inteligente es un sustituto de un simple puntero que realiza alguna acción adicional:Contar el número de referencias al objeto original.  Cargar un objeto persistente en memoria cuando es referenciado por vez primera.  Bloquea el acceso al objeto real para que no sea modificado por otro objeto.

Estructura:

Los participantes:

 Proxy:

Tiene referencia al objeto RealSubject, tiene una interfaz idéntica a la de Subject así un proxy puede sustituirse por una RealSubject, y controla el acceso al RealSubject y puede ser el responsable de su creación y borrado.

Subject: 

Define una interfaz común para RealSubject y Proxy.

RealSubject: 

Define el objeto real que Proxy representa.

Client:

  Quien  desea acceder al objeto.

 Colaboraciones:

 Client accede a Subject a través de Proxy. 

Consecuencias:

  • El patrón proxy no es útil en su forma pura, debe ser combinado con un gestor de servicios para satisfacer algún comportamiento de utilidad.
  • El proxy  remoto oculta espacios de direcciones diferentes.
  • El proxy  virtual evita consumir recursos hasta que no es necesario.
  • El proxy  de protección y las referencias inteligentes permiten realizar tareas internas (recolección de basura, controlar accesos, etc.)
  • Permite el copy-on-write: un objeto costoso es compartido hasta que alguien cambia su estado. Suele utilizarse junto con una cuenta de referencias por parte del objeto compartido. Cuando no es referenciado por nadie se autodestruye. 

Implementación:

El siguiente ejemplo permite modificar un archivo existe  y visializarlo doblemente, en la parte izquierda se muestra el archivo real , no editable, y el la parte el archivo editable, cuando se elije guardar cambios, se actualiza el archivo real, sólo hasta ese momento, pues proxy retrasa la creacion y modificación de los objetos, hasta que sea necesario.  Debes crear un archivo "Texto" en blog de notas, para  que funcione el archivo, al cual le adicionaras la informacion que quieras.

 package logicap;

/**

 *

 * @author Katherin

 */

public interface Archivo {

    public String cadenaTexto();

}

package logicap;

import java.io.*;

/**

 *

 * @author Katherin

 */

public class ArchivOriginal implements Archivo {

    private String contenido = "";

    private String temp = "";

    public ArchivOriginal() {

        this.cargarArchivo();

    }

    public void cargarArchivo() {

        contenido = "";

        temp = "";

        try {

            FileReader Fichero = new FileReader("Texto.txt");

            BufferedReader leer = new BufferedReader(Fichero);

            while ((temp = leer.readLine()) != null) {

                contenido = contenido + temp + "\n";

            }

            leer.close();

        } catch (IOException ioe) {

            System.out.println(ioe);

        }

    }

    public String cadenaTexto() {

        this.cargarArchivo();

        return contenido;

    }

}

package logicap;
import java.io.*;
import javax.swing.JOptionPane;
/**
 *
 * @author Katherin
 */
public class ArchivoProxy implements Archivo {
    private ArchivOriginal archivo;
    public void guargarArchivo(String str) {
        try {
            FileWriter fw = new FileWriter("Texto.txt");
            fw.write(str, 0, str.length());
            fw.close();
        } catch (IOException e) {
            JOptionPane.showMessageDialog(null, "Se supone que nada podría salir mal.");
        }
    }
    public String cadenaTexto() {
        if (archivo == null) {
            archivo = new ArchivOriginal();
        }
        return archivo.cadenaTexto();
    }
}
package logicap;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.*;
/**
 *
 * @author Katherin
 */
public class Pizarra extends JFrame implements ActionListener {
    private JTextArea tablero;
    private JTextArea tableroProxy;
    private ArchivoProxy proxy;
    private String texto = "";
    private JButton cargarArchivo;
    private JButton guardarArchivo;
    private JButton refrescar;
    private JButton salir;
    private Font f;
    public Pizarra() {
        this.setLayout(null);
        this.setTitle("Laboratorio de Moléculas");
        this.setSize(800, 500);
        this.setLocation(100, 100);
        f = new Font("Helvetica", Font.ITALIC + Font.BOLD, 10);
        tablero = new JTextArea();
        tablero.setSize(350, 300);
        tablero.setLocation(10, 10);
        tablero.setFont(f);
        tablero.setText("");
        tablero.setEditable(false);
        add(tablero);
        JScrollPane areaScrollPane = new JScrollPane(tablero);
        areaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        areaScrollPane.setSize(350, 300);
        areaScrollPane.setLocation(10, 10);
        this.getContentPane().add(areaScrollPane);
        tableroProxy = new JTextArea();
        tableroProxy.setSize(350, 300);
        tableroProxy.setLocation(400, 10);
        tableroProxy.setFont(f);
        tableroProxy.setText("");
        tableroProxy.setEditable(true);
        add(tableroProxy);
        JScrollPane areaScrollPane2 = new JScrollPane(tableroProxy);
        areaScrollPane2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        areaScrollPane2.setSize(350, 300);
        areaScrollPane2.setLocation(400, 10);
        this.getContentPane().add(areaScrollPane2);
        cargarArchivo = new JButton();
        cargarArchivo.setSize(300, 20);
        cargarArchivo.setLocation(40, 360);
        cargarArchivo.setText("Cargar Archivo");
        cargarArchivo.addActionListener(this);
        add(cargarArchivo);
        guardarArchivo = new JButton();
        guardarArchivo.setSize(300, 20);
        guardarArchivo.setLocation(40, 390);
        guardarArchivo.setText("Guardar Cambios");
        guardarArchivo.addActionListener(this);
        add(guardarArchivo);
        refrescar = new JButton();
        refrescar.setSize(300, 20);
        refrescar.setLocation(40, 420);
        refrescar.setText("Actualizar");
        refrescar.addActionListener(this);
        add(refrescar);
        salir = new JButton();
        salir.setSize(100, 50);
        salir.setLocation(400, 370);
        salir.setText("Salir");
        salir.addActionListener(this);
        add(salir);
        addWindowListener(new Cierre());
    }
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == cargarArchivo) {
            proxy = new ArchivoProxy();
            tablero.setText(proxy.cadenaTexto());
            tableroProxy.setText(proxy.cadenaTexto());
        }
        if (e.getSource() == guardarArchivo) {
            texto = tableroProxy.getText();
            proxy.guargarArchivo(texto);
        }
        if (e.getSource() == refrescar) {
            tablero.setText(proxy.cadenaTexto());
        }
        if (e.getSource() == salir) {
            System.exit(0);
        }
    }
    class Cierre extends WindowAdapter {
        @Override
        public void windowClosing(WindowEvent e) {
            System.exit(0);
        }
    }
}
package improxy;
import logicap.Pizarra;
/**
 *
 * @author Katherin
 */
public class Main {
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Pizarra lab=new Pizarra();
        lab.setVisible(true);
    }
}

Usos conocidos:

 NEXTSTEP [Add94] utiliza los poderes (los casos de clase NXProxy) como local  representantes de los objetos que puedan ser distribuidos. Un servidor proxy crea  mando a distancia para los objetos cuando los clientes lo soliciten. Al recibir un mensaje, el proxy  codifica junto con sus argumentos y, a continuación, envía el mensaje codificado al objeto remoto. Del mismo modo, el sujeto codifica toda vuelta los resultados y los envía al volver a la NXProxy objeto. 

McCullough [McC87] discute el uso de proxies en Smalltalk para acceder a objetos remotos. Pascoe [Pas86] se describe cómo proporcionar a los efectos secundarios sobre el método de las llamadas y el acceso  de control con "Encapsulators". 

Patrones relacionados:

Adapter: un adaptador proporciona una interfaz para el objeto que se adapta. En cambio, una aproximación proporciona la misma interfaz que su tema. Sin embargo, un representante utilizados para protección de acceso podría negarse a realizar una operación que el tema llevará a cabo, por lo que su interfaz puede ser efectivamente un subconjunto de la del sujeto. 

Decorator: Aunque los decoradores pueden tener aplicaciones similares como apoderados, decoradores tienen un propósito diferente. Un decorador añade una o más funciones a un objeto, mientras que un servidor proxy controla el acceso a un objeto. 

Proxy varía en el grado en que su aplicación como un decorador. Una protección proxy podría aplicarse exactamente como un decorador. Por otra parte, un mando a distancia de proxy no contienen una referencia directa a su verdadero tema, pero sólo una referencia indirecta, como "host ID y dirección local de acogida." Un espacio virtual proxy comenzará con una referencia indirecta, tales como un nombre de archivo, sino que eventualmente obtener y utilizar una referencia directa.

Referencias:

PDF-Departamento de Sistemas Informáticos y Programación Curso de doctorado 1999 - 2000 Patrones  de  diseño orientado a objetos. 

DesIgn Patterns: Elements of Reusable Object-Oriented Software Gamma, Helm, Johnson,   Vlissides Editorial              Addison-Wesley.

kybele.escet.urjc.es/documentos/SI/Patrones/18_Proxy.ppt

1 comentario: