BOLOVO — Você conhece esse modelo de arquitetura de software? 👌
Antes de começar, preciso te dizer que pode se sentir a vontade de corrigir até mesmos erros de escrita, e deixar sua opnião, vou achar ótimo saber 😂
Business Object, Layer Object, Value Object são os padrões que compõem este padrão arquitetural, surgiu para suprir uma necessidade em meados de 2004, mas hoje, temos formas melhores de resolver o mesmo problema, uma delas é conhecida como “Rails Way” que eu aprendi como sendo a verdadeira Orientação a Objetos programando em SmallTalk.
Business Object — Camada de negócios, onde você vai implementar suas regras de negócio :D
Layer Object — Objetos de camadas, que separam as camadas de sua aplicação
Value Object — Ou também conhecido como Transfer Object, é um objeto sem comportamento, é um POJO (Plain Old Java Object) é a denominação que se dá para um objeto sem comportamento, serve apenas de estrutura de dados.
Alguns dizem que ao utilizar BOLOVO, “O Código já nasce legado, já nasce com problemas de Orientação a Objetos”.
Nos livros sobre JEE Patterns de meados de 2004/2008 você vai encontrar claramente referências interessantes sobre este modelo arquitetural, mas sobre outros nomes, como: Transfer Object, Business Object, Data Access Object, há outros nomes que referenciam o mesmo conceito, inclusive o livro Core J2EE Patterns é dividido em Presentation Tier, Business Tier, Integration Tier 😉.
BOLOVO trás a tona o modelo anêmico (sempre os vejo juntos), que é outro termo muito utilizado na prática, e muitofalado pelos “grandes intelectuais” da literatura como algo a ser evitado.
Muitos o adoram, e até o defendem por sua simplicidade. Porém, este modelo de arquitetura em três camadas trás uma série de conflitos e problemas a aplicação, produtividade e manutenibilidade. Outros modelos também trazem, é interessante sabermos como isto acontece neste e outros modelos, esta visão nos permite escolher melhor como escrever nossas aplicações 😉 .
É por este motivo que gravei um vídeo, na tentativa de mostrar, ilustrar e exemplificar tudo isto de forma simples e com código, para que possamos trocar aquela idéia monstra 😉
Arquitetura em camadas.🤔
Quem nunca viu o sistema dividido em 3 camadas diferentes, a camada de modelo, a camada de regras de negócio, e a camada de acesso a dados?
A idéia por de trás deste modelo, é separar e permitir manutenções mais fáceis, porém oque acontece na prática é o contrário, é comum vermos imensas classes com as regras de negócios repetidas e espalhadas. O código abaixo, é simples, fácil de entender não é? Mas há algo que ele esconde, imediatamente ao ver algo assim penso, que todos os lugares no sistema, incluindo no teste automatizado este if irá se repetir.
Provavelmente alguns irão dizer que não há problema, é um simples if, com apenas uma clausula, e esta afirmação está correta, mas, há características neste código que ele esconde:
- Sempre que alguém precisar saber se existe o price em product, é necessário digitar !=, correndo o risco de digitar erroneamente ==, centralizar a clausula do if em um único ponto, o risco e a repetição;
- Indica que o autor, dá preferência a um estilo de código que data de meados de 2002/2004, época em que utilizávamos o Java 1.4 (lançado em 2000), quando trabalhavamos com EJB 1, também era uma época que tínhamos problemas para serializar e trafegar objetos entre computadores, também tínhamos problemas para criarmos nossas classes O.O. sem criar uma dependência forte com os frameworks. Posso estar errado, mas hoje temos meios melhores;
- Indica que a classe Product possuí métodos de acesso ao atributo desnecessariamente, furando a regra de encapsulamento da O.O.
- Se existe métodos de acesso aos atributos, criados indiscriminadamente (gets/sets), isto indica que há objetos instanciados e sendo utilizados de forma inconsistente;
- Se há objetos sendo criados de forma inconsistente, provavelmente há construtores que permitem criar o objeto com dados inválidos ou faltando dados;
- Indica que o sistema utiliza o modelo anêmico, que nos livros de DDD (Domain Drive Design), TDD (Test Drive Design), Clean Arquitecture, recomendam fortemente evitar;
- É difícil evoluir isto, você precisará varrer todo o sistema buscando todos os ifs iguais caso tenha de altera-la.
Modelo Anêmico 🤔
Martin Fowler tem um texto só sobre modelos anêmicos no seu site
“O Phillip Calçado aborda esse tema, chamando essas classes de classes fantoches (puppets). Uma classe fantoche é a que não possui responsabilidade alguma, a não ser carregar um punhado de atributos! Onde está a orientação a objetos? Uma grande quantidade de classes fantoches são geradas quando fazemos Value Objects, entidades do hibernate, entre outros.” — Paulo Silveira
Abaixo você vê o mesmo código, mas agora sem todo os problemas listados acima, dando a Product o comportamento a ELE saber se ELE tem a informação que pertence a ELE. Este código evita erro digitação no sinal da clausula if, permite remover o getPrice, encapsula a validação, da comportamento a classe que de fato é dele, facilita alteração afinal há apenas um ponto para alterar, e ainda viabiliza teste unitário.
A grande maioria dos gets e sets nunca serão utilizados, poderiam ser substituídos por métodos de negócio (com comportamento). Estamos jogando fora todos os benefícios que a orientação a objetos nos dá e ainda reclamando que o código está uma bosta pra manter. O mais surpreendente é quando temos a oportunidade de criar um software novo (green field), repetimos a mesma receita, chegamos ao mesmo resultado, cometendo os mesmos erros. É por isso que temos de aprender outras linguagens, e paradigmas, buscando melhorar e aprender novas formas de desenvolver software.
“Insanity is doing the same thing over and over again but expecting different results” (“Loucura é continuar fazendo a mesma coisa e esperar resultados diferentes”) frequentemente atribuída a Albert Einstein.
Quer saber mais sobre qualidade de código? Que ler algo diferente sobre code review.
Conclusões 🤓
Nem sempre é possível fugir 100% do modelo anêmico, do modelo BOLOVO, mas sabendo que ele existe, podemos buscar formas melhores de desenvolver nossos softwares, simplificando, diminuindo a complexidade, viabilizando testes unitários.
É possível, utilizar o modelo rico, termos entidades com comportamento, e ainda assim, dividir nossa aplicação utilizado a arquitetura em camadas. Isto inclusive vai trazer o SOLID de maneira evidente em seu código.
Há muitos frameworks opinativos, estes impõem uma forma de escrever código que muitas vezes te obriga a abrir mão da Orientação a Objetos.
Quando você possuí entidades persistentes, que não possuí comportamento, que são apenas estrutura de dados, muito provavelmente você está programando no modelo Anêmico, utilizando Arquitetura BOLOVO.
Leitura recomendada 🤓
Referências
http://www.corej2eepatterns.com/
https://www.oracle.com/technetwork/java/catalog-137601.html
https://stackabuse.com/java-j2ee-design-patterns/
https://guides.rubyonrails.org/active_record_basics.html