O que é Modelo Anêmico? E por que fugir dele?

Pensar em design e arquitetura é sem dúvida o grande desafio de um desenvolvedor mais experiente. Todos nós já trabalhamos com linguagens orientadas a objetos há algum tempo, e já tivemos tempo suficiente para perceber que, quando a interação entre as classes do sistema não é clara o suficiente, temos diversos problemas: repetição de código, dificuldade de manutenção, propagação de bugs, e etc.

Por esse motivo, é que tanto ouvimos falar sobre diferentes tipos de arquitetura. E com certeza, o termo mais popular sobre isso é a tal da 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 ideia dessa arquitetura é justamente separar as regras de negócio em um canto, do conjunto dos atributos da entidade em outro, do acesso aos dados. E, com isso, facilitar a manutenção. O código abaixo é um exemplo dessa separação:

// camada de modelo
class NotaFiscal {
  private int numero;
  private double valor;
  private String razaoSocial;
  // getters e setters
}

// camada de regra de negocios
class NotaFiscalBLL {
  public void encerraNota(NotaFiscal nf) {
    nf.setEncerrada(true);
  }
}

// camada de acesso a dados
class NotaFiscalDAO {
  public void insere(NotaFiscal nf) {
    // insert into nota fiscal (...)
  }
}

O problema é que, na prática, acontece exatamente o contrário! Veja, no momento que separamos dados de um lado, e comportamento de outro, voltamos a programar de maneira procedural. Nesse tipo de arquitetura, é comum vermos imensas classes com as regras de negócios repetidas e espalhadas. A consequência disso? Um código dificílimo de ser mantido e evoluído. Tanto é que, hoje, esse tipo de arquitetura, é conhecida por modelo anêmico.

Muita gente já falou sobre isso: o Paulo Silveira comentou dos problemas da criação de getters e setters sem qualquer cuidado, o Martin Fowler tem um texto só sobre modelos anêmicos no seu site, e o Philip Calçado também já brigou bastante com os BOs e VOs (nomes que as pessoas do mundo Java dão aos objetos que guardam as regras de negócio e aos que guardam os dados de uma entidade). É, com certeza, um assunto bem popular na comunidade.

Estamos jogando fora todos os benefícios que a orientação a objetos nos dá! Não preciso defender aqui as vantagens da OO: reutilização de código, polimorfismo, herança, etc.

Mas se os problemas são claros, por quê as pessoas fazem assim? Por vários motivos diferentes.

  • É mais fácil programar de maneira procedural do que de maneira orientada a objetos. Afinal, fazer bom uso de polimorfismo, herança, encapsulamento e abstrações, não é fácil.
  • Tanto a Sun quanto a Microsoft já divulgaram “catálogo de boas práticas”, onde a arquitetura sugerida era parecida com essa. A diferença é que em ambos os textos, a ideia era discutir arquitetura para sistemas distribuídos. Mesmo nesse caso, esse tipo de arquitetura não é a melhor, mas essa discussão fica para um próximo post.
  • Por que, por algum motivo estranho, ter essas camadas dá uma falsa sensação de facilidade de manutenção, afinal “tudo está bem isolado”.

Fuja de modelos anêmicos. Tenha objetos ricos, isto é, objetos que tenham atributos, e métodos que manipulam esses atributos. Faça uso de abstrações, polimorfismo e herança nos momentos que precisar de flexibilidade. Encapsule tudo para que as mudanças sejam facilmente propagáveis e não haja código espalhado.

Como fazer isso? Orientação a objetos… Não há mágica. Onde aprender? Nos diversos cursos que temos qualidade de código no Alura, como Orientação a Objetos, refatoração de código, e TDD.

