Files
2023-10-28 11:41:01 +03:00

167 lines
4.9 KiB
Markdown

---
title: Proxy
category: Structural
language: pt
tag:
- Gang Of Four
- Decoupling
---
## Também conhecido como
Surrogate
## Propósito
Fornecer um substituto para controlar o acesso ao objeto original
## Explicação
Exemplo de mundo real
> Imagine uma torre onde magos locais vão estudar os seus feitiços. A torre de marfim consegue ser
> acedida através de uma proxy que garante que apenas os três primeiros magos podem entrar. Aqui a proxy
> representa a funcionalidade da torre e adiciona controlo de acesso a ela.
Em palavras simples
> Usando um padrão proxy, a classe representa a funcionalidade de uma outra classe.
Wikipedia diz
> Uma proxy, na sua forma mais genérica, é uma classe a funcionar como interface para algo.
> Uma proxy é um wrapper ou objeto agente que está a ser chamado pelo cliente para aceder ao verdadeiro
> objeto por detrás das cortinas. O uso de uma proxy pode ser apenas redirecionar para o objeto real, ou
> pode fornecer lógica adicional. Numa proxy, funcionalidade extra também pode ser fornecida, por exemplo apanhar
> operações no objeto real que gastam muitos recursos, ou verificar precondições antes
> das operações no objeto real serem invocadas.
**Exemplos de programação**
Usando a nossa torre de magos do exemplo acima. Primeiro temos a interface `WizardTower` e a classe
`IvoryTower`.
```java
public interface WizardTower {
void enter(Wizard wizard);
}
@Slf4j
public class IvoryTower implements WizardTower {
public void enter(Wizard wizard) {
LOGGER.info("{} enters the tower.", wizard);
}
}
```
Depois uma simples classe `Wizard`.
```java
public class Wizard {
private final String name;
public Wizard(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
```
Depois temos a `WizardTowerProxy` para adicionar controlo à `WizardTower`.
```java
@Slf4j
public class WizardTowerProxy implements WizardTower {
private static final int NUM_WIZARDS_ALLOWED = 3;
private int numWizards;
private final WizardTower tower;
public WizardTowerProxy(WizardTower tower) {
this.tower = tower;
}
@Override
public void enter(Wizard wizard) {
if (numWizards < NUM_WIZARDS_ALLOWED) {
tower.enter(wizard);
numWizards++;
} else {
LOGGER.info("{} is not allowed to enter!", wizard);
}
}
}
```
E aqui está a torre a entrar em cenário.
```java
var proxy = new WizardTowerProxy(new IvoryTower());
proxy.enter(new Wizard("Red wizard"));
proxy.enter(new Wizard("White wizard"));
proxy.enter(new Wizard("Black wizard"));
proxy.enter(new Wizard("Green wizard"));
proxy.enter(new Wizard("Brown wizard"));
```
Saída do programa:
```
Red wizard enters the tower.
White wizard enters the tower.
Black wizard enters the tower.
Green wizard is not allowed to enter!
Brown wizard is not allowed to enter!
```
## Diagrama de classes
![alt text](./etc/proxy.urm.png "Diagrama de classes do padrão proxy")
## Aplicabilidade
O proxy é aplicável quando existe a necessidade de uma referência a um objeto mais versátil ou sofisticada em vez de um simples ponteiro. Aqui estão várias situações comuns em que o padrão Proxy é aplicável.
* Proxy remoto dá uma representação local de um objeto num espaço de endereçamento diferente.
* Proxy virtual cria objetos dispendiosos quando requisitado.
* Proxy de proteção controla o acesso ao objeto original. Proxies de proteção são úteis quando objetos deviam ter direitos de acesso diferentes.
Tipicamente, o padrão proxy é usado para
* Controlar acesso a um outro objeto
* Inicialização preguiçosa
* Implementar um registro de eventos (logging)
* Facilitar a conexão com a rede
* Contar o número de referências para um objeto
## Tutoriais
* [Controlar acesso com um padrão Proxy](http://java-design-patterns.com/blog/controlling-access-with-proxy-pattern/)
## Usos conhecidos
* [java.lang.reflect.Proxy](http://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Proxy.html)
* [Apache Commons Proxy](https://commons.apache.org/proper/commons-proxy/)
* Frameworks para Mocking [Mockito](https://site.mockito.org/),
[Powermock](https://powermock.github.io/), [EasyMock](https://easymock.org/)
* UIKit's da Apple [UIAppearance](https://developer.apple.com/documentation/uikit/uiappearance)
## Padrões relacionados
* [Ambassador](https://java-design-patterns.com/patterns/ambassador/)
## Créditos
* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59)
* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b)