sexta-feira, 23 de outubro de 2009

Modelo anêmico realmente é ruim?

Eu sempre costumo dizer para o pessoal que se você não enxerga o problema não tem por que aplicar uma solução.

O mesmo vale para o modelo anêmico, se você não consegue enxergar os problemas dessa modelagem com certeza você não vê valor nenhum nas outras formas de modelar o domínio.

Com certeza você vai dizer que conhece aplicações desenvolvidas com modelo anêmico e que funcionam muito bem, e com certeza isso é verdade, da mesma forma que conheço aplicações procedurais que funcionam muito bem. Então o que nos motiva a não ter modelos anêmicos?

Quando você decide pelo modelo anêmico você tem que estar ciente que você esta abrindo mão de vários benefícios que o OO pode lhe proporcionar. Fowler diz o seguinte:

“The fundamental horror of this anti-pattern is that it's so contrary to the basic idea of object-oriented design; which is to combine data and process together. The anemic domain model is really just a procedural style design, exactly the kind of thing that object bigots like me (and Eric) have been fighting since our early days in Smalltalk. What's worse, many people think that anemic objects are real objects, and thus completely miss the point of what object-oriented design is all about.”

http://martinfowler.com/bliki/AnemicDomainModel.html

Ele reforça a idéia de que o modelo anêmico não é OO, podemos ver essa afirmação na prática trazendo o clássico exemplo do carro para o mundo do modelo anêmico. Quando você modela um carro geralmente você faz algo assim:


public class Carro
{
private int _posicaoAtual;

public void Andar()
{
this._posicaoAtual += 10;
}
}

Agora no mundo anêmico o carro ficaria assim:

public class Carro
{
private int _posicaoAtual;

public int PosicaoAtual
{
get{ return this._posicaoAtual;}
set{ this._posicaoAtual = value;}
}
}

public class BLCarro
{
publicvoid Andar(Carro carro)
{
carro.PosicaoAtual += 10;
}
}


Perceba que agora criamos um “andador de carro” isso faz algum sentido? Creio que não.
Mas se o modelo anêmico é um anti-padrão, por que temos o DTO (Data Transfer Object Pattern)?

Modelo anêmico não tem nada haver com DTO, eu falo que DTO é um mal necessário, ele foi criado para realizar transporte de dados, não para transporte entre as camadas lógicas como se tem feito com os modelos anêmicos.

Um fator que motiva a utilização do modelo anêmico é o acesso a dados, mas acredite esse problema tem solução, você pode utilizar o Repository ou Active Record.

Active Record with Castle
http://www.castleproject.org/activerecord/index.html

Using Repository and Unit of Work patterns with Entity Framework 4.0

http://blogs.msdn.com/adonet/archive/2009/06/16/using-repository-and-unit-of-work-patterns-with-entity-framework-4-0.aspx

NHibernate and the Unit of Work Pattern
http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/04/10/nhibernate-and-the-unit-of-work-pattern.aspx

Outro fator que confunde um pouco a cabeça do pessoal é que se tem um caminho fixo para se chegar ao banco de dados com o modelo anêmico sendo UI > BL > DL utilizando o modelo o anêmico para trafegar os dados entre a camada, com uma entidade como fica esse caminho?

Pra não fugir do costume vou soltar a frase “cada caso é um caso” você pode por exemplo utilizar um façade para ter acesso ao domínio. Ex.: UI > Façade > Domínio.

Um comentário:

fpadoan disse...

Após conversamos sobre isso ano passado, e fugindo da anemia das BLs (ou "chamadoras de métodos de DL"), acabei criando uma aplicação "fantasma", de tantas classes vazias usando Generics...
Aí resolvi essa anemia fantasmagórica generalizando as operações CRUD, pra dedicar minha digitação lenta às funcionalidades chave, e pior que faltou tempo pra limpar o que era desnecessário. Bom, ao menos foi um ensaio pra um código realmente coerente e bem estruturado.