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

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

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

Estrutura proxy.

Participantes
-------------

* **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
-------------

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

Consecuencias
-------------

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

```
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
------------

### Bibliografía

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

|  |  |
| --- | --- |
| Control de autoridades | 
* Wd: Q23846
* MAG: 109870207

 |