Um post do Paulo sobre abstração de DAOs me fez lembrar de escrever sobre este assunto.
Durante muitos anos, eu fui adepto do desacoplamento e da abstração a todo custo. Eram factories com interface, que eram implementadas por uma abstract factory, que achava a própria implementação delas através de properties (sim, isso foi antes dos containers de DI, era uma boa prática pra época) e que sempre produziam interfaces e por aí vai. Os DAOs tinham interfaces e suas factories também e tudo era lindo.
Isso foi há pouco mais de 5 anos e hoje faz uns 2 anos e meio que parei com isso. Por quê? Bem, a análise do que eu havia feito naquela época me mostrou que ter esse princípio como norma geral é uma péssima idéia. Vou tomar como exemplo o casos dos DAOs.
No começo, isso fazia algum sentido, porque a idéia dos DAOs era permitir que você trocasse de banco de dados. Se seu sistema usava só JDBC puro e não havia triggers e afins no banco, no caso da remota possibilidade de trocar de banco, havia alguma vantagem nisso. Agora, quantos de vocês já viram isso acontecer? Mesmo quando acontece, dependendo das diferenças de funcionalidades utilizadas dos dois bancos e da forma como a abstração foi implementada, uma reescrita de tudo acaba sendo necessária. Além disso, nos grande maioria dos casos em que a mudança não ocorre, o quanto isso atrasa o ciclo de desenvolvimento? E aquele monte de interfaces inúteis, que só servem para deixar seu deploy mais lento e seu code completion mais poluído? Fora o fato de fazer os juniors entenderem por que isso é necessário. Obviamente, eu não estou considerando aqui o caso de produtos “genéricos” ou ferramentas que realmente tem que funcionar com mais de um banco desde o primeiro dia e, mesmo assim, estou supondo que o Hibernate ainda não existia.
Quando o Hibernate e seus semelhantes surgiram, aí as coisas passaram a fazer muito menos sentido. O problema principal que era poder usar outros bancos foi coberto. Aí as pessoas começaram a raciocinar: e se eu quiser trocar o Hibernate? Bem, se você quiser fazer isso, provavelmente sua aplicação inteira vai acabar mudando, a menos que você vá mudar para EJB 3 (o que, por sinal, não faz sentido na maioria dos casos). Escondendo o Hibernate você perde acesso a funcionalidades avançadas e outras delas “vazam” pelo código, como o uso de Transfer Objects para evitar a carga lazy de algumas propriedades e coisas do tipo.
O fato é que nos últimos anos todos nós ouvimos que devemos fazer a coisa mais simples que funciona. E os sistemas não funcionariam sem essa parafernalha toda? Então, por que estamos construindo algo de que não sabemos se vamos precisar? Da próxima vez que achar que precisa de interfaces ou abstrair uma implementação, verifique o custo-benefíio antes de sair codificando.