Texto escrito em 2015
Sempre me incomodou bastante toda esta história de que Java é uma linguagem verbosa e sistemas feitos nesta são complexos. Então resolvi escrever este post pra mostrar alguns erros cometidos por desenvolvedores que, realmente, tornam não a linguagem verbosa, mas sim seus projetos verdadeiras máquinas "burrocráticas".
Este é um primeiro post sobre alguns erros que encontro: é capaz de surgirem outros em um futuro próximo.
Pra quê interfaces?
Este é um ponto que fica muito claro quando você programa algum tempo em plataformas como Grails, Ruby on Rails ou Node.js e, em seguida, pega um projeto de revitalização de legados feitos em Java. Lemos em diversos livros ou palestras o seguinte princípio:
"Programe para uma interface, não para uma implementação"
O princípio está corretíssimo, mas a pergunta fundamental que o motiva não é feita: pra quê preciso de uma interface? Respondo: para representar uma abstração, ou seja, aquilo que é essencial no serviço e compartilhado por todas as suas diferentes implementações.
Portanto, se só existe uma implementação de uma classe no sistema por que você precisa criar uma interface? Não há o que abstrair daí.
Dica um: crie interfaces apenas se existir mais de uma implementação do serviço cuja funcionalidade você deseja abstrair.
DAOs desnecessários quando se está usando um ORM
É outro erro que encontro com frequência: imagine que seu sistema possua doze classes de domínio, todas elas persistidas contra uma mesma base de dados (relacional ou não). Um padrão comum que observo é a geração abusiva de objetos e classes no sistema:
- Uma interface para representar o DAO para cada entidade.
- A implementação do DAO para aquela interface
- Todos os DAOs são executados contra a mesma base de dados
- O DAO expõe algumas consultas, mas estas em sua esmagadora maioria (quando não todas) são usadas por uma única classe do sistema..
Levando em consideração que o papel do DAO é acessar e escrever dados em um repositório de dados, e existe uma ferramenta chamada ORM, acho interessante levantar sempre algumas perguntas:
- Dentro de um futuro próximo você se vê trocando seu SGBD por alguma tecnologia ou fornecedor completamente diferentes?
- Seu projeto precisa lidar com diferentes tipos de persistência de acordo com o ambiente no qual é implantado?
- Se você usa um ORM (como Hibernate, EclipseLink ou JPA) para todas estas classes de domínio, e todas são persistidas contra o mesmo repositório de dados, realmente preciso ter implementados N DAOs apenas para persistir o estado destas?
- Se só há uma implementação do DAO, preciso realmente de uma interface?
- As consultas expostas por seu DAO são usadas por mais de um componente do sistema?
Minha sugestão aqui é simples: os ORMs já nos oferecem um DAO genérico por padrão (pense no Entity Manager do JPA): tire proveito disto. É exatamente o que Grails faz e, como vejo há quase uma década, funciona muito bem! Nós não escrevemos DAOs em Grails: nossos serviços usam apenas as consultas que realmente precisam e, quando há uma consulta compartilhada, a expomos ao restante do sistema através de uma função.
Se você tem um serviço responsável por gerenciar a lógica de negócio que envolve uma ou mais classes de domínio, e também possuí um ORM que já lida bem com o processo de persistência, pra quê ficar criando DAOs que expõem consultas usadas por um único ponto do sistema para todo o resto?
Solução simples: escreva seu serviço com um conjunto de métodos públicos bem definido que exponha aos clientes do mesmo apenas o que deve ser visto (isto se chama encapsulamento). Se ele precisa interagir com o banco de dados, use este DAO genérico fornecido pelo ORM internamente em seu serviço e evite com isto criar uma série de componentes que apenas irão aumentar a quantidade de código que você precisará gerenciar no futuro.
Concluindo
Neste post expus apenas duas situações que vejo repetidas vezes em projetos Java e que podem facilmente ser evitadas. Entendo perfeitamente o que motiva a ocorrência destes erros: você quer fazer bem feito mas não refletiu a respeito das boas práticas que muito provavelmente lhe foram impostas e não apresentadas.
_ Ah... mas e se no futuro meu sistema precisar de...
_ Bom: se você sabe o que vai ocorrer, você não tem um "e se", mas sim um "vai", então aplique.
_ Mas o futuro é imprevisível, preciso me preparar para ele.
_ Bacana: que então você tenha uma base de código menos complexa pra poder se adaptar mais rápido a ele.
Top comments (0)