Essa semana saiu mais uma edição da Revista MundoDotNet. Desta vez, pude dar minha contribuição com um artigo em que a idéia é relacionar "métricas de código" com "design de software".  Acho que ainda exploramos muito pouco dos benefícios que as métricas de código podem oferecer para o aumento nos níveis de qualidade do design de um software. Apesar de haver muitas ferramentas, raramente se vê alguém que efetivamente obtém alguma vantagem em utilizar as informações que elas geram. De maneira geral, eu tento dar ali um caminho para se chegar a sintomas de problemas de design por meio da análise numérica de informações extraídas do código-fonte. Assim como um médico pode usar os números extraídos de exames - como números de plaquetas, ph, taxas de glicose e colesterol e outras centenas de índices possíveis - para diagnosticar doenças e prescrever tratamentos, desenvolvedores de software também podem. Um dos caminhos é saber como algumas medições revelam problemas no design. Obviamente que números não são suficientes para avaliar o design de um software. A avaliação subjetiva e humana sempre será necessária. Mas eles podem sim ser de grande ajuda nessa questão. Quando falamos em "problemas de design", a primeira coisa que me vem a cabeça são os mau-cheiros de código que nos levam aos padrões de refatoração. Assim, o artigo tenta mostrar como podemos encontrar pontos de refatoração à partir de métricas coletadas no código-fonte. Além disso, há a questão de utilizar tal abordagem de modo sistêmico, criando assim alguns mecanismos de proteção contínua do design e abrindo espaço para a evolução do código de forma contínua. Sei que muitos leitores desse blog não trabalham e também não conhecem a plataforma .Net. Mas, mesmo para eles, recomendo comprar de vez em quando a MundoDotNet (eu não trabalho com Java, mas estou sempre lendo a MundoJava). A MundoDotNet é uma revista que foca na plataforma, porém com uma boa ênfase em aspectos gerais sobre desenvolvimento (como design, arquitetura e técnicas de desenvolvimento), o que a faz ser atraente para qualquer um que leve desenvolvimento a sério. No caso do meu artigo em específico, ele poderá ser lido e aproveitado por usuários de qualquer plataforma de desenvolvimento. Se quiser discutir sobre o artigo, é só deixar um comentário aqui ou me enviar um e-mail. Boa Leitura! 

Posted by: alisson.vale
Posted on: 2/12/2008 at 7:40 PM
Tags: ,
Categories: Coding | Design
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (6) | Post RSSRSS comment feed
 
 
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: 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
 
 
O singleton é um dos design patterns mais populares e mais simples de implementar. Nesse post, eu descrevo como esse pattern do GoF pode ser uma armadilha de design quando utilizado de forma inapropriada. [More]

Posted by: alisson.vale
Posted on: 11/22/2006 at 2:39 PM
Categories: Coding | Design
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed