Proxy (patrón de deseño)

Na Galipedia, a Wikipedia en galego.

O patrón de deseño Proxy é un patrón estrutural que ten como propósito proporcionar un subrogado ou intermediario de un obxecto para controlar o seu acceso.

Índice

Motivación [editar]

Para explicar a motivación do uso deste patrón vexamos un exemplo onde a súa aplicación seria a solución mais axeitada ao problema requirido.

  • Editor que pode engadir obxectos dentro dun documento. A apertura do documento deberá ser rápida, e a creación dos obxectos (imaxes de gran tamaño) é cara
  • Non é necesario crear todos os obxectos con imaxes o abrir o documento porque non todos os obxectos son visibles.
  • Solución : cargar as imaxes baixo demanda.
  • Problema: Como cargar as imaxes baixo demanda sen complicar o resto do editor?
  • Solución: Utilizar un obxecto proxy que se comporte como unha imaxe normal e que sexa o responsable de cargalas baixo demanda.
Exemplo proxy

Aplicabilidade [editar]

O patrón proxy necesita de unha forma de referencia a un obxecto mais flexible que un punteiro. Dependendo dá función que se desexe realizar con dita referencia pódense distinguir diferentes tipos de proxies:

  • proxy remoto: representante local de un obxecto remoto.
  • proxy virtual: crea obxectos custosos baixo demanda (como a clase ImageProxy do exemplo de motivación).
  • proxy de protección: controlo o acceso ó obxecto orixinal.

Estrutura [editar]

Estructura proxy.

Participantes [editar]

  • Proxy (ImageProxy)

Mantén unha referencia ao obxecto real (RealSubject).
Proporciona unha interface idéntica ao suxeito (Subject).
Controla o acceso ao obxecto real e pode ser o responsable da súa creación e borrado.

  • Subject (Graphic)

Defina a interface común de Proxy e RealSubject.

  • RealSubject (Image)

Define o obxecto real.

Colaboracións [editar]

  • Dependendo da clase de proxy, o obxecto proxy redirixe as petición ao obxecto real que representa.

Consecuencias [editar]

O uso do proxy introduce un nivel de indirección adicional con diferentes usos:

  • Un proxy remoto oculta o lugar onde reside un obxecto.
  • Un proxy virtual realiza optimizacións como creación baixo demanda.
  • Os proxies de protección permite realizar diversas tarefas de mantemento adicional ao acceder a un obxecto.

Implementación [editar]

public abstract class Suxeito {
 
        public Suxeito(String nome) {
                _nome = nome;
        }
 
        public String toString() {
                return _nome;
        }
 
        public abstract void metodo1();
        public abstract void metodo2();
 
 
        private String _nome;
}
 
public class SuxeitoReal extends Suxeito {
 
        public SuxeitoReal(String nome) {
                super(nome);
        }
 
        public void metodo1() {
                System.out.println("Executando metodo1 en " + this);
        }
 
        public void metodo2() {
                System.out.println("Executando metodo2 en " + this);
        }
}       
 
public class Proxy extends Suxeito {
 
        public Proxy(String nome) {
                super(nome);
                _accesos_metodo1 = 0;
                _accesos_metodo2 = 0;
                _suxeito_real = null;
        }
 
        private SuxeitoReal obterSuxeitoReal() {
        if (_suxeito_real == null) {
                _suxeito_real = new SuxeitoReal(this + " (Real)");
        }
        return _Suxeito_real;
        }
 
        public void metodo1() {
                _accesos_metodo1++;
                obterSuxeitoReal().metodo1();
        }
 
        public void metodo2() {
                _accesos_metodo2++;
                obterSuxeitoReal().metodo2();
        }
 
        public void status() {
                if (_suxeito_real != null) {
                        System.out.println("Accesos a " + _suxeito_real +
                                                                ": metodo1=" + _accesos_metodo1 +
                                                                ", metodo2=" + _accesos_metodo2);
                } else {
                        System.out.println("Suxeito Real (" + this + ") no creado.");
                }
        }
 
        private SuxeitoReal _suxeito_real;
        private int _accesos_metodo1, _accesos_metodo2;
}       
 
public class Cliente {
 
        public Cliente(Suxeito suxeito) {
                _suxeito = suxeito;
        }
 
        public void executar() {
                _suxeito.metodo1();
                _suxeito.metodo1();
                _suxeito.metodo2();
                _suxeito.metodo1();
        }
 
        private Suxeito _suxeito;
}
 
public class Main {
 
        public static void main(String[] argv) {
                Proxy obxecto_a = new Proxy("obxecto_a");
                Cliente c = new Cliente(obxecto_a);
 
                obxecto_a.status();
                c.executar();
                obxecto_a.status();
 
                SuxeitReal obxecto_b = new SuxeitoReal("obxecto_b");
                Cliente d = new Cliente(obxecto_b);
 
                d.executar();
        }
 
}

Véxase tamén [editar]

Bibliografía [editar]

  • E. Gamma, R. Helm, R. Johnson and J. Vlissides (1994). Design Patterns: elements of reusable object-oriented software.