Namespaces vs. Assemblies o dilema na separação de interesses

Mais um recente dilema na plataforma .NET. Desta vez a questão é: Os namespaces são suficientes para distinguir e organizar as camadas da minha aplicação ou, além disso, devo separá-las em assemblies diferentes?

Tenho visto um número cada vez maior de projetos .NET com uma quantidade exagerada de assemblies. IMHO, os namespaces são subutilizados. De forma geral, eu usaria mais namespaces e menos assemblies! Vou expor o meu sentimento em relação a isto:

Um exemplo típico é a camada de persistência (no jargão .NET: uma DAL, Data Access Layer). Se eu estou criando uma camada de persistência específica para minha aplicação, ou seja, que é capaz apenas de manipular os modelos do domínio em questão; então qual o problema em distribuí-la juntamente com minha camada de negócio em um único assembly? O fato de duas camadas diferentes estarem num mesmo assembly não torna o meu design menos coeso.

Estamos falando de um limite – conceito-chave da separação de interesses (Separation of Concern) - que delineia os interesses de um conjunto de classes da aplicação. A escolha entre um limite físico (assemblies) ou lógico (namespaces) dependerá das reais necessidades, vantagens e desvantagens.

Por exemplo, se um componente será reutilizado por várias aplicações, ou então uma equipe separada é responsável por desenvolvê-lo, é necessário defini-lo num assembly específico. Load on-demand também é um bom cenário para recursos em assemblies.

Separar camadas mutuamente dependentes em assemblies diferentes causa um problema de design conhecido como Circular Dependency. Isso quer dizer que os dois assemblies não podem depender diretamente um do outro. Um ponto interessante citado no artigo do Smacchia é que esta dependência resulta no que ele chama de “super componentes”. Se um assembly A depende diretamente do assembly B, e este depende do assembly C, é impossível executar algo no primeiro assembly sem ao menos ter que carregar os dois últimos.

Para resolvermos este impasse devemos retirar a ligação direta entre os assemblies com algum tipo de mapeamento ou interceptação. O que é mais comum (e indicado em alguns textos) é criarmos um terceiro assembly onde definiremos estruturas e interfaces comuns para persistência e negócio. É comum nestes casos ver modelos anêmicos usando o conjunto BO/DTO-VO-TO/DAO. Então fica a pergunta:

Se eu não consigo aproveitar minha lógica de persistência em outros cenários – já que ela depende da interface dos DTOs (ahrg!) e este deve refletir os atributos dos meus objetos de negócio (ou nos piores casos refletem as tabelas do banco) – Qual a vantagem da separação dos objetos de negócio e da persistência em assemblies diferentes?

Já tentou abrir e executar um solution com muitos projetos relacionados? É demorado, o build é lento (e às vezes exige que uma ordem de compilação dos projetos seja seguida) e propenso a erros de output e etc. Já imaginou o problema na distribuição? Voltamos aos tempos de DLL Hell – programadores Win32 já ouviram falar muito nisso!

Talvez você esteja se perguntando se deveria distribuir a sua aplicação inteira num único e onipotente assembly. Mas como dito anteriormente, essa questão vai depender dos seus requisitos de arquitetura – principalmente em como as camadas se comunicarão – e de muito bom senso. Eu procuro sempre refletir esta célebre frase do gênio Albert Einstein: “Make everything as simple as possible, but not simpler

Referências

http://www.theserverside.net/tt/articles/showarticle.tss?id=ControllingDependencies
http://articles.techrepublic.com.com/5100-22-1044871.html
http://www.msdners.com//dev-archive/88/12-39-881434.shtm

http://codebetter.com/blogs/david.hayden/archive/2005/07/23/129745.aspx

Uma resposta

  1. Concordo com vc! Comoo foi dito no texto, essa decisão – separação lógica ou física – dependerá do contexto.

    PArabéns!

Deixe uma resposta