Dos livros na área de design lançados nos últimos meses, o que mais me chamou a atenção foi o livro do Jimmy Nilsson: Applying Domain-Driven Design and Patterns. Depois de ler e reler alguns capítulos, já dá pra dizer que o livro é muito bom. O autor explica sua solução de design para uma série de problemas recorrentes que nós desenvolvedores passamos toda vez que queremos montar um esquema arquitetural que privilegie flexibilidade, extensibilidade, desacoplamento, facilidade para escrever testes de unidade e para manter o código fácil de ler e manter.

Na verdade, não há muitas novidades para quem é fã de arquitetura e, como eu, acha que – a não ser que algo novo apareça – o Domain Model pattern (Fowler, PoEAA) é a solução ideal para pelo menos 90% das soluções de softwares empresariais que desenvolvemos hoje em dia. Mas vale a pena reforçar algumas idéia do livro, das quais eu compartilho na totalidade.

Quando se fala em Domain Driven Design, o conceito-chave é o Foco no Domínio do problema, o que leva a premissa de que código que resolve problema de domínio não se mistura com código que resolve problema de software. Em outros termos, eu devo ser capaz de codificar soluções para o domínio do negócio sem absolutamente nenhuma dependência com nenhuma estrutura ou infra-estrutura de software.

Isso resulta em uma solução de software com uma estrutura de camadas arquiteturais parecida com a figura apresentada a seguir:

ddd-schema.png

A camada de Interface com o Usuário (UI) e a camada Application são simples e não há nada de diferente do que já estamos acostumados a fazer. Repare que não há nenhuma seta saindo de Domain. Isso revela que Domain não depende de ninguém. É totalmente isolada e, em tese, poderia funcionar sem nenhuma limitação imposta pela infra-estrutura de software adotada.

Veja um exemplo:

   public class JurosSimples: EstrategiaCalculoJuros

    {

        Money _principal;

        decimal _taxa;

        int _numeroPeriodos;

        public JurosSimples(Money principal, decimal taxa, int numeroPeriodos)

        {

            _principal = principal;

            _taxa = taxa;

            _numeroPeriodos = numeroPeriodos;

        }

        public override Money Calcular()

        {

            return _principal.Valor * _taxa * _numeroPeriodos;

        }

    }

Será que esse código vai mudar se estivermos trabalhando em uma aplicação web ou desktop? Windows, linux ou Mac? Que acessa um banco de dados MSSql, SqlLite ou Oracle? Ou que persiste e recupera dados da memória, de arquivos-texto ou xml? É claro que não. Mas esse exemplo não é muito bom. É óbvio até para o mais novato dos desenvolvedores que eu não precisaria mudar uma classe de cálculo de juros só porque mudei o banco de dados ou o sistema operacional. Vamos colocar de outra maneira então. Imagine alguns milhares de classes de regras de negócio. Inclua nessa lista aquelas que precisam buscar a lista de clientes e mostrar na tela com a maior variedade de filtros e opções, além daquelas que juntam 7 ou 8 tabelas do seu banco de dados para montar uma estrutura de dados.  No DDD, todas elas precisam funcionar sem nenhum acoplamento  com a infra-estrutura de software adotada.

Assim, a forma como o modelo de domínio vai  ser utilizada para que seu sistema funcione é um problema de software e não de negócio. O que importa para o domain model é como o negócio estará sendo representado e como suas regras estarão descritas. Quanto mais as duas coisas estiverem desassociadas melhor será para o esquema arquitetural do seu sistema.

Confesso que realmente é difícil de enxergar o funcionamento disso sem que possamos “ver com os nossos próprios olhos”. Essa é a parte mais difícil. A chave dessa solução está na implementação da camada de infra-estrutura. É ela que possibilita toda essa independência do Domain Model. Uma camada de infra-estrutura com falhas de design inviabilizará o modelo DDD.

Muitos conceitos, técnicas e padrões de design estarão por trás trabalhando para que a arquitetura DDD funcione. Estou falando de:

·         Persistence Ignorance (PI) (ou POCO/POJO em termos mais populares);

·         Repository Pattern;

·         Query Object Pattern;

·         UnitOfWork Pattern;

·         Aggregate Pattern (Eric Evans DDD);

·         Dependency Injection;

·         Mocks, Stubs and Fakes;

·         Patterns de Domínio (Specification Pattern, Factory, Strategy, State e outros). Lembrando que, segundo o autor, os patterns de domínio são tratados de uma forma um pouco diferente dos patterns GoF, apesar de terem a mesma implementação, podem ter semântica e objetivos diferentes.

Regras de Negócio

Um dos pontos altos do livro é o capítulo 7, onde são discutidas uma série de questões sobre estruturação e uso de regras de negócio no Domain Model. Veja no snippet de código apresentado abaixo como eu estruturei algumas regras de persistência em uma classe Aluno, seguindo o modelo que o Nilsson apresentou nesse capítulo:

namespace DomainModel.Academico

{

    public class Aluno

    {

        private List<Rule> _persistenceRules = new List<Rule>();

 

        public Aluno()

        {

            DefinePersistenceRules();

        }

       

        public void DefinePersistenceRules()

        {

            _persistenceRules.Add(new InformacaoRequerida("NomeCompleto", this));

            _persistenceRules.Add(new TamanhoMaximoDeCampo(100, "NomeCompleto", this));

            _persistenceRules.Add(new FormatacaoDeEmail("Email", this));

            _persistenceRules.Add(new TamanhoMaximoDeCampo(150, "Email", this));

            _persistenceRules.Add(new MatriculaPreExistente(this));

            _persistenceRules.Add(new CPFPreExistente(this));

        }

 

        public ListaDeRegras CollectBrokenRules()

        {

            return RuleBase.CollectBrokenRules(_regras);

        }

    }

}

Veja que a validação de um objeto de negócio quanto a persistência pode soar totalmente natural dessa forma para quem está lendo o código sob a ótica de domínio. Nada de queries, acessos ao NHibernate, DAOs, etc. É claro que em algum momento isso será feito, mas não de forma acoplada ao objeto de domínio.

Veja que esse design permite acoplar diferentes listas de regras para um objeto de negócio, podendo ser validadas em momentos diferentes e com propósitos diferentes.

Esse assunto é bastante interessante e pode render muita discussão. Assim que novas idéias forem surgindo estarei publicando por aqui.


Posted by: alisson.vale
Posted on: 11/26/2006 at 10:58 PM
Categories: Design
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (1) | Post RSSRSS comment feed
 
 

Comments (1) -

Rubens José Rosa Brazil

Saturday, July 05, 2008 7:27 PM

Rubens Jos&#233; Rosa

Alisson, muito boa suas considerações. Eu possuo esse livro do Jimmy Nilsson e também o do Eric Evans, Domain-Driven Desing. O foco desses dois livro é Domain-Driven Desing (DDD), claro, dessa forma eles falam pouco sobre a interface gráfica com o usuário, GUI, que é justamente aonde estou tendo problemas. Não é explicado como que a GUI trabalha com o DDD. Eu estou trabalhando em um projeto e estou aplicadon o DDD mas não estou satisfeito com a interação entre DDD e a GUI. Você conhece algum site, artigo ou livro que foque mais na interação entre o DDD e a GUI. Obrigado e parabens pelo seu artigo.

Add comment

  Country flag

biuquote
  • Comment
  • Preview
Loading