"Para que levar a vida tão a sério, se a vida é uma alucinante aventura da qual jamais sairemos vivos." - Bob Marley

Perguntas ao final do eventoOi Pessoal! Nesse sábado rolou o primeiro Arena do grupo MSDev-ES na Faculdade Faesa. O evento tinha como objetivo apresentar as características dos dois ORMs que estão mais “em alta” no mercado: O NHibernate e o Entity Framework. Apesar do nome Arena, não tínhamos como objetivo definir qual das duas ferramentas era a melhor, e sim apresentar suas características e particularidades a fim de tirar as principais dúvidas dos desenvolvedores locais sobre suas utilizações.

A idéia era o Dilter Porto (@dilterporto) apresentar o NHibernate e eu apresentar o EF4. Conversamos muito nas semanas que antecederam o evento e decidimos não falar puramente das ferramentas. Tomei a liberdade de falar não só de EF4, mas sim como eu tenho utilizado o EF4, sendo assim, falei sobre Arquitetura de software, TDD, Domain-Driven Design, DI, Repository e finalmente EF4. O Dilter abordou desde a teoria dos ORMs até sua experiência na utilização do NHibernate. Os feedbacks que tivemos é que as palestras se encaixaram perfeitamente. Gostei muito da seleção de informações que foram apresentadas no evento.

Após as duas palestras tivemos uma mesa redonda mediada pelo Rafael Hrasko (@hrosko) com perguntas e comparações sobre os dois ORMs. Procurei deixar bem claro que não curto vestir camisas de tecnologias, e sim tentar aplicá-las da melhor forma para solucionar os meus problemas. Tivemos perguntas bem interessantes sobre Performance, facilidades, maturidade, etc. Acredito que esse tenho sido um dos melhores eventos que participei ultimamente.

Disponibilizei aqui o vídeo da minha palestra (veja no denisferrari.blip.tv com qualidade superior), a apresentação, algumas fotos do evento e o código fonte do projeto apresentado (Faça download aqui).

Vídeo da palestra

Apresentação

Fotos do evento

Abraços!

Tagged with:
 
Faça da pedra de tropeço, um degrau de subida. Transforme cada fato negativo, em uma experiência positiva. - "Bruce Lee"

Nessa semana realizamos o II Fórum para Gerentes de Sistemas na Mindworks em Vitória-ES. Realizamos a primeira versão do evento no mês passado a pedido da própria Microsoft, e depois de uma série de pedidos para realização de uma segunda versão, decidimos organizar um evento semelhante, porém, voltado para a comunidade local.

Acredito que a segunda versão do evento ficou ainda melhor que a primeira. Mudamos algumas abordagens, inserimos alguns assuntos importantes e procuramos trabalhar de uma forma dinâmica e interativa com os participantes. Vou relatar agora um pouco do que aconteceu no evento:

.NET 4.0 e Visual Studio 2010

Nesse evento procuramos apresentar todos os recursos do Framework .NET desde a sua primeira versão lançada em 2003. O objetivo principal dessa parte do evento foi mostrar a maturidade da plataforma e como a mesma vem sendo melhorada de forma contínua e incremental (desde sua versão 2.0).

Como a idéia era fazer uma espécie de túnel do tempo das tecnologias Microsoft, procuramos abordar desde as características mais básicas da versão 2.0 do framework até as novidades mais quentes da versão 4.0 (versão mais atual).

Depois do apanhado histórico sobre o framework, fizemos algumas demonstrações das ferramentas de arquitetura do Visual Studio 2010, tais como: Gráfico de Dependências e Diagrama de camadas.

É impressionante perceber o mundo de ferramentas que temos à disposição no Framework .NET, e essa foi a idéia dessa apresentação, mostrar o poder que temos nas mãos utilizando essa plataforma.

Scrum e Agilidade

