Proxy - Padrão de Projeto com Microsoft .NET C#
Introdução
Padrão de
Projeto ou em inglês Design Patterns, é
uma forma organizada de criar soluções para os problemas recorrentes do dia a
dia de um programador.
1 Porque devo usar Padrão de Projeto
Todos
sabemos que é possível desenvolver software sem utilizar padrão de projeto, e o
fato de usar ou não padrão de projeto não característica um software de
qualidade, padrão de projeto é somente um dos vários detalhes que compõem um
software. Usar padrão de projeto é uma escolha que cabe a cada empresa, existem
casos onde as empresas desenvolvem seus próprios padrões de projetos e suas
framework de trabalho.
O conceito
de padrão de projeto foi criado na década de 70 pelo arquiteto e matemático
Christopher Alexander um australiano que foi um dos principais críticos da
arquitetura moderna. Alexander definiu dois pontos fundamentais para criação de
um padrão, apontando as características e formato básico que um
"objeto" deve ter para ser classificado como padrão.
Características
·
Encapsulamento
·
Generalidade
·
Equilíbrio
·
Abstração
·
Abertura
·
Combinatoriedade
Formato
·
Nome ·
Exemplo ·
Contexto ·
Problema ·
Solução Agora
podemos entender o que existe em comum no trabalho de Alexander com o
desenvolvimento de software, podemos compreender o que é necessário para
criação de um padrão. Agora vamos entender quais os benefícios e vantagens que
ao desenvolver software utilizando padrões de projetos a empresa pode ganhar. Alguns acontecimentos são comuns no dia a dia
das fabricas de software, tais como: giro de funcionários; mudanças no sistema
em produção; correção de erros; implementação de novos recursos; customizações
especificas e etc. Os padrões de projetos tem como objetivo facilitar o
desenvolvimento de software com a reutilização de soluções já implementadas,
não estamos falando de reutilização de código e sim em um desenvolvimento
padronizado com: vocabulário unificado; facilidade para comunicação e leitura
do código; documentação padronizada; compreensão rápida do código para novos e
antigos integrantes do time de TI. 2. Proxy - Padrão de Projeto O padrão
Proxy tem como objetivo proporcionar um espaço reservado para outro objeto
controlar o acesso a ele. A classe proxy teoricamente pode se conectar a
qualquer objeto, ou seja, normalmente quando existe uma instância grande/complexa
pode-se criar vários proxies, todos contendo uma única referencia. 2.1 Classificação Padrão de
projeto descreve 23 modelos de desenho, porem cabe ressaltar que existem
centenas de padrões. No famoso livro Design
Patterns dos autores Gamma, Helm, Johnson e Vlissides é apresentado 23
padrões de projeto, documentados e já conhecidos no mundo do desenvolvimento de
software. É importante saber que isso não significa que esses padrões são os mais
uteis para se implementar, sendo assim vale a pena pesquisar padrões de outras
fontes. Esses 23
padrões são divididos em padrões de criação, padrões estruturais e padrões
comportamentais. Vamos explorar os 23 padrões de projeto na serie de artigo
sobre o assunto. O padrão de projeto Proxy está classificado como padrão
estrutural. 3. Implementando padrão Proxy Geralmente
os objetos comuns fazem seu próprio trabalho e oferecem suporte as interfaces públicas
declaradas no objeto. Porem existem casos que essa responsabilidade precisa ser
transferida para um objeto adequado. Isto pode ocorrer em diversos casos, vamos
para alguns exemplos: quando um objeto necessita de um longo tempo para
carregar; quando o programador precisa intercepatar a mensagem do objeto;
quando o processo precisa ser executado em outro computador/servidor e etc.
Nestes casos, um objeto proxy pode assumir a responsabilidade, assim criando
uma instância cliente que aguarda e encaminha solicitações de forma adequada a
um objeto alvo. Com isso
podemos entender o principal objetivo do padrão Proxy, que em resumo é fornecer
uma solução substituta ou espaço reservador para outro objeto controlar a
solicitação. 3.1 Simple Proxy Um objeto
proxy geralmente possui uma interface que é praticamente idêntica à interface
do proxy que ira substituí-lo. O proxy vai realizar seu trabalho
criteriosamente por encaminhamento de solicitações para o objeto subjacente. Um
exemplo prático do proxy refere-se a evitar a utilização inadequada do espaço em
memória. Suponhamos que arquivos/dados em um aplicativo pertencem a tarefas que
inicialmente não serão executadas, sendo assim, precisamos evitar o
carregamento desnecessário de todos os arquivos/dados antes que eles sejam
solicitados, neste caso pode deixar os proxies para os arquivos. Essa atividade
funciona como um espaço reservado para carregar os arquivos requeridos na demanda,
vamos desenvolver um exemplo simples que ilustra essa situação. Figure 1. Diagrama de classes, com representação
gráfica do que vamos desenvolver Abaixo o
código da classe principal, fazendo a chamada a classe que carrega o arquivo solicitado. class Program { static void Main(string[] args) { Arquivo
arq01 = new ArquivoProxy("Arquivo01"); Arquivo
arq02 = new ArquivoProxy("Arquivo02"); Arquivo
arq03 = new ArquivoProxy("Arquivo03"); Console.ReadKey(); } } Interface
para implementação do padrão proxy. interface Arquivo { void
getArquivo(); } Classe que contém o método que será executado
pelo proxy virtual. public class ArquivoReal:Arquivo { private
string NomeDoArquivo; public
ArquivoReal(string _nomedoarquivo) { this.NomeDoArquivo
= _nomedoarquivo; loadArquivo(); } private
void loadArquivo() { Console.WriteLine("Carregando: " + this.NomeDoArquivo); } public void getArquivo() { Console.WriteLine(this.NomeDoArquivo); } } Classe que ilustra uma forma simples de proxy
virtual. A classe abaixo será utilizada para acessar um método remoto. public class ArquivoProxy
: Arquivo { private
string NomeDoArquivo; private
Arquivo vrArquivo; public
ArquivoProxy(string _nomedoarquivo) { this.NomeDoArquivo
= _nomedoarquivo; getArquivo(); } public void getArquivo() { vrArquivo = new ArquivoReal(this.NomeDoArquivo); vrArquivo.getArquivo(); } } Abaixo o
resultado do programa: Carregando: Arquivo01 Arquivo01 Carregando: Arquivo02 Arquivo02 Carregando: Arquivo03 Arquivo03 Este
exemplo ilustra de uma forma simples a implementação do pradrão proxy, porem
ainda não deixa claro a total justificatica para utilizar esse padrão. No
próximo exemplo vamos desenvolver um proxy com chamada remota, justificando os
beneficios em se usar o padrão proxy. 3.2 Remote Proxies Em algumas
situações precisamos chamar um método que está sendo executado em outro
computador, neste caso é interessante encontrar uma maneira de se comunicar com
o objeto remoto sem chamá-lo diretamente. Uma forma de executar essa atividade
seria abrir um socket no servidor remoto e elaborar algum protocolo para
transferir mensagens entre os objetos. Este processo permite passar mensagens
para os objetos remotos como fossem hospedados no servidor local. Existem
objetos bem conhecidos que é capaz de chamar métodos que estão sendo executados
em máquinas remotas. Alguns componentes são: Common Object Request Broker
Architecture (CORBA), Java Remote Method (RMI), Active Server Pages em ASP.NET. 3.3 Exemplo Mão na massa, este exemplo requer os seguintes passos: ·
Internet Information Server (IIS) ·
Relacionar um diretório no disco com um
endereço Uniform Resource Locator (UML) ·
Web services (vamos desenvolver juntos) ·
Criar um proxy para o serviço de web
(vamos criar juntos) Passo 1: Instalar o IIS, caso a ferramenta
ainda não esteja disponível. Passo 2: Criar
um diretório como por exemplo "c:\exemplo" e o diretório onde será
hospedado nossa pagina como por exemplo "c:\exemplo\bin". Execute o
IIS e crie um diretório virtual apontando para pasta "c:\exemplo" e
informe o alias name "exemploproxy". Passo 3:
Vamos criar um Web service using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Services; [WebService(Namespace
= "http://tempuri.org/")] [WebServiceBinding(ConformsTo
= WsiProfiles.BasicProfile1_1)] public class WebService : System.Web.Services.WebService { public WebService () { } [WebMethod] public string
OlaMundo() { return "Web service. Olá
mundo"; } } Passo 4: Teste!
Execute o projeto e verifique se o resultado está parecido com a ilustração
abaixo. Passo 5: Capturar
a interface do serviço de Web service disponível. Com o Web Services
Description Language (WSDL), este recurso faz parte do conteúdo disponível no
kit de ferramentas do .NET framework. Execute o seguinte comando: c:\exemplo>wsdl
http://localhost/exemplo/WebService.asmx ?wsdl Após
executar esse comando o arquivo Webservice.cs seré criado contendo o proxy que
os clientes porem utilizar para chamar o serviço. Podemos traduzir essa
processo da seguinte forma. O arquivo criado irá conter uma chamada ao método
OlaMundo() que vai operar de forma diferente da OlaMundo() implementada no
WebService.asmx. Quando o método for solicitado será criado um pedido no
formato texto correspondente ao protocolo Simples Object Access Protocol
(SOAP), passando essa mensagem para o servidor IIS que envia a resposta para o
cliente que está aguardando. Figure 2. Ilustração da utilização do Proxy com
protocolo SOAP Passo 6: No
ultimo passo, basta então criar o cliente que irá utilizar o proxy. Crie um novo
projeto, adicione a ele a classe WebService.cs (criada com o comando wsdl) e
implemente o código abaixo no método Main(). class MostraCliente { static void Main() { // Metodo
disponível no arquivo webservice.cs, //criado pelo
comando wsdl OlaMundo _olamundo = new
WebService.OlaMundo(); } } Um dos
benefícios do ASP.NET é que a framework permite que aplicativo cliente possa
interagir com um objeto local, no caso o proxy para o objeto remoto. Com isso
os desenvolvedores dificilmente precisam estar ciente das chamadas remotas que
acontecem, sendo que o ASP.NET fornece um meio de comunicação e isola o
servidor do cliente. Conclusão O proxy na
computação distribuída é um avanço permanente em computação orientada a objeto.
É recomendado então implementar o padrão proxy, quando existe a necessidade de
estabelecer um objeto reservado que controla/gerencia o acesso a outra tarefa.
O objeto proxy tem a habilidade de isolar o cliente a partir de uma mudança no
estado do objeto, como vimos nos exemplos acima. O padrão
proxy tem alguns problema, podemos perceber que o objeto depende de uma ligação
entre o espaço reservado e o objeto em proxy. Geralmente na prática, o uso de
proxy pode trazer benefícios, porem os projetos alternativos muitas vezes
oferecem outras soluções mais estáveis. O uso de proxy é recomendado para
computação remota, onde realmente justifica o uso do mesmo. Ao invés de depender
de algum outro protocolo ou sistema de computação distribuída. Como o ASP.NET
estabelece comunicação com objetos remotos em uma chamada de método normal,
este recurso permite que o cliente se comunique com outro objeto utilizando o
proxy como referencia, caracterizando como se o acesso fosse local. Comunicado Importante Espero que
tenham gostado do conteúdo explorado neste artigo, caso exista interesse em conhecer
um pouco mais sobre padrão de projeto proxy, como por exemplo: como utilizar
proxy no acesso a dados. Informe seu interesse usando o recurso de "comentários"
neste artigo ou qualquer dúvida relacionada ao conteúdo do mesmo. Referência Eric T Freeman; Elisabeth Robson; Bert Bates; Kathy Sierra. Head First Design Patterns, O'Reilly
Media, Inc 2004. Steven John Metsker. Design
Patterns in C#, Addison-Wesley Professional, 2004. ERL, Thomas. SOA: Design Patterns.
Vancouver: Prentice Hall, 2008. 500 p.