Aplicação do Design Pattern: Factory
Depois de falarmos do Singleton, está na hora de falarmos de outro padrão de projeto, o Factory. O Factory é mais difícil de entender do que o Singleton. Mais do que isso, mais difícil de mostrar alguma aplicação prática.
Nesse post eu mostrarei as duas coisas, explicar o funcionamento do Factory, bem como sua aplicação.
Rápida Explicação …
De uma maneira bem simples, o Factory é um padrão que nada mais é do que uma classe geradora de objetos, onde a decisão de qual classe o objeto será é feita pela classe “geradora”.
Onde eu apliquei o Factory em ABAP?
Projeto Code Coaching
Estamos trabalhando num projeto open source chamado Code Coaching que está sendo desenvolvido sob a iniciativa do ABAP101 Open Source.
O objetivo do projeto é construir uma aplicação ABAP onde o Programador e Coordenador possam se comunicar pelo próprio programa ABAP.
Veja esse exemplo. Esse trecho de código faz parte de outro projeto em que estávamos envolvidos. Eu queria passar instruções para a implementação de uma classe interface específica. Então ao invés de passar instruções por e-mail, eu resolvi colocar alguns comentários dentro do próprio código. Daí para evoluir para uma proto-markup-language foi um pulo (lembre-se, meu sangue é de programador, minha tendência é resolver tudo com um programa de computador).
Existem algumas linhas de comentários que são iniciadas por *@. Essas linhas contêm uma espécie de código que dá um significado especial às linhas comentadas logo na sequência. Continuando na linha do *@ encontramos a seguinte instrução: “jack:task”. Isso significa que os comentários logo abaixo dessa linha, trata-se de uma tarefa designada para o programador chamado Jack.
Sendo assim, o programador pode facilmente fazer uma busca no programa pelo seu nome e descobrir todos os pontos que possuam algum comentário para ele. Para facilitar eu automatizei essa busca em um programa que lê o programa e extrai todos os pontos onde a linha começa com *@ e gera um relatório, como o mostrado abaixo.
Esse programa é apenas um protótipo e como tal serve apenas para apresentar e testar a ideia central do projeto. O projeto final contemplará muitas outras funcionalidades bem como outros comandos, muito além do task. É nesse ponto que o factory será usado.
O que o Factory Significa para o Code Coaching?
No protótipo do programa Code Coaching, ele consegue interpretar apenas o comando task, mas já no primeiro release, estamos planejando expandir para pelo menos três outros comandos além do task, question, answer e comment.
Para fazer a interpretação desses comandos, o programa relatório contará com um diagrama de classes semelhante ao apresentado abaixo:
Cada comando é representado por uma classe. Abaixo você verá mais um programa de teste de conceito, este usando o factory para interpretar um comando entrado pelo usuário.
Implementando o Factory em ABAP
Vamos para mais um programa que simula o interpretador que usaremos no Code Coaching. Trata-se de um programa bem simples, com um parâmetro que é o nome do comando. Se o comando existe, ele mostra o texto que está na classe correspondente ao comando, caso contrário mostra uma mensagem de erro.
Programa ZABAP101_FACTORY_PATTERN completo.
A classe LCL_COMMAND é responsável por decidir de qual classe o objeto deve ser criado. Se ocorrer um erro na criação, ou seja, se a classe que estamos querendo criar o objeto não exista, uma exceção é lançada e tratada como um erro de sintaxe.
Repare que eu monto o nome da classe de acordo com o nome do comando entrado pelo usuário no parâmetro do programa. Ou seja, para esse caso, a classe do comando precisa seguir a seguinte nomenclatura: LCL_<comando>, caso contrário haverá um erro na criação do objeto daquela classe, pois a classe não existirá.
Os objetos dos comandos são criados no método FACTORY( ), com o seguinte comando:
CREATE OBJECT re_instance TYPE (lv_command).
O tipo do objeto é definido em tempo de execução, de acordo com o valor da variável lv_command. Colocando a variável entre parênteses, o interpretador ABAP entende que o tipo do objeto a ser criado não é lv_command, mas sim o que está no conteúdo da variável entre os parênteses.
Qual a Vantagem?
Por que criei uma classe para cada comando? Porque dessa forma, pode-se adicionar um novo comando de maneira MUITO fácil, apenas criando uma nova classe para o novo comando e herdando da classe LCL_COMMAND.
Todo o resto não será afetado.
(sim, isso cheira polimorfismo).
(sim, isso é genial!!!)
O padrão de projeto Factory pode ser implementado de várias maneiras, essa foi apenas uma delas. Acho sim interessante estudá-lo para ter mais essa ferramenta em sua workbench.
Olha que legal, não sabia que você podia referenciar a classe dentro dela mesmo! Gostei da brincadeira!
(sim, isso cheira ajuda no meu TCC).
Parabéns, ideia muito boa!
Furlan, você bem que poderia deixar os seus códigos todo comentário, ficaria mais fácil de entender e intuitivo os conceitos, tipo linha a linha. Contribuiria ainda mais para o nosso aprendizado!
E mais uma vez, parabéns e muito obrigado!