O André Pires apresentou o Scrum de uma forma muito interativa e dinâmica. Visitamos os conceitos do Scrum, seus papéis, artefatos, regras, cerimônias e recomendações. Acredito que todos os participantes tiveram uma visão bem clara do framework.

Gosto muito de discutir sobre Agile e Scrum. Apesar de não ser o palestrante desse tema, foi muito rico só ouvir os questionamentos feitos pelos gerentes de projetos que estavam presentes. O André apresentou com maestria o tema discorrendo sobre as grandes dúvidas e questionamentos dos gerentes de projeto tradicionais ao mundo ágil.

A apresentação terminou com uma dinâmica que exemplificava a utilização do Scrum. Os participantes tinham que atingir um objetivo específico em um tempo limite. O bacana é que o PO (André) passava pelas equipes gerando pequenos impedimentos e interferindo nos trabalhos, o que gerou fortes reações pela parte de alguns ScrumMasters. :)

Volto a destacar que, apesar de entender do tema, nada paga a troca de experiências que temos com os participantes do evento.

Técnicas de engenharia de software e TDD

Diferente da versão anterior desse evento, abordamos a importância da orientação a objetos e das técnicas de engenharia em projetos de software que usem processos interativos e incrementais na produção.

Fizemos algumas reflexões sobre qualidade de software e discutimos como é importante utilizar técnicas para construir o projeto que façam com que o custo de evolução não seja discrepante do custo de produção. Afinal de contas, em processos iterativos estamos sempre evoluindo o projeto.

Aprofundamos alguns conceitos que o André havia citado na palestra sobre Scrum. Falamos sobre POO, Design Patterns, CI, ORMs (Entity Framework e NHibernate), Programação em par, Testes unitários, DDD e TDD. Foi muito legal apresentar uma visão geral sobre esses assuntos que estão em alta nas listas de discussão mais ativas.

Finalmente, apresentamos o TDD de uma forma resumida como primeira prática a ser adotada dentre todas as práticas que havíamos discutido nessa etapa do evento.

O objetivo principal dessa parte do evento foi mostrar aos participantes que investir nas disciplinas apresentadas é um investimento tão importante quanto o investimento feito no aprendizado das tecnologias (ou mais).

Fotos do evento

Estamos preparando muitas novidades para o próximo evento, fiquem ligados!

Abraços!

Tagged with:
 
batman-dc-ultimate-online

Batman - DC Universe Online

Olá Pessoal! No meu primeiro post sobre Design By Contract recebi questionamentos interessantes sobre os prós e contras dessa abordagem comparando-a com a forma tradicional de validações com if…throw, logo, o objetivo deste post será evidenciar as diferenças entre essas duas abordagens.

No último post lancei um desafio ao meu amigo Gustavo Badke (@guripunk) após ele ter escrito o seguinte comentário: “Pra min isso é firula, não vejo diferença nenhum do if(…) throw new Exception…“. Alguns códigos que vou apresentar aqui foram escritos por ele, então, considerem-no como uma participação especial nesse post :) . Vamos lá:

Pré-condições

Tradicionalmente, quando precisamos verificar se os parâmetros de um método qualquer estão válidos para utilização, escrevemos algo semelhante ao código abaixo:

1
2
3
4
5
6
7
8
9
10
11
public Cor(int pVermelho, int pVerde, int pAzul)
{
    if (pVermelho < 0 || pVermelho > 255)
        throw new ArgumentOutOfRangeException("O argumento 'pVermelho' deve ser entre 0 e 255");
    if (pVerde < 0 || pVerde > 255)
        throw new ArgumentOutOfRangeException("O argumento 'pVerde' deve ser entre 0 e 255");
    if (pAzul < 0 || pAzul > 255)
        throw new ArgumentOutOfRangeException("O argumento 'pAzul' deve ser entre 0 e 255");
 
    // Implementação...
}

