C# - Padrões Estruturais Gof - Proxy
Neste artigo vou apresentar o padrão estrutural Gof Proxy. |
O padrão Proxy é um padrão de projeto estrutural que fornece um objeto que atua como um substituto para um objeto de serviço real usado por um cliente para controlar o acesso a ele.
Este padrão
permite
encapsular a instância de uma classe complexa usando uma instância de outra
classe que possui a mesma interface. Com isso podemos controlar a criação e
acesso aos objetos complexos usando objetos mais simples.
Proxy significa 'no lugar de' ou 'em nome de'.
Assim o Proxy
recebe solicitações do cliente, realiza alguma tarefa (controle de acesso,
armazenamento em cache etc.) e passa a solicitação para um objeto de
serviço.
Este padrão é muito usado quando precisamos criar um invólucro para ocultar a
complexidade do objeto principal do cliente.
Exemplo de uso do padrão Proxy
Vejamos um exemplo
simples e prático do mundo real para entender o Proxy.
Quando emitimos um cheque ou usamos o cartão de crédito em uma compra ou
pagamento :
Neste contexto o cheque e/ou o cartão de crédito atuam como um
Proxy da nossa
conta bancária :
Ou seja, um cheque ou cartão de credito ou ordem de pagamento é uma procuração para fundos em uma conta.
Assim podemos usar o cheque/cartão no lugar do dinheiro que esta na conta e eles
fornecem uma maneira de acessar o dinheiro na conta quando isso for preciso.
É exatamente assim que o padrão Proxy faz: Controla e gerencia o acesso ao
objeto que ele esta representando ou substituindo.
Tipos de Proxy
Temos 3 tipos
principais de Proxy
1 - Proxy Virtual : Um proxy virtual é
um espaço reservado para objetos que consomem muitos recursos para serem criados
Neste contexto o objeto real só é criado quando um cliente primeiro solicita ou
acessa o objeto.
2 - Proxy Remoto: Um proxy remoto
fornece representação local para um objeto que reside em um espaço de endereço
diferente. O conceito de proxy remoto é semelhante ao conceito de uso de
serviços da web em que o cliente deve acessar o recurso remoto em outra rede,
usando a instância da classe proxy.
3 - Proxy de proteção: Controla o
acesso a um objeto principal. Podemos assim criar um proxy seguro de um recurso
adicionando algum tipo de autenticação para o código do cliente fornecer. O
objeto proxy verifica se o chamador tem as permissões de acesso necessárias
antes de encaminhar a solicitação.
Isso é conhecido como Proxy de proteção, pois os recursos são protegidos pelo proxy e o código do cliente deve passar pelo processo de autenticação.
Diagrama UML
O diagrama UML do padrão Proxy segundo o Gof apresenta os seguintes participantes
1- Subject : Define a interface comum para
RealSubject e Proxy para que um Proxy possa ser
usado em qualquer lugar em que um RealSubject for esperado.
2- Proxy : Mantém uma referência que permite ao proxy acessar RealSubject. O proxy pode referir-se a um Subject se as interfaces RealSubject e Subject forem iguais. Fornece uma interface idêntica à do Subject para que um proxy possa ser substituído pelo RealSubject.
3- RealSubjcet : Define o objeto real que o Proxy representa.
Embora o padrão Proxy não seja muito usado nas aplicações C#, ele ainda é muito útil em alguns casos especiais. Como exemplo ele pode ser muito útil quando você deseja adicionar alguns comportamentos adicionais a um objeto de alguma classe existente sem alterar o código cliente.
Quando podemos usar o padrão Proxy
podemos usar o
padrão Proxy :
- Quando precisarmos criar objetos sob demanda quando suas operações forem
solicitadas;
- Quando temos uma classe que com dados sensíveis (que deveriam ser de acesso
restrito) e é necessário fornecer o controle de acesso para o objeto
original;
- Quando temos que usar classes onde a criação dos objetos é muito demorada e
consome muitos recursos;
- Quando devemos permitir o acesso a um objeto remoto usando um objeto local (referenciando
o objeto remoto);
- Para adicionar um recurso thread-safe a uma classe existente sem alterar o código de classe existente;
- Fornecer
interfaces para recursos remotos, como serviço da web ou recursos REST;
Vantagens do padrão Proxy
Como vantagens deste padrão temos que :
- Evita a
duplicação de objetos grandes e que usam muita memória. E Isso aumenta o
desempenho da aplicação através do uso de cache para acessar os objetos mais
pesados;
- O Proxy Remoto também garante a segurança instalando o proxy de código local (stub)
na máquina do cliente e acessando o servidor com a ajuda do código remoto
- O Proxy Virtual
nos ajuda a adiar a criação do Real Subject até que seja totalmente
necessário;
- O Proxy Remoto ajuda a fazer o trabalho pesado de empacotar e desembrulhar,
fazendo chamadas remotas para o objeto real para o cliente. O cliente não sabe
onde reside o Sujeito Real;
- O Proxy Cache ajuda a melhorar o desempenho do aplicativo, fornecendo os
recursos acessados com frequência.
- O Proxy de Proteção nos permite adicionar uma camada de segurança adicional
para evitar o acesso não autorizado aos recursos;
Desvantagem
Como desvantagens
deste padrão temos que :
- Ele introduz outra camada de abstração que às vezes pode ser um problema se o
código do RealSubject for acessado por alguns dos clientes diretamente e
alguns deles puderem acessar as classes Proxy. Isso pode causar
comportamentos díspares.
- Outra desvantagem é que em certos cenários a sua implementação pode ser
complexa;
Aplicação prática do padrão Proxy
Vejamos a seguir
um exemplo pratico de implementação do padrão Proxy.
Neste exemplo o objetivo é controlar o acesso a uma pasta compartilhada a
usuários a área de TI de uma empresa.
Vamos supor que em uma empresa temos um computador compartilhado que possui uma
pasta compartilhada que contem informações confidenciais.
Este computador pode ser acessado pelos usuários que são funcionários da área de
TI da empresa. Temos 3 perfis de usuários que acessar o computador compartilhado
e podem acessar a pasta compartilhada :
1- Ceo
2- Programador
3- Usuario
Agora, existe uma restrição de acesso onde somente o perfil
Ceo pode acessar as informações confidenciais.
Dessa forma teremos que proteger o acesso à pasta compartilhada no computador.
Para fazer isso vamos implementar o padrão Proxy e
criar uma pasta Proxy onde iremos verificar o perfil de quem esta
acessando o computador. Se o perfil for igual a Ceo
então o usuário poderá acessar o conteúdo caso contrario terá o acesso negado.
Levando em conta este cenário e estas considerações vamos implementar o padrão Proxy usando uma aplicação Console .NET Core (.NET 5.0) criada no VS 2019 Community.
A seguir temos o diagrama de classes obtido a partir do VS 2019 na implementação do padrão:
1 - IPastaCompartilhada: Representa o Subject e é uma interface que define os membros que serão implementados pelas classes RealSubject e Proxy para que o Proxy possa ser usado em qualquer lugar em que o RealSubject seja esperado;
2 - PastaCompartilhada: Representa RealSubject e é uma classe concreta que queremos usar de forma mais eficiente usando a classe proxy.
3- PastaCompartilhadaProxy : Representa o Proxy e é uma classe concreta que contém uma referência à classe RealSubject e pode acessar os membros da classe RealSubject conforme necessário. Ela deve implementar a mesma interface de RealSubject para que os dois possam ser usados de forma intercambiável.
4- Program - A classe Program representa o Client e usa a implementação definida;
A seguir temos o código usado na implementação:
A classe Funcionario é definida para ser usada na implementação do padrão e possui o seguinte código:
public class Funcionario { public string Nome { get; set; } public string Senha { get; set; } public string Perfil { get; set; } public Funcionario(string nome, string senha, string perfil) { Nome = nome; Senha = senha; Perfil = perfil; } } |
1- Interface IPastaCompartilhada (Subject)
public interface IPastaCompartilhada { void OperacaoDeLeituraGravacao(); } |
2- Classe PastaCompartilhada (RealSubject)
public class PastaCompartilhada : IPastaCompartilhada { public void OperacaoDeLeituraGravacao() { //define operação a ser realizada na pasta Real Console.WriteLine("### Operação de Leitura e Escrita " + "na pasta compartilhada ###"); } } |
3- Classe PastaCompartilhadaProxy (Proxy)
using System;
namespace Proxy1 |
4- Program
|
A execução do projeto irá apresentar o seguinte resultado:
Com isso temos uma
implementação do padrão Proxy onde o tipo de proxy usado é o
Proxy de Proteção.
Com base no que foi apresentando podemos notar que o padrão Proxy e o padrão
Adapter possuem estruturas semelhantes mas
finalidades diferentes. Ambos descrevem como fornecer um nível de
indireção a outro objeto, e as implementações mantêm uma referência ao objeto
para o qual encaminham solicitações. O Adapter
fornece uma interface diferente para seu sujeito. O Proxy
fornece a mesma interface.
Pegue o código
do projeto aqui :
Proxy1.zip
"(Disse Jesus) Eu sou a videira verdadeira, e meu Pai
é o agricultor. Todo ramo que, estando em mim, não dá fruto, ele corta; e
todo que dá fruto ele poda, para que dê mais fruto ainda. "
Joao 15:1
Referências:
NET - Unit of Work - Padrão Unidade de ...
NET - O padrão de projeto Decorator
NET - Padrão de Projeto Builder
C# - O Padrão Strategy (revisitado)
NET - O padrão de projeto Command
NET - Apresentando o padrão Repository