Arquivo para janeiro 2009
Primeiros passos com Fluent NHibernate
Acredito que não sou o único que ficou “mal-acostumado”; com a facilidade trazida pela tecnologia Linq to SQL (L2S) que a Microsoft lançou no ano passado.
Infelizmente, há poucos meses a Microsoft anunciou baixinho que não iria mais desenvolver o mesmo L2S, e recomendou que todos adotassem em seu lugar Entity Framework, que, se por um lado é uma plataforma mais robusta, por outro lado é mais complexa, e, assim como L2S, atraiu muitas críticas de puristas que consideram essa plataforma difícil de estender e testar via unit tests.
Isso fez com que muitas empresas, incluindo a que eu trabalho, começasse a ver quais alternativas existem para O/RM, e de fato existe um produto no mercado que é livre e que já provou seu valor: NHibernate. Algo me diz que 2009 vai ser o ano que NHibernate vai entrar de fato na caixa de ferramentas da maioria dos desenvolvedores intermediários e avançados, ainda mais com o recente desenvolvimento da biblioteca Linq2NHibernate (L2NH) e Fluent NHibernate, esse último uma forma de configurar NHibernate usando código ao invés de arquivos XML.
Como nunca usei NHibernate nem L2NH, mas pretendo em muito breve, vou cobrir nesse artigo e nos próximos os primeiros passos com essa plataforma. Meu plano é usar esse código como base para um aplicativo ASP.NET MVC que também quero blogar aqui em forma de tutorial.
Pra dar uma visão melhor de onde quero chegar, o aplicativo que pretendo desenvolver é uma “Estante de livros virtual”, que me permita cadastrar livros (titulo, autor, imagem de capa etc) manualmente ou através de procura na Amazon, bem como marcar quais livros eu pretendo comprar, estou atualmente lendo e emprestei para alguém. Numa segunda fase esse aplicativo deverá suportar diferentes usuários. Ainda que eu não pretenta seguir práticas estritamente TDD, vou procurar criar unit tests para a maior parte do meu código.
Criando o modelo
Antes de mais nada vou iniciar uma solução nova, Bookshelf, com dois projetos: Bookshelf.Model e Bookshelf.Tests. O primeiro vai conter classes do tipo POCO (Plain Old C# Object), que significa classes que não têm qualquer conhecimento sobre qual plataforma é usada para armazenamento. Métodos como book.Update() e book.Delete() não vão existir aqui. Isso é uma forma de seguir o princípio de responsabilidade única, que mencionei num post anterior.

O modelo inicial é extremamente simples: uma única classe, Book (vou escrever o código em inglês, incluindo nome de classes e comentários, pois vou compartilhá-lo com alguns colegas de trabalho noruegueses).
namespace Bookshelf.Model
{
public class Book
{
public int ID { get; private set; }
public string ISBN { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public int ReleaseYear { get; set; }
}
}
O próximo passo é mapear esse modelo, ou seja, ensinar ao NHibernate a acessar essa classe e como a mesma deverá ser representada no banco de dados. O NHibernate pode tanto mapear bancos de dados já existentes quanto criar novos bancos de dados.
namespace Bookshelf.Model.Mapping
{
public class BookMap : ClassMap
{
public BookMap()
{
Id(x => x.ID);
Map(x => x.ISBN).CanNotBeNull();
Map(x => x.Title).CanNotBeNull();
Map(x => x.Author);
Map(x => x.ReleaseYear);
}
}
}
Como o nome diz, dá pra ver que a leitura desse código é bem fluente, e todos os métodos são encadeáveis, podem ser colocados uns após os outros formando “frases”; ou uma DSL rudimentar. O único encadeamento que fiz por enquanto foi ao usar CanNotBeNull() para os campos que não quero que sejam nulos. Para que esse código compilasse, tive que adicionar duas referências: NHibernate.dll e FluentNHibernate.dll (todas DLLs necessárias estão incluídas no código-fonte, no final do artigo).
Testando o mapeamento
Agora já podemos testar esse mapeamento, pra ver se funciona mesmo. No meu projeto Bookshelf.Tests vou criar uma classe BookTests. Também vou precisar de uma classe FixtureBase que vai ser a base de todas minhas classes para testes, vai conter o código a ser reutilizado.
Vou começar por adicionar algumas referências: nunit.framework.dll, NHibernate.dll, FluentNHibernate.dll e FluentNHibernate.framework.dll. Nesse caso vou usar NUnit, mas qualquer outra biblioteca de testes poderia ser usada.
namespace Bookshelf.UnitTests
{
public class FixtureBase where TModel : PersistenceModel, new()
{
protected SessionSource SessionSource { get; set; }
protected ISession Session { get; private set; }
[SetUp]
public void SetupSession()
{
var cfg = new SQLiteConfiguration()
.InMemory()
.ShowSql();
SessionSource = new SessionSource(cfg.ToProperties(), new TModel());
Session = SessionSource.CreateSession();
SessionSource.BuildSchema(Session);
Session.Flush();
Session.Clear();
}
[TearDown]
public void TearDown()
{
Session.Close();
Session.Dispose();
}
}
}
O mais interessante aqui é o método SetupSession(), no qual criamos um banco de dados SQLite que vai rodar na memória apenas. Isso significa que os testes serão extremamente rápidos. Ao usarmos SQLite nos testes não significa que nosso programa propriamente dito terá que usar SQLite também, se quisermos usar SQL Server ou Oracle basta usarmos uma configuração diferente, seja via XML, seja usando a sintaxe fluente parecida com a acima. O método ShowSql() fará que toda vez que um comando ao banco de dados seja executado, o SQL será mostrado no console.
Session é equivalente ao DataContext no Linq2SQL, é o objeto usado para disparar comandos no NHibernate.
Vamos agora dar uma olhada na nossa classe de teste:
namespace Bookshelf.UnitTests
{
public class BookTestModel : PersistenceModel
{
public TestModel()
{
addMappingsFromAssembly(typeof(BookMap).Assembly);
}
}
[TestFixture]
public class BookTests : FixtureBase
{
[Test]
public void Can_Insert_Books()
{
//Arrange
var book = new Book
{
ISBN = "123456",
Author = "Isaac Asimov",
Title = "Foundation Trilogy",
ReleaseYear = 1950
};
//Act
Session.Save(book);
Session.Flush();
//Assert
Session.Clear();
var dbBook = Session.Get(book.ID);
Assert.AreNotSame(book, dbBook);
Assert.AreEqual(book.ID, dbBook.ID);
Assert.AreEqual(book.Title, dbBook.Title);
Assert.AreEqual(book.ISBN, dbBook.ISBN);
Assert.AreEqual(book.ReleaseYear, dbBook.ReleaseYear);
}
}
}
Na verdade temos duas classes aqui: a primeira, BookTestModel, serve apenas para aplicar o mapeamento que definimos em BookMap. Como a classe BookTests deriva de FixtureBase, o código de setup de FixtureBase será executado para configurar nosso banco de dados de acordo com o mapeamento de BookTestModel.
Finalmente, o teste insere um livro no banco de dados (lembrando que nesse caso é um banco de dados na memória, mas poderia muito bem ser um físico), e depois busca o livro do banco de dados e compara as propriedades. Assert.AreNotSame garante que não estamos nos referenciando ao mesmo livro na memória.
Hora de executar o teste!

Perfeito! Repare que os comandos SQL também foram impressos.
Se quiser testar o código você mesmo, baixe aqui.
Num próximo artigo, vamos começar a usar Linq2NHibernate para criar a aplicação MVC.
Em busca de uma arquitetura sólida – Parte 2
Olá,
Na segunda parte de nossa série sobre princípios S.O.L.I.D., vamos analisar a segunda letra do acrônimo, O. Caso você não tenha lido a introdução a essa série, recomendo que dê uma passadinha lá antes de prosseguir.
Como vimos lá, a letra O representa o princípio Open-Closed, ou seja, Aberto-Fechado. O enunciado desse princípio é simples:
Uma classe deve ser aberta para extensão, e fechada para mudanças.
Ora, todo bom programador não busca escrever código que seja fácil de ser mantido, ou seja, fácil de mudar? E como o sistema pode mudar se minhas classes estão fechadas para mudança?
Mudanças são inevitáveis, a questão é minimizar riscos e facilitar testes. A idéia é reduzir ao máximo o número de mudanças que temos que fazer em classes já existentes (de preferência, a zero), e ao invés disso implementar mudanças através de novas classes que podem ser “plugadas” ao sistema, como blocos em um Lego.
Vamos ver como isso funciona com um exemplo prático. Suponha que você está encarregado de desenvolver um sistema que suporte busca de usuários por email. Uma forma de implementar isso seria
public class Procura
{
public IEnumerable<Usuario> ProcuraUsuarioPorEmail(string email)
{
//efetua a procura no banco de dados
}
}
E seu programa principal seria mais ou menos assim:
Procura p = new Procura();
var resultado = p.ProcuraUsuarioPorEmail("usuario@meusistema.com.br");
Bem, nada mal. O código funciona, e o cliente está satisfeito. Pelo menos até a próxima semana, que ele te pede que implemente agora uma busca por nome.
Sem problemas, você abre sua classe e faz algumas alterações:
public class Procura
{
public IEnumerable<Usuario> ProcuraUsuarioPorEmail(string email)
{
//efetua a procura no banco de dados
}
public IEnumerable<Usuario> ProcuraUsuarioPorNome(string nome)
{
//efetua a procura no banco de dados
}
}
Essa solução, a princípio, não é de todo ruim. Funciona, e seu código ainda é legível. A questão é, à medida que tais mudanças forem se acumulando com o passar dos meses e anos, quão complexa será sua classe?
Todos nós conhecemos a dor de abrir uma classe pra manutenção rápida e deparar com 200 linhas de código, muitas vezes se uma ordem lógica (ninguém tem tempo pra ficar colocando métodos similares em blocos), o que sempre nos deixa com medo que nossa mexida rápida cause problemas em algum lugar que nem sabíamos que existia.
Como poderíamos então fechar nossa classe pra mudança, mas mesmo assim permitir que o sistema evolua? A chave é extensão, e existem várias estratégias para tal.
Vamos olhar uma dessas possibilidades. Uma idéia boa de seguir quando desenhamos classes é separar o que é constante do que varia. No nosso caso, o que é constante é a necessidade de buscar usuários. O que varia é a estratégia usada para tal busca.
Podemos então definir uma interface para busca genérica, e uma classe que use tal interface, que representam as partes constantes da equação:
public interface IEstrategiaDeProcura
{
IEnumerable<Usuario> EfetuaProcura(string criterio);
}
public class Procura
{
private IEstrategiaDeProcura _estrategia;
public Procura(IEstrategiaDeProcura estrategia)
{
_estrategia = estrategia;
}
public IEnumerable<Usuario> EfetuaProcura(string criterio)
{
return _estrategia.EfetuaProcura(criterio);
}
}
Embora tal estrutura pareça mais complicada a princípio, a grande vantagem é que essas duas classes não terão mais que mudar tão cedo, podemos agora plugar quantas estratégias diferentes quisermos. O que fizemos na classe de procura é injetar a estratégia que ela deverá usar, ainda que ela não saiba nem tenha que saber qual estratégia concreta seja. Com isso estamos atendendo a outro princípio de boa pragramação OO que é programar em cima de abstrações, não classes concretas. Veja que ao reescrevermos essa classe também atingimos o princípio de responsabilidade única! Antes nossa classe tinha dois motivos para mudar (caso a procura por nome ou email mudassem, respectivamente), agora ela tem apenas um motivo para mudar, por tem apenas um simples método genérico. Como dizem os capixabas, matamos dois coelhos com uma caixa d’água só!
A busca por email e nome então implementariam tal interface, e serão usadas pela classe de procura:
public class ProcuraPorEmail : IEstrategiaDeProcura
{
public IEnumerable<Usuario> EfetuaProcura(string criterio)
{
//efetua a busca por email
}
}
public class ProcuraPorNome : IEstrategiaDeProcura
{
public IEnumerable<Usuario> EfetuaProcura(string criterio)
{
//efetua a busca por nome
}
}
E tais implementações seriam usadas assim:
var p = new Procura(new ProcuraPorEmail());
var resultado = p.EfetuaProcura("usuario@meusistema.com.br");
De agora em diante, toda vez que o cliente pedir um novo tipo de procura, basta implementar uma nova classe para a interface IEstrategiaDeProcura, escrever alguns unit tests para a nova classe, e pronto. Reduzimos em muito a chance de quebrar algo que antes funcionava, que é o grande problema em manutenção de sistemas.
Claro, esse exemplo é bem simples (por exemplo, não trata de procuras mais complexas), mas quis manter o exemplo simples para que o princípio Aberto-Fechado ficasse claro, sem distrações.
Seguindo esse princípio você estará abrindo possibilidades para que seu sistema seja extensível, por exemplo para que outras pessoas escrevam módulos de procura que você não implementou, mesmo que eles não tenham acesso ao código-fonte.
Até a próxima!
Em busca de uma arquitetura sólida – Parte 1
Ultimamente venho lendo bastante sobre boas práticas de programação, em especial as promovidas pela comunidade ALT.NET.
Da sopa de letras que sempre nos vemos quando começamos a fazer esse tipo de pesquisa (DDD, TDD, BDD, DI, IoC, etc etc) o que parece trazer maior consenso são os princípios defendidos por Robert C. Martin para o desenvolvimento de código orientado a objetos, detalhados em seu artigo “The Principles of OOD”, que buscam reduzir o acoplamento, facilitar o gerenciamento de dependências, e aumentar a coesão, mantenabilidade e testabilidade de código, e que atendem pela sigla S.O.L.I.D.:
- Single Responsibility Principle, ou Princípio de Responsabilidade Única;
- Open-Closed Principle, ou Princípio Aberto-Fechado;
- Liskov Subtituition Principle, ou Princípio de Substituição de Liskov;
- Interface Segregation Principle, ou Princípio de Segregação de Interface;
- Dependency Inversion Principle, ou Princípio da Inversão de Controle.
Nesse e nos próximos posts, irei explicar cada um desses princípios, procurando mostrar quais vantagens eles trazem para nós programadores OO. Vamos então começar com a letra S
O Princípio da Responsabilidade Única (SRP)
Robert Martin define assim esse princípio:
Uma classe deve ter apenas um motivo para mudança.
Uma outra definição popular desse princípio é:
Uma classe deve ter uma e apenas uma responsabilidade.
Se a ligação entre essas duas definições não é muito clara, basta pensar o seguinte: quanto mais responsabilidades uma classe possui, quanto mais tarefas uma classe executa, maior o número de pontos de mudança na mesma.
Muitas vezes não é possível seguir tal princípio ao pé da letra, por questões práticas, mas ao buscarmos seguir tal ideal teremos classes mais coesas, fáceis de entender, alterar e testar.
Vamos olhar um exemplo prático, uma classe típica que todos nós já desenvolvemos aos montes: nessa classe, uma lista de preços é lido de um banco de dados, um determinado índice é buscado em um serviço web, esse índice é então aplicado em todos os preços e finalmente os novos preços são salvos no banco de dados.
namespace SOLID.SRP
{
public class Indexador
{
public void AtualizaPrecos()
{
var precosAtuais = CarregaPrecosAtuais();
var indiceAtual = BuscaIndiceCorrente();
//aplica o indice atual em todos os valores
var precosAtualizados = ....
SalvaPrecosAtualizados(precosAtualizados);
}
private IEnumerable<double> CarregaPrecosAtuais()
{
//busca os valores no banco de dados da empresa
}
private double BuscaIndiceCorrente()
{
//busca o indice atual, em um servico na web
}
private void SalvaPrecosAtualizados(IEnumerable<double> valoresAtualizados)
{
//grava os valores atualizados no banco de dados da empresa
}
}
}
A gente sabe que esse tipo de classe começa simples, mas logo complica: um dia alguém descobre que, caso o serviço que fornece os índices esteja fora do ar, a classe deverá ler o índice de um arquivo texto; depois um bug é arquivado, informando que o índice não deve ser aplicado em fins-de-semana e feriados, e para tanto vamos precisar integrar algum tipo de calendário de feriados na classe. Rapidamente, nos vemos com uma classe com 900 linhas de código, e que ninguém entende direito!
Para aplicar o SRP, basta checar quantos motivos diferentes conseguimos ver para que a classe tenha que mudar:
- Mudança na estrutura ou tipo de banco de dados;
- Mudança no serviço de índices;
- Mudança em como o índice é aplicado aos preços
Vamos tentar então isolar cada um desses elementos. Como o índice pode agora vir tanto de um serviço web quanto um arquivo text, acho que faz sentido criar uma interface com um método BuscaIndiceCorrente, de forma que podemos implementar uma classe que busque tal índice da web, e outra que busque tal índice de um arquivo texto. Como a classe Indexador vai referenciar a interface, e não uma das classes concretas, fica fácil trocar a estratégia em tempo de execução, bem como criar uma classe “fake” em nossos testes (unit tests) que retorne um valor qualquer. Matamos 2 coelhos com uma pedrada!
O mesmo conceito será seguido para o repositório de preços.
Aqui está a declaração da interface:
namespace SOLID.SRP
{
public interface IServicoIndice
{
double BuscaIndiceCorrente();
}
}
Aqui então está a nossa classe principal. Note que as suas dependências (o serviço de índices e o repositório de preços) são passados à classe no seu construtor. É como se disséssemos à classe “faça o que você sabe fazer, e aqui estão as ferramentas que você vai precisar”. Como disse anteriormente, note que fica fácil então trocarmos essas ferramentas quando necessário, mesmo em tempo de execução…uma arquitetura bem elegante, e que retornaremos no futuro
namespace SOLID.SRP
{
public class Indexador
{
private IServicoIndice _servicoIndice;
private IRepositorioPrecos _repositorio;
public Indexador(IServicoIndice servicoIndice, IRepositorioPrecos repositorio)
{
_servicoIndice = servicoIndice;
_repositorio = repositorio;
}
public void AtualizaPrecos()
{
var precosAtuais = _repositorio.CarregaPrecosAtuais();
var indiceAtual = _servicoIndice.BuscaIndiceCorrente();
//aplica o indice atual em todos os valores
var valoresAtualizados = ..... ;
_repositorio.SalvaPrecosAtualizados(valoresAtualizados);
}
}
}
Em nosso novo código, vemos que agora cada classe é responsável por apenas um tipo de tarefa, e tem apenas um motivo para mudar. Sucesso!
Daqui a uns dias postarei um novo artigo cobrindo o “O” de SOLID. Abraços!
Console.WriteLine(“Hello World”);
Olá, esse é o primeiro post nesse novo blog. Vou deixar as apresentações de lado (no fundo, no fundo, não interessa muito), e informar que esse blog vai tratar de desenvolvimento em .NET, principalmente para web, mas também cobrindo aspectos de análise de sistemas, best practices, e tecnologias específicas que me interessam tal como javascript e, quem sabe, um pouco de Python.
Eu costumava escrever para o site linhadecodigo.com.br, onde ainda pode-se encontrar artigos antigos meus…mas, como 1 ano na web valem 7 do lado de fora, esses artigos estão um tanto quanto desatualizados.
Como venho estudando no momento ASP.NET MVC, jQuery, YUI e princípios relacionados a ALT.NET e S.O.L.I.D., meus primeiros posts devem focar nesses temas.
Bem-vindo e por favor sinta-se livre para entrar em contato.