A abordagem acima resolve o nosso requisito de validação dos parâmetros, porém, o código utilizado para isso é extremamente “carregado” para a implementação de um requisito simples. Utilizando DbC a implementação ficaria da seguinte forma:

1
2
3
4
5
6
7
8
public Cor(int pVermelho, int pVerde, int pAzul)
{
    Contract.Requires<ArgumentOutOfRangeException>(pVermelho >= 0 && pVermelho <= 255);
    Contract.Requires<ArgumentOutOfRangeException>(pVerde >= 0 && pVerde <= 255);
    Contract.Requires<ArgumentOutOfRangeException>(pAzul >= 0 && pAzul <= 255);
 
    // Implementação...
}

A abordagem acima não só resolve o nosso requisito de validação dos parâmetros, como também deixa o código mais legível e você ainda conta com a validação dos contratos em tempo de compilacão. O método Requires ainda possibilita a configuração de uma mensagem personalizada caso seja necessário.

Também poderíamos usar AOP para resolver nosso problema, contudo, seria utilizar um recurso muito poderoso e complexo para uma necessidade muito simples. Se você não vai usar AOP para nenhuma outra necessidade do seu projeto, não recomendo utilizar nessa situação.

Não devemos avaliar o poder do DbC analisando somente suas pré-condicões. Precisamos avaliar se todos os aspectos dessa abordagem serão realmente úteis no nosso projeto, isso inclui também as pós-condições e invariantes.

Pós-condições

É comum, após a execução de um método, realizar a verificação de estado da classe nos membros que foram afetados pelo mesmo. Nessa situação, usando a abordagem tradicional, faríamos uma verificação qualquer no final do corpo do método. Algo como mostra o código abaixo:

1
2
3
4
5
6
7
public void AdicionarVermelho(int pValor)
{
    this.Vermelho += pValor;
 
    if (this.Vermelho > 255)
        throw new Exception("A propriedade Vermelho não deve ser maior que 255");
}

Um dos principais problemas nessa abordagem é a falta de legibilidade no método. Veja a solução usando DbC:

1
2
3
4
5
6
public void AdicionarVermelho(int pValor)
{
    Contract.Ensures(this.Vermelho <= 255);
 
    this.Vermelho += pValor;
}

Quando trabalhamos com contratos, sempre inserimos os mesmos no topo dos métodos, o que facilita muito a leitura dos códigos. Mesmo com exemplos simples como esses, podemos perceber que a curva de aprendizagem é muito baixa.

Invariantes

Como você garantiria que um objeto estará válido sempre independente de quais e quantos métodos forem executados? Provavelmente, você precisará construir algum método de validação e chamá-lo ao final de cada método público de sua classe. Nesse ponto, percebemos uma grande diferença entre as abordagens, pois usando DbC, só precisaríamos construir o método Invariant com as validações necessárias e pronto, vejam o exemplo:

1
2
3
4
5
[ContractInvariantMethod]
private void Invariant()
{
    Contract.Invariant(this.Vermelho <= 255);
}

Em resumo, como disse anteriormente, é necessário analisar todos os recursos da abordagem e não somente um. Apensar das pré-condições serem facilmente substituídas por if…throw, isso não acontece da mesma forma com as invariantes.

DbC não é para todos os projetos, DbC não é regra, DbC não é melhor ou pior que ninguém. Use em seus projetos quando precisar de todos os recursos que a abordagem dispõe, e mesmo assim não deixe de analisar alternativas como AOP.

Abraços Pessoal!

Tagged with:
 
"O futuro parece ser extremamente brilhante, com muitas possibilidades pela frente - grandes possibilidades. Como a canção diz: 'Nós precisamos apenas começar'." - Bruce Lee

PodcastProgramação orientada a aspectos é uma ótima saída para solução de requisitos ortogonais em projetos de software. Após algumas experiências e palestras sobre o tema, tive a oportunidade de participar da gravação de um podcast com a galera do .NET Architects: Alexandre Valente e Fábio Gouw.

