Padrões de Projetos - Proxy

De Aulas

Afluentes: Modelos, métodos e técnicas da engenharia de software

Definição

O padrão de projeto Proxy é um padrão estrutural que cria uma classe intermediária, chamada de proxy, para agir como uma "camada de acesso" entre o cliente e o objeto real que ele quer acessar. Esse padrão permite controlar e gerenciar o acesso ao objeto real de diversas maneiras.

Estrutura do Proxy

O padrão Proxy geralmente envolve três elementos principais:

  1. Interface Comum: Uma interface que define as operações que o objeto real e o proxy devem implementar. Isso permite que o cliente trate o proxy e o objeto real da mesma forma.
  2. Objeto Real (ou implementação do objeto): O objeto principal que o cliente quer acessar, onde reside a implementação verdadeira das operações.
  3. Proxy: A classe intermediária que implementa a mesma interface do objeto real e atua como um substituto controlado para ele.

Tipos de Proxy e Aplicações

Existem várias formas de aplicar o Proxy, dependendo da necessidade:

  • Virtual Proxy: Carrega o objeto real sob demanda (lazy loading). Por exemplo, se o objeto real é um recurso pesado, como uma imagem ou um arquivo grande, o proxy pode atrasar a criação até o momento em que ele for realmente necessário.
  • Protection Proxy: Controla o acesso ao objeto real, restringindo operações com base em permissões. Um exemplo seria um sistema de segurança em que o proxy verifica se o usuário tem permissão para acessar o recurso.
  • Remote Proxy: Age como um representante local de um objeto remoto, útil em sistemas distribuídos onde o objeto real está em um servidor distante. Um exemplo disso seria uma chamada de um cliente para um serviço remoto, como em uma aplicação cliente-servidor.
  • Cache Proxy: Guarda resultados de chamadas para evitar repetição de cálculos ou operações pesadas, servindo uma versão cacheada quando apropriado.

Exemplo Simples

Imagine um serviço de banco que permite o acesso ao saldo do cliente:

Banco.java

// Interface comum para o Banco e o Proxy
interface Banco {
    String getSaldo();
}

BancoImpl.java

public class BancoImpl implements Banco {
    private double saldo;

    public BancoImpl() {
        this.saldo = 1000.0; // Saldo fictício
    }

    @Override
    public String getSaldo() {
        return "O saldo é: " + saldo + " reais";
    }
}

BancoProxy.java

class BancoProxy implements Banco {
    private BancoImpl banco;
    private boolean temPermissao;

    public BancoProxy(boolean temPermissao) {
        this.temPermissao = temPermissao;
        this.banco = new BancoImpl();
    }

    @Override
    public String getSaldo() {
        if (temPermissao) {
            return banco.getSaldo();
        } else {
            return "Acesso negado. Você não tem permissão para ver o saldo.";
        }
    }
}

Main.java

public class Main {
    public static void main(String[] args) {
        Banco bancoComPermissao = new BancoProxy(true);
        System.out.println(bancoComPermissao.getSaldo());

        Banco bancoSemPermissao = new BancoProxy(false);
        System.out.println(bancoSemPermissao.getSaldo());
    }
}

Saída Esperada

O saldo é: 1000.0 reais
Acesso negado. Você não tem permissão para ver o saldo.

Vantagens e Desvantagens

Vantagens:

  • Controle de acesso adicional.
  • Melhora no desempenho ao evitar a criação desnecessária de objetos.
  • Segurança, ao restringir o acesso baseado em permissões.

Desvantagens:

  • Adiciona complexidade ao sistema.
  • Pode introduzir latência se mal implementado, especialmente em casos de proxies remotos ou pesados.