41 Comentários

  1. Antonio 03/04/2014 at 11:01 #

    Pode adaptar seu exemplo para um modelo não- anêmico?

  2. Wesley Bezerra 03/04/2014 at 11:03 #

    A OO. é tão abstrata que às vezes precisamos de mais maturidade para compreender suas vantagens. Noto isso em projetos grandes e que de uma forma ou de outra sua necessidade de evolução nos mostra problemas e flexibilidades na prática!

  3. Alberto Souza 03/04/2014 at 12:47 #

    Oi Antonio,

    A classe NotaFiscal poderia ter o método encerra() que simplesmente trocaria o estado do atributo encerrada. Dessa forma você não precisaria expor um método setEncerra onde a pessoa, por algum equívoco, poderia passar false :).

  4. Alberto Souza 03/04/2014 at 12:48 #

    Ou seja lá qual fosse o processo dentro de uma nota fiscal para encerrar a mesma 🙂

  5. Marcello Mello 03/04/2014 at 14:30 #

    Olha ja pensei muito sobre isso, usar ou não modelo anemico, aqui na empresa estou justamente trabalhando em cima de um modulo novo de nota fiscal. nesse caso o metodo salvar nota teria que Gravar a Nova no banco de dados e marcar como encerrada, mudar o Estado da classe nota fiscal (ela mesmo) como encerrada, disparar um email, todo esse codigo ficaria dentro da classe NotaFiscal? a propria classe saberia qual classe utilizar para gravar no banco de dados, entao uma lista de notas teria todos esses metodos, e se eu precisar de uma relacao de notas fiscais emitida no periodo de 3 meses a propria classe nota fiscal retornaria uma lista de notas fiscais? por essas e outras perguntas é que eu sempre prefiro trabalhar com o modelo anemimo. Vou a outro exemplo:

    Uma Venda, ao salvar a venda precisa fazer diversas coisas, salvar os itens, as parcelas, movimentar o estoque, contabilizar, gerar titulos a receber, movimento no caixa para as formas de pagamento a vista, cheque para as formas de pagamento via cheque, etc….
    Da forma que voce fala, a Classe Venda faria tudo isso? pode ar um exemplo? por que pra mim fica bem melhor uma Classe VendaBO que faz uma coisa soh da vida, salva uma venda executando subclasses que faz cada uma dessas obrigações, ficando a classe Venda sendo somente as variais dessa venda (aquilo que o usuario digitou na tela).
    Enfim ainda nao estou convencido de como fazer

  6. Mauricio Aniche 03/04/2014 at 15:57 #

    Oi Marcello,

    Geralmente separamos código de domínio de infraestrutura. Então você teria um DAO ou coisa do tipo, responsável pela persistência.

    Se você tem uma regra de negócio que toca diferentes entidades, é comum criar uma classe para encapsular essa regra.

    Sugiro a você a leitura do livro “DDD: Domain Driven Design”, do Eric Evans! Acho que ele vai tirar grande parte das suas dúvidas.

    Um abraço!

  7. Marcello Mello 03/04/2014 at 16:06 #

    Obrigado Mauricio, ja estava com esse livro na fila dos livros para leitura obrigatoria, acho que vou antecipar a leitura dele. Sempre procuro muito na NET sobre esse assunto, sempre vejo teorias mas nunca encontrei exemplo reais, com codigo escrito que funcionem em producao. Vou ver o livro!

    Abraço

  8. Willian Fuertes Batista 04/04/2014 at 07:04 #

    Olha o assunto e muito válido, e também tenho muitas dúvidas. Porém da forma com que foi apresentado me pareceu mais um ad que qualquer outra coisa. Grato M. Aniche pela dica do livro.

  9. Augusto 04/04/2014 at 10:23 #

    Gostaria de ver um projeto modelo, utilizando uma arquitetura não-anêmica, para entender um pouco melhor na prática. Seria possível Meniche?

  10. Antonio 04/04/2014 at 11:50 #

    Encontrei um bom exemplo:
    https://www.link-intersystems.com/bin/view/Blog/Anemic+and+Rich+Domain+Models

  11. Alexandre Aquiles 04/04/2014 at 12:33 #

    Acho importante ressaltar o que o Mauricio Aniche disse no comentário acima:

    “Se você tem uma regra de negócio que toca diferentes entidades, é comum criar uma classe para encapsular essa regra.”

    Entidades, como NotaFiscal e Venda, não são as únicas coisas que de um bom Modelo bem nutrido. O livro DDD indica outros tipos de objetos além de Entidades, como Serviços, Eventos, Agredados, Valores, Repositórios, etc…

    É sugerida também uma arquitetura em 4 camadas: UI, Aplicação, Domínio e Infra. A estratégia de acesso a dados, por exemplo, é parte da Infra. A orquestração entre os diferentes objetos de domínio fica a cargo da Aplicação. Gosto de pensar que as camadas são módulos (ou jars), isolados entre si por interfaces e, claro, a de cima dependendo apenas da de baixo.

    Também há a ideia de Contextos com diferentes Modelos. Provavelmente, uma aplicação de vendas vai unir vários contextos.

    O Daniel Cukier fez um teatro sobre DDD no Agile Brazil 2013 que revelou os problemas que o DDD quer resolver e como aplicá-lo. Há uma gravação de uma outra encenação dessa peça:
    http://www.agileandart.com/portfolio/ddd-domain-driven-design-teatro/

    ___

    Recentemente, foi lançado o livro “Implementing DDD” que aparenta ser bastante promissor. Não li ainda, mas parece que é um guia para a adoção fluente de DDD.

    http://vaughnvernon.co/?page_id=168

    ___

    Boa parte dos exemplos são curtos e, por isso, não chegam ao cerne da questão.

    O exemplo do livro DDD, que é sobre o domínio de logística de navios, está disponível em:
    http://dddsample.sourceforge.net/

    O autor do “Implementing DDD” disponibilizou os exemplos do livro no Github:
    https://github.com/VaughnVernon/IDDD_Samples

  12. Mauricio Aniche 04/04/2014 at 12:56 #

    Oi Augusto,

    Um exemplo pequeno, mas interessante, é o nosso AgileTickets (www.github.com/caelum/agiletickets), projeto utilizado no nosso curso PM-87.

    Ele usa um modelo rico.

    Dá uma olhada!

    Um abraço!

  13. Diego Mariano 07/04/2014 at 14:35 #

    Chega a ser engraçado, Maurício, mas essa frase eu falei para um amigo meu semana passada depois de ler o seu livro sobre TDD: “agora eu vejo o quanto o MVC é procedural”.

  14. Mauricio Aniche 08/04/2014 at 12:06 #

    Oi Diego,

    Hahaha, ótimo! Esse era meu objetivo! 🙂

    Um abraço!

  15. Diogo Marins 15/04/2014 at 10:42 #

    Obrigado, Aniche!

    Esse exemplo ilustra ainda mais aquela dúvida que postei no fórum do curso online da Alura “Design Patterns para bons programadores em C#”, é exatamente sobre isso que estava falando.

    Vou ler esse livro.

    Alexandre Aquiles, valeu pela postagem do link com o vídeo do teatro sobre DDD.

    Reforçando: Teatro sobre DDD – http://www.agileandart.com/portfolio/ddd-domain-driven-design-teatro/

  16. André Simões 15/04/2014 at 11:05 #

    É engraçado. E me eu lembro que na faculdade essa foi a forma que eu “aprendi” orientação a objeto. hehe

  17. Andre 15/04/2014 at 12:51 #

    Me parece que a arquitetura MVC segue a risca os conceitos de “alta coesão” e “baixo acoplamento”. Eu a utilizo há alguns anos e pelo menos no meu caso, não vejo dificuldades em manutenção. Sem contar que já reaproveitei muitas classes dezenas de vezes.
    De início, objetos ricos me causam uma certa desconfiança… Sinal que preciso ler e aprender mais sobre o assunto.
    🙂

  18. Meireles 15/04/2014 at 13:42 #

    Não sei por que se insiste em nomear métodos e funções com verbos que não estão no infinitivo. Por que usar “insere” no lugar de “inserir”, “encerraNota” no lugar de “encerrarNota”. Este (péssimo) hábito começou quando péssimos tradutores começaram a traduzir, no final da década de 1980 os livros de linguagens. Em inglês usa-se o infinitivo: “run”, “do” (doSomething), “write”, “close” etc. Se fosse no presente do indicativo, nunca veríamos “doSomething” mas “doesSomething”. Cabe aos instrutores dos cursos de linguagem (java, C, C# etc.) ensinar corretamente para evitar propagar péssimos hábitos.

  19. Vinicius 15/04/2014 at 15:34 #

    “herança” e “flexibilidade” na mesma frase. Pode isso, Arnaldo?

  20. Artur Bernardo 15/04/2014 at 17:02 #

    Aprendi a programar usando o MVC. Alias, até hoje acho raro achar softwares que ao menos usem bem essa arquitetura. Sempre tem um “atravessamento”, um request no model ou o controle do fluxo de dados se baseando em alterações no HTML através de um monte de J.S. (triste, mas real)
    Ao menos softwares bem desenhados, dentro da arquitetura MVC, já fariam o mundo do desenvolvimento um lugar mais feliz.

    Quando a “objetos ricos”. Não sou muito habituado com esse mundo, mas estou tentando entender mais a fundo o porque tanta gente defende a forma de trabalho apresentada no texto.
    Preciso acompanhar mais casos reais para entender perfeitamente este ponto.

  21. Rodolfo 15/04/2014 at 18:48 #

    Respondendo ao Marcello, cada caso é um caso:

    A classe de NF pode utilizar outros objetos pra trabalharem junto dela e resolverem conjuntamente a tarefa. Se vc aplicar o principio da responsabilidade única vc ve que a sua classe de NF precisaria apenas utilizar outros objetos pra delegar suas funções: persistir as informações, enviar emails, etc*. Injetando esses outros objetos pelo container ou trabalhando com eventos (dependendo do caso) te ajuda a deixar o código ainda mais desacoplado e coeso.

    Já no caso da venda, também ficaria a cargo dela manusear os itens (eles não existem sobre a venda, são os Aggregates do DDD) e as demias responsabilidades podem ser delegadas chamando métodos de outros objetos (injetados pelo container) ou via eventos (eu, particularmente, prefiro).

    *No caso de retornar as listas, DDD sugere vc usar Repositories como responsáveis por retornar dados. O padrão CQRS (Command Query Responsibility Segregation) também fala sobre isso e é bem interessante.

  22. Marcelo Daniel sales 17/04/2014 at 21:21 #

    Não vamos considerar que DDD é a solução para todos os problemas do mundo “anêmico”. Ele te ensina a pensar mais O.O. Como sempre a casos e casos para o uso. Penso sempre que se você for um bom utilizador de herança, composição, encapsulamento ou polimorfismo não se trata de você usar modelo X ou Y. No final a qualidade do código é que vai contar.
    É importante absorver novas visões e aprender técnicas novas, mas não cometamos o erro de desprezar e menospreza o que hoje está no mercado, em produção e sustentando milhares de aplicativos.

  23. Mauricio Aniche 22/04/2014 at 13:38 #

    Oi Marcelo,

    Veja que DDD apareceu só nos comentários. No post, sou bem enfático em relação ao uso de OO. DDD é só a cereja do bolo.

    Concordo em absoluto com a sua frase “DDD não é a solução para todos os problemas do mundo anêmicos”, mas sou bastante tendencioso a acreditar que OO é! 🙂

    Um abraço!

  24. Leonardo Leite 29/04/2014 at 08:29 #

    Oi Aniche!

    Não li todos os comentários então me desculpe se falar alguma redundância aqui!
    Esse é um problema que me incomoda faz tempo!
    Uma leitura que me foi muito esclarecedora sobre esse tema foi o capítulo 6 “Objects and Data Structures” do livro Clean Code. Tanto que fiz um resumo do capítulo aqui: http://polignu.org/artigo/clean-code-objetos-n%C3%A3o-s%C3%A3o-estruturas-de-dados
    Apesar de esclarecedor, a solução continua não sendo simples… pois pensando na responsabilidade única agora penso que de fato as classes que representam estruturas de dados (como NotaFiscal) não devem conter regras de negócio (segundo Uncle Bob: afinal elas não classes, mas apenas estruturas de dados), mas o como fazer muitas vezes ainda é obscuro…

    (depois ainda leio melhor os outros comentários : )

  25. Leonardo Leite 29/04/2014 at 09:37 #

    Comentário do Marcello Mello (“Olha ja pensei muito sobre isso…”) vai na linha do meu…
    Parece q eu tb tenho que conhecer esse tal DDD (ainda não tinha ouvido falar!)

    “agora eu vejo o quanto o MVC é procedural”
    boa frase do Diego! Tb faz tempo q tenho essa impressão.

  26. Silva 19/05/2014 at 22:34 #

    Todo post falando mal de anêmico não mostra exemplo real de não-anêmico.

  27. Vanderson assis 31/07/2014 at 08:51 #

    Grande Maurício!
    Cara, fui seu aluno em janeiro de 2012 , claro que não vai lembrar rs …. mas cara, entendi em partes o que você escreveu, teria a possibilidade de disponibilizarem um projetinho básico de um modelo não-anêmico?

    Até mais!

  28. Clayton Passos 10/10/2014 at 16:57 #

    Como fugir do BOLOVO, utilizando JSF + EJB + JPA?

    Não consigo por em uma classe JPA (@entity) o comportamento de salvar, pois não consigo injetar um EJB ou até mesmo anotar essa classe com @Stateless/@Local.

    Gostaria muito de um modelo de implementação de referência completo (MVC) que utilize apenas a stack do JEE e outra utilizando outros frameworks.

  29. Luiz Guilherme Rodrigues 27/02/2015 at 15:12 #

    mas e quando estamos trabalhando com uma tecnologia que requer um construtor sem argumentos por exemplo?

  30. Maurício Aniche 02/03/2015 at 14:02 #

    Oi Vanderson,

    Puxa, acho que todos nossos códigos no Github usam modelos ricos. Não são necessariamente apps web, mas fazem bom uso de OO.

    Oi Clayton,

    O segredo é você abstrair todo o problema de infraestrutura que você tem. Você não pode deixar a infra ganhar de você!

    Oi Luiz,

    Aí não tem jeito. CDI é o exemplo. Você cria um construtor pra ele, e anota como @Deprecated, para que um humano não use!

    Abraço!

  31. Andrey 10/04/2015 at 15:01 #

    Oi Aniche,

    eu ainda estou com dúvidas em como posso fugir de modelos anêmicos trabalhando com ORM, já que o hibernate me obriga a usar POJOs.

    ainda não consegui vislumbrar em manter os 2 mundos juntos.

    Abraços!!!

  32. Maurício Aniche 13/04/2015 at 14:45 #

    Oi Andrey,

    O Hibernate faz vc ter POJOs, mas nada te impede de ter métodos com regras de negócio lá dentro, não é mesmo!? Essa é a ideia!

    Um abraço,

  33. Andrey 10/06/2015 at 12:41 #

    Opa.

    é, realmente, nada me impede de criar regras de negócios mesmo não. Mas, tentando implementar isso em meus projeto, me surgiu mais uma dúvida.
    Bom, no caso, preciso garantir que a classe tenha um contrutor padrão, mas, se por acaso essa minha classe tiver uma forma específica de ser criada? como devo proceder como boa prática? criar metodo de fabrica estatica? encapsular em um proxy ou decorator? manter um consrutor padrão por causa do hibernate e criar outro construtor para usar dentro do sistema?

    tenho uma classe que deve persistir um valor e uma taxa. mas tem regra de negócio um valor total que é calculado com a multiplicação do valor com a taxa. esse calculo por exemplo, devo criar um metodo retornaTotal{return taxa*valor} ou um fild total @Transient (com seu getter) que é calculado no construtor?

    ainda tenho essa dificuldade em enchergar uma classe rico quando tenho que usar componentes anemicos no meu dominio.

    hoje mesmo, tive um desafio de uma classe como essa que não teria que ter um construtor padrão, por causa da regra de negocio de criação desse objeto, mas tive que adicionar o construtor padrão somente por causa do hibernate.

  34. Andrey 10/06/2015 at 12:44 #

    opa, vi agora a resposta para o luiz

    ”’
    Oi Luiz,

    Aí não tem jeito. CDI é o exemplo. Você cria um construtor pra ele, e anota como @Deprecated, para que um humano não use!
    ”’

  35. Ravane 05/12/2015 at 10:56 #

    Se me permitem um ponto de vista não-técnico (sou Corretor de Imóveis):

    “MVC não é procedural”, uma vez que nasceu em ambiente Smalltalk: as camadas “são implementadas | se comunicam” através de objetos. Mas em ambiente Web não é possível devido à infraestrutura da rede, que impõe a distribuição das camadas e total separação da view (browser). O que se tem usado é o pattern Model–View–Presenter (MVP). Se você acessa o repositório a partir da controller, e de lá repassa os dados à view, então você está usando MVP. A não ser que tenha implementado um observer na view para observar mudanças de estado diretamente na camada model (DB).

    Compartilho com o Sr. Meireles a frustração ao tentar acompanhar trechos de código não muito legíveis. Mas o tempo verbal correto seria o IMPERATIVO. Java, C# e tantas outras são linguagens de programação baseadas no paradigma da Programação Imperativa. Assim, os termos corretos seriam: #insira(), #encerreNota(). Um programa é uma receita, ou um diálogo entre alguém e uma máquina. Você manda a máquina fazer o que você deseja através de ordens, e a máquina responde se foi possível realizar o comando ou não.

    O conceito de ENTIDADE discutido em DDD não diz respeito ao modelo, mas sim ao domínio do negócio (aka Domain Driven Design). Pode parecer preciosismo, mas se você está implementando entidades apenas “pensando” em persistência (aka model), então seria útil “revisitar” o livro. É preciso ignorar totalmente o aspecto técnico de um sistema ao definir seu domínio do negócio, pois só assim é possível identificar as entidades. Até porque o domínio do negócio surgiu antes do sistema, como o ovo antes da galinha e a planilha-excel antes do sistema.

    A responsabilidade de uma entidade se limita aos dados em sua estrutura. Você pode implementar o método Venda.totalizeItens() que soma todos os itens da venda, o que é fácil se Venda for uma entidade agregada e já possui em sua estrutura uma lista de itens. Mas ao implementar o método Venda.suspenda(), apos alterar o flag interno será preciso persistir esta alteração no repositório, e esta atividade de persistência não deve ser de responsabilidade da entidade. Ao desenhar o modelo de classes da implementação, imagine que não há banco de dados remoto, mas sim um grande repositório (in-memory) composto por um conjunto de estruturas de dados que estão ao alcance através de uma simples chamada de método, sem necessidade de uma DAO ou DAL. Dentro do método Venda.suspenda(), você vai executar o método de alguma classe pertencente a este repositório para persistir os dados (alterados) da venda suspensa.

  36. Alexandre Valente 17/12/2015 at 18:08 #

    haha.. lá vou eu fazer o papel de advogado do diabo… Não tenho como discordar do embasamento teórico apresentado pelo Maurício… Muito bom artigo por sinal. Porém, tenho algumas ressalvas quanto à produtividade, especialmente de sistemas grandes com equipes maiores.

    Programar o.o. é difícil. Pelas respostas da lista se ve o quão difícil é. Se temos um projeto, especialmente os de larga escala, projetar e manter as abstrações corretas em todo o ciclo de vida é um desafio hercúleo, especialmente com uma equipe heterogênea. Mesmo com programadores experientes, o o.o. vai te dar várias maneiras de fazer a mesma coisa. Isto é ótimo individualmente, mas ruim pra fazer padrões de projeto para equipes, corre-se o risco de cada um fazer de uma forma e depois termos uma colcha de retalhos.

    Acho que esta é a maior vantagem de modelo anêmico. Como foi citado, programar procedural é muito mais simples. Acho que talvez por isto MVC seja tão procedural, como eram também os guidelines gerados pela Microsoft.

    Temos vários sistemas, de grande porte, com mais de 10 anos, rodando, usando separação clara de negócio em uma “camada” (ou seja, modelo anêmico). Temos pouquíssimos problemas de repetição de código e de manutenabilidade (pelo contrário, é muito mais fácil ensinar um programador novo neste tipo de arquitetura do que em um o.o. puro). E ainda vejo outras vantagens, como facilidade para auto-documentação (ou seja, é super claro o que uma regra de negócio faz, ela é procedural e está em um local só), e facilidade de melhorias de desempenho (é fácil saber qual regra tem problemas, é fácil isolá-la ou reescrevê-la).

    Em suma, para um pequeno projeto, o.o. pode ser o caminho. Mas para o dia-a-dia, ainda preciso ser convencido que um sistema grande puro o.o. será tão fácil de manter e evoluir quanto uma arquitetura clássica multicamadas com separação de regras de negócio! 🙂

  37. Maurício Aniche 25/12/2015 at 12:06 #

    Oi Alexandre,

    Minha opinião mudou um pouco ao longo do tempo. Hoje, minha cabeça me diz que se estou desenvolvendo um sistema web “tradicional”, ou seja, basicamente manipulação de dado, código procedural me parece um bom caminho. A requisição vem, vc responde, e acabou. É fácil rastrear.

    No entanto, se seu sistema foge disso, tem estado de verdade, ainda não vejo motivo pra trabalhar de maneira procedural. Não só por causa do blá-blá-blá de manter o comportamento perto do estado, mas por causa dos ganhos com polimorfismo.

    Um abraço

  38. Ravane 02/01/2016 at 11:33 #

    Um possível caso de uso não mencionado aqui seria a implementação e publicação de EJB’s ou Web Services. Ao disponibilizar os JAR’s referentes ao EJB-Client para outros sistemas, normalmente utiliza-se o design pattern DTO para as estruturas de dados manipuladas. Sem dúvida estas classes serão anêmicas por definição. Mas como é uma prática já consagrada em muitas empresas, não há muito interesse em mudar/evoluir. Neste caso, sugiro adotar o seguinte pattern:

    public class Cliente extends ClienteDTO implements IEntity {}

    A classe ClienteDTO, ou ClientStruct, trata-se de um JavaBean apenas com atributos e respectivos métodos getters e setters. Como não possui lógica integrada, pode ser exportada via EJB-Client sem causar dependências indesejadas em xxxHome, xxxRemote, xxxStub, xxxSkeleton ou “whatever”…

    Já a classe Cliente seria uma entidade com propriedades (herdadas) e lógica integrada. Pode possuir métodos #toDTO() e #fromDTO() para agilizar a codificação.

    IMHO não acho uma boa ideia implementar lógica de negócio em classes EJB/Session Bean, pois a meu ver são requisitos de infraestrutura (de acordo com a visão do DDD). Acho que servem melhor para orquestrar/coreografar outras classes Entity e Service.

  39. Joao Roberto 13/12/2016 at 08:32 #

    é um assunto bem polemico esse pois as pessoas tentam sair desse modelo e acabam indo pra outros que ficam piores ainda, pelo pouco que pude perceber este exemplo citado é mais uma má implementação do modelo 3 camadas do que uma forma de dizer que ele não esta bom.

    não sou especialista em arquitetura mas atualmente dou manutenção em um sistema java onde há um projeto pra cada camada e cada projeto possui um “BO e DAO” isso me confunde mto talvez eu nao esteja entendendo a arquitetura feita direito mas esta mto estranho esta.

Deixe uma resposta