Nos projetos em que usei AOP, trabalhei com o framework PostSharp, mas no podcast também abordamos Aspect.NET e AspectJ.

Vale muito a pena pesquisar sobre o tema.

Podcast

Post no DNA

http://podcast.dotnetarchitects.net/2010/05/podcast-13programacao-orientada-a-aspecto/

Tagged with:
 

Design By Contract (DbC) em .NET

"O homem, criatura viva e criador individual, é sempre mais importante do que qualquer estabelecido estilo ou sistema." - Bruce Lee

Design By Contract (DbC)Olá Pessoal! Estou escrevendo esse post no intuito de compartilhar com vocês o resultado de uma de minhas pesquisas: Como aplicar o Design By Contract usando os recursos do framework .NET.

O conceito DbC é usado para garantir o estado de seus objetos em tempo de execução. Basicamente, quando construímos nossa classe usando o conceito DbC, definimos acordos formais (o que chamamos de contratos) com quem a utiliza. Esses contratos visam garantir regras de utilização e estado, regras essas que são expressas através de pré-condições, pós-condições e invariantes.

Vamos explorar algumas situações do nosso dia-a-dia para fortalecer o conceito e aprender a utizar a classe Contract que se encontra no namespace System.Diagnostics.Contracts:

Como podem ver no código abaixo, estou criando uma classe chamada Cor que receberá no construtor uma string contendo o código hexadecimal. No teste, desejo garantir que caso a classe Cor seja instanciada com um parâmetro nulo, uma exceção do tipo ArgumentNullException seja lançada.

1
2
3
4
5
6
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void Deve_rejeitar_parametros_nulos()
{
    var cor = new Cor(null);
}

Para fazer o nosso teste passar, poderíamos verificar se o parâmetro é nulo usando if e lançar a exceção, porém, quando pensamos em contratos, o que fazemos é criar uma pré-condição de utilização da nossa classe. Para construir pré-condições, utilizamos o método Requires da classe Contract informando qual tipo de exceção será lançada caso o contrato for quebrado. Vejam o código abaixo:

1
2
3
4
5
6
7
8
9
public class Cor
{
    public Cor(string pCodigoHexadecimal)
    {
        Contract.Requires<ArgumentNullException>(pCodigoHexadecimal != null);
 
        // Código que converte o hexadecimal...
    }
}

Como podem ver, o código fica bem mais limpo e expressivo. Sem falar que caso você tenha o plugin do Visual Studio instalado terá essas verificações de constrato em tempo de design, isso mesmo, enquanto você cria suas classes seu código será analisado para verificar possíveis quebras de contrato. Vejam a imagem abaixo:

validacaoContrato

Vamos para outra situação: Agora nossa classe Cor possui um construtor que recebe as taxas de vermelho, verde e azul. Construímos um método para adicionar tonalidades de vermelho na cor, porém, a taxa máxima permitida de vermelho é de 255.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[TestMethod]
public void Deve_garantir_taxa_de_vermelho_menor_ou_igual_255()
{
    var vermelho = 200;
    var verde = 200;
    var azul = 200;
    var cor = new Cor(vermelho, verde, azul);
 
    try
    {
        cor.AdicionarVermelho(56);
    }
    catch
    {
        // O método deve lançar a exceção pois 200 + 56 ultrapassa o limite de 255.
        Assert.AreEqual(vermelho + 56, cor.Vermelho);
    }
}

Para garantir o limite da taxa de vermelho no nosso objeto, precisamos que o nosso método seja executado para então verificar o estado. Em DbC podemos criar uma pós-condição para avaliar o estado do nosso objeto ao final da execução do nosso método/propriedade. No exemplo abaixo usamos o método Ensures para criar a pós-condição que verifica a taxa de vermelho do nosso objeto após a execução do nosso método. Os contratos sempre são definidos no início dos métodos/propriedades.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Cor
{
    public int Vermelho { get; private set; }
 
    public Cor(int pVermelho, int pVerde, int pAzul)
    {
        this.Vermelho = pVermelho;
        // Configurar as outras propriedades...
    }
 
    public void AdicionarVermelho(int pValor)
    {
        // Aqui estamos garantindo que ao final da execução desse método, a propriedade Vermelho deverá respeitar o limite de 255;
        Contract.Ensures(this.Vermelho <= 255);
 
        this.Vermelho += pValor;
    }
}

