terça-feira, 9 de agosto de 2005

Dynamic Proxy

Dynamic Proxy é uma funcionalidade fornecida pela plataforma Java que abre a potenciais inovadores caminhos na programação por objectos. Resumidamente isto permite instanciar uma classe, em que só definimos a sua Interface em runtime ou então permite a facilidade de interceptar todas as chamadas aos métodos do objecto, com a finalidade de lhe acrescentar novas funcionalidades de uma forma transparente.
Através de um exemplo de demonstração dá para começar a deslumbrar as suas potencialidades. Este exemplo foi adaptado deste artigo que serviu-me de introdução ao tema. Neste exercicio pretende-se acrescentar uma mensagem de log, a cada um dos método das classes Elevator e Explorer que já foram desenvolvidas e não podem ser mais alteradas e recompiladas.
Numa primeira solução (ver classe TestSpecificLogger.java), foram criados duaswrapper classes: ExplorerLogger e ElevatorLogger, que imprimem uma mensagem “Método method() chamado” e depois reencaminham a chamada do método, respectivamente para a sua superclasse ou para o seu delegate.
No exemplo TestGenericLogger.java, só foi necessário criar uma classe genérica Logger. Esta contem uma referencia para um Object, que tanto pode ser Explorer ou Elevator. É definido um único método que é sempre executado automaticamente sempre que se chama qualquer método da sua futura interface. Ao ser chamado esse método, imprime uma mensagem a indicar qual o método realmente chamado, e reencaminha esse pedido para o seu delegate.
Ao ser instanciado este Logger, é lhe atribuído em runtime a Interface implementada pelo objecto contido por si. Neste caso IExplorer ou IElevator. A aplicação cliente do Logger, poderá chamar os métodos dessa interface.
Assim em vez de desenvolver uma classe XXXLogger para cada classe XXX, e implementar a escrita da mensagem para cada método, só foi preciso escrever uma classe Logger, e só escrever num método a mensagem.
Existem muitas potencialidade para este padrão de software. Se pretender aprofundar o conhecimento com mais exemplos de aplicação deste mecanismo, recomendo a leitura dos seguintes artigos:
  • OnJava - Memoization in Java Using Dynamic Proxy Classes: Exemplo de utilização desta funcionalidade para implementar um mecanismo de cachegenérico, aplicado a "qualquer" classe. É um artigo bem escrito e que detalha passo a passo a diferentes estratégias de implementação deste mecanismo.
  • JavaWorld - Explore the Dynamic Proxy API: Exemplos de proxys para controlo de acesso a classes e métodos, conceito de Views sobre objectos e adicionar strong typing a tipos de dados abstractos.
  • Java Dynamic Proxies - One Step from Aspect-oriented Programming:Exemplo de proxys para logging, transações e remotos. Comparação o novo paradigma de programação AOP.
  • GenericListener: Classe desenvolvida pela SUN, que permite uma melhor estruturação de GUIs complexos ao nível de tratamento de eventos. Para melhor compreender a sua utilidade, recomendo a leitura deste artigo que exemplifica diferentes estratégias de implementação de event listeners
  • Absolute Singleton: É possivel quebrar o conceito de Singleton de uma classe em Java com a utilização de ClassLoaders próprios. Este artigo explica o porquê e voltar a forçar a existência de uma única instancia da classe.
  • Java Reflection in Action: Este livro contém um capítulo dedicado a este assunto. Poderá encontrar um exemplo de utilização deste mecanismo comostub para classes que representam serviços remotos e também como testes unitários.
Quem conhecer mais aplicações deste conceito, ficava agradecido pela sua divulgação. Escrevam-me.