Proxy (padrón de deseño)

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

Motivación editar

Para explicar a motivación do uso deste padrón vexamos un exemplo onde a súa aplicación sería a solución máis 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 ao 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 padrón proxy necesita dunha forma de referencia a un obxecto máis flexible que un punteiro. Dependendo da función que se desexe realizar con dita referencia pódense distinguir diferentes tipos de proxies:

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

Estrutura editar

 
Estrutura 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)

Define 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óns 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. Addison-Wesley.