As pós-condições são tão simples de serem escritas quanto as pré-condições.

Outra forma de garantir o nosso limite de 255 é criar um contrato invariante, ou seja, uma regra que será mantida sempre, independente de quais método forem executados no objeto. Para criamos o contrato invariante no .net usamos o método Invariant da classe Contract. Métodos invariantes são verificados sempre após a execução de qualquer método público da sua classe, eles só devem ter declarações de contratos e não podem retornar valores.

1
2
3
4
5
[ContractInvariantMethod]
private void Invariant()
{
    Contract.Invariant(this.Vermelho <= 255);
}

Como vimos, DbC é uma obordagem muito interessante e pode nos auxiliar muito no dia-a-dia. O objeto desse post não é apresentar bons padrões para design de testes ou grandes soluções no trabalho com cores, os exemplos aqui mostrados visam apenas apresentar alguns recursos da classe Contract. Façam os devidos testes e contem o que acharam do recurso e dessa abordagem.

Separei alguns links interessantes sobre o assunto no delicious, veja no link: delicious.com/denisferrari/DbC.

Fico no aguardo do feedback de vocês.

Abraços!

Tagged with:
 

Podcast: Modelo Anêmico

"Quando a geração mais velha diz NÃO a algo, geralmente desaprova sem análise, peremptoriamente... só porque a tradição diz ser errado! Raros são os indivíduos que usam a mente para chegar à verdade e expressar sinceramente seus reais sentimentos." - Bruce Lee

Modelos anêmicosTive a oportunidade de participar do podcast sobre Modelos Anêmicos com a galera do .Net Architects: Giovanni Bassi, Alexandre Valente, Emmanuel Brandão e Fábio Margarito.

Esse podcast ficou muito legal, rolaram discussões muito bacanas sobre o assunto, sem falar que os comentários nos bastidores da gravacão são muito engraçados.

Espero que gostem dos tópicos apresentados no podcast.

Podcast

Post no DNA

http://podcast.dotnetarchitects.net/2010/03/podcast-11-modelo-anemico/

Tagged with:
 
"Nada é permanente nesse mundo cruel. Nem mesmo os nossos problemas."

NinjectRealizei nas últimas semanas uma pesquisa sobre frameworks para injeção de dependência (DI) para atender uma demanda do projeto que estou trabalhando atualmente na Mindworks. Encontrei vários frameworks bacanas, porém, pela simplicidade de configuração e de uso, acabei decidindo por estudar mais a fundo o framework Ninject.

O exemplo que vou mostrar aqui é básico, pois esse framework tem vários recursos legais que serão abordados em outros posts. Vou mostrar um pouco da teoria sobre DI e como utilizar o Ninject para aplicar esse pattern.

Quando utilizamos um componente qualquer, estamos acoplando o mesmo a nossa solução. Componentes atendem a necessidades específicas, por exemplo: Enviar e-mail, gerar pdf, compactar arquivos, etc. O que buscamos com o pattern DI é usar esses componentes sem acoplá-los diretamente a nossa solução, e basicamente conseguimos isso através de interfaces.

Vamos começar declarando uma interface IContrato. Esse interface representa uma necessidade qualquer da sua solução, e todos os seus algoritmos devem considerar apenas os membros desse interface.

1
public interface IContrato { }

