O cenário típico para aplicação do padrão Proxy aparece quando há algum tipo de restrição para acessar o objeto real, justificando que a criação dele seja postergada até que o objeto seja de fato necessário. Por exemplo, se há necessidade de carregar uma imagem muito grande ou se o objeto tem que ser acessado remotamente ou ainda se o acesso ao objeto depende de o usuário ter ou não permissão para isso. Assim, o objeto que age por procuração tem oportunidade de tomar as providências necessárias para acessar o objeto real e, então, repassar para ele os comandos recebidos.
Quando o cenário envolve o gerenciamento de objetos cuja duplicação é muito dispendiosa (usa muita memória, por exemplo) ou até mesmo impossível, é comum adaptar o padrão Proxy e usá-lo de uma forma mais flexível, misturada como o FlyWeight.
Como exemplo prático, imagine a situação em que você tem diversas estações habilitadas a enviar a Nota Fiscal Eletrônica para o site da Receita Federal mas o Certificado Digital necessário para assinar os documentos está disponível apenas no servidor, sendo que há um objeto publicado remotamente no Servidor que é capaz de realizar a assinatura. Para o programa nas estações, é possível implementar um "proxy" para acessar o objeto do Servidor. Segue um esquema UML mostrando a solução para esse exemplo usando o pattern Proxy:
A nomenclatura para as classes envolvidas na solução típica para o Proxy é a seguinte:
O Subject é uma classe abstrata que apenas introduz o comportamento esperado tanto para o objeto real quanto para seu "Proxy", isto é, a interface desejada para esses objetos. No diagrama, esse é o papel da classe TWSigner.
O Proxy é a classe que age como um substituto para a classe real de objetos. É muito comum, portanto, que ela própria gerencie o ciclo de vida do objeto real, criando-o e destruindo-o no momento apropriado. Por isso, deve armazenar uma referência ao objeto real. O objetivo do Proxy é repassar ao objeto real os comandos solicitados, preparando antes o terreno para que a execução seja feita. Para isso, deve tomar providências tais como realizar conexões remotas, execução de tarefas demoradas ou validação de credenciais do usuário no momento mais oportuno, de forma que isso tudo é feito apenas se for estritamente necessário.
Como o Proxy reproduz fielmente a interface publicada pelo Subject, ele pode, se for necessário, ser substituido pela própria classe real de modo que esta será usada no lugar do Proxy. A classe TWSignerProxy age como Proxy no diagrama acima.
Real Subject é a classe que efetivamente realiza as operações estipuladas pela interface Subject. Esse é o papel exercido pelo TWRemoteSigner no exemplo.
O Client é a parte do programa que faz uso da interface estabelecida pelo Subject. Para ele, é indiferente qual instância está de fato sendo usada, uma vez que tanto o Proxy quanto o RealSubject implementam a interface. Este papel é desempenhado pela classe TWBusinessObj no diagrama do exemplo.
O Proxy é a classe que age como um substituto para a classe real de objetos. É muito comum, portanto, que ela própria gerencie o ciclo de vida do objeto real, criando-o e destruindo-o no momento apropriado. Por isso, deve armazenar uma referência ao objeto real. O objetivo do Proxy é repassar ao objeto real os comandos solicitados, preparando antes o terreno para que a execução seja feita. Para isso, deve tomar providências tais como realizar conexões remotas, execução de tarefas demoradas ou validação de credenciais do usuário no momento mais oportuno, de forma que isso tudo é feito apenas se for estritamente necessário.
Como o Proxy reproduz fielmente a interface publicada pelo Subject, ele pode, se for necessário, ser substituido pela própria classe real de modo que esta será usada no lugar do Proxy. A classe TWSignerProxy age como Proxy no diagrama acima.
Real Subject é a classe que efetivamente realiza as operações estipuladas pela interface Subject. Esse é o papel exercido pelo TWRemoteSigner no exemplo.
O Client é a parte do programa que faz uso da interface estabelecida pelo Subject. Para ele, é indiferente qual instância está de fato sendo usada, uma vez que tanto o Proxy quanto o RealSubject implementam a interface. Este papel é desempenhado pela classe TWBusinessObj no diagrama do exemplo.
Este tipo de abordagem onde as chamadas a funções de um objeto são encapsuladas em outro objeto é parecido com o padrão Adapter. A diferença crucial está no fato que no Adapter a interface das classes envolvidas são diferentes entre os objetos pois o objetivo é permitir que se troque o objeto interno quando há necessidade sem precisar modificar o resto do programa. Já no Proxy, ambos os objetos compartilham a mesma interface, sendo que o objeto externo apenas redireciona as chamadas para o objeto interno.
No próximo post, mostro a criação das classes Delphi para implementar essa solução.
Nenhum comentário :
Postar um comentário
OBS: Os comentários enviados a este Blog são submetidos a moderação. Por isso, eles serão publicados somente após aprovação.
Observação: somente um membro deste blog pode postar um comentário.