A interface que criamos precisa de uma implementação concreta, pois como vimos, ela só representa nossas necessidades. O próximo passo é criar a classe Fornecedor que irá implementar a interface IContrato. Nosso desafio nesse exemplo é usar a classe Fornecedor no nosso código sem criar uma referência direta, ou seja, não poderemos usar o new para obter uma instância da classe Fornecedor.

1
public class Fornecedor : IContrato { }

A grande solução aqui é delegar a responsabilidade de intanciar os nossos componentes para um terceiro elemento, que nesse caso é o Ninject. Precisamos dizer ao Ninject qual classe queremos que resolva a interface IContrato, para isso, precisamos criar um Módulo e nele configurar os Binds.

1
2
3
4
5
6
7
8
public class Modulo : NinjectModule
{
    public override void Load()
    {
        // Configuramos para que a interface IContrato seja direcionada para a classe Fornecedor;
        Bind<IContrato>().To<Fornecedor>();
    }
}

Agora vamos a utilização do Ninject. Criei um método de teste para exemplificar como configuramos e usamos a classe Kernel, que é a classe responsável por retornar as instâncias dos componentes que precisamos a partir da interface.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[TestMethod]
public void Deve_obter_fornecedor_pelo_contrato()
{
    // Instancia o módulo;
    var modulo = new Modulo();
 
    // O Kernel é a classe responsável por fornecer as instâncias necessárias para o código;
    IKernel kernel = new StandardKernel(modulo);
 
    // O método Get devolve a instância da classe mapeada para a interface;
    IContrato meuContrato = kernel.Get<IContrato>();
 
    Assert.IsNotNull(meuContrato);
    Assert.IsInstanceOfType(meuContrato, typeof(Fornecedor));
}

Como vimos anteriormente, podemos solicitar ao Kernel uma instância de classe manualmente, porém, o Ninject possibilita configurar as dependências de uma classe a partir do atributo [Inject]. Vamos declarar uma classe chamada Servico com uma propriedade do tipo IContrato.

1
2
3
4
5
public class Servico
{
    [Inject]
    public IContrato Fornecedor { get; set; }
}

Vamos aos testes. Podemos perceber no teste abaixo que o método Inject da classe Kernel resolve todas as dependências da instância da classe Servico.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[TestMethod]
public void Deve_resolver_dependencias_manualmente()
{
    IKernel kernel = new StandardKernel(new Modulo());
 
    // A instância normal não tem as dependências resolvidas;
    var servico = new Servico();
 
    Assert.IsNull(servico.Fornecedor);
 
    // O método Inject resolve as dependências da instância usando como marcador o atributo [Inject];
    kernel.Inject(servico);
 
    Assert.IsNotNull(servico.Fornecedor);
    Assert.IsInstanceOfType(servico.Fornecedor, typeof(Fornecedor));
}

Nesse teste, percebemos que se solicitarmos uma instância da classe Servico diretamente ao kernel do Ninject, o mesmo já resolverá as dependências internas da classe.

1
2
3
4
5
6
7
8
9
10
11
[TestMethod]
public void Deve_resolver_dependencias_automaticamente()
{
    IKernel kernel = new StandardKernel(new Modulo());
 
    // Quando solicitamos uma instância de classe, a mesma é devolvida com as dependências resolvidas.
    var servico = kernel.Get<Servico>();
 
    Assert.IsNotNull(servico.Fornecedor);
    Assert.IsInstanceOfType(servico.Fornecedor, typeof(Fornecedor));
}

Como vimos, o grande truque aqui é delegar a responsabilidade de criação das instâncias para o kernel do Ninject. Como não utilizamos em nenhum momento o new para instanciar a classe Fornecedor, podemos substituí-la só alterando o Bind na classe Módulo.

Posteriormente vou postar outros artigos sobre Ninject focando em características mais específicas do framework.

Para mais referências, visite a tag Ninject no delicious: delicious.com/denisferrari/Ninject

Você pode baixar o projeto pelo Google Docs: Faça o Download

Abraços!

Tagged with: