quinta-feira, 5 de novembro de 2009

TDD: primeiras impressões

Embora já tenha quase 7 anos de experiência em desenvolvimento de software, até hoje nunca trabalhei em uma empresa que se preocupasse muito em estar atualizada em termos de qualidade de software, o que ainda me frustra um pouco. Sendo assim, me dedico nas minhas "horas vagas" a estudar para ser um engenheiro de software ou simplesmente um profissional melhor, como diz o Alexandre Gomes.

Ultimamente, me entreguei à experimentação de TDD (Test Driven Development). Já tinha ficado muito entusiasmado quando aprendi sobre testes unitários automáticos, pelos motivos já amplamente citados em qualquer pesquisa sobre o assunto que você fizer no google. Agora experimentando TDD me dei conta de outra coisa, talvez óbvia para quem é experiente TDDista: TDD te leva, ou melhor, literalmente te induz, diretamente, implicitamente, a manter o foco no DOMÍNIO. Quem entende essa outra sigla de 3 letrinhas aqui: DDD, sabe do que eu estou falando. Raciocínio simples: com TDD você implementa requisitos (ou histórias) funcionais do seu cliente. Cada teste é um requisito. Quando você conversa com seu cliente sobre qual o problema que ele quer resolver, ele dirá mais ou menos assim:

- Preciso de um sistema que controle minhas vendas.
- Hum, beleza. Como é o seu método de vendas?
- Simples. Criamos um pedido de acordo com o especificado pelo cliente. Depois que está tudo ok, emitimos a nota fiscal e enviamos a mercadoria.
- Ok. E o que faz "tudo ficar ok"?
- Ah. Basicamente, o cliente precisa aprovar o pedido para que possamos faturar.
- Legal. O que vocês repassam para o cliente para que ele aprove o pedido?
- Basicamente só o valor total do mesmo.
- Ok. E o total do pedido eu presumo que seja a soma dos totais dos seus itens, certo?
- Correto.

Primeiro requisito implementável: o total do pedido deve ser igual a soma dos totais dos itens da ordem (tá, eu sei, exemplo manjado, mas é muito fácil de entender, pelo menos).



@Test

public void testaTotalPedido() {

Pedido pedido = new Pedido(new Cliente("Marcelo"));

pedido.addItem(new ItemPedido("parafuso",5,0.1));

pedido.addItem(new ItemPedido("mancal",3,5.0));

assertEquals(pedido.getTotal(),15.5);


--- Cliente.java ---

public class Cliente {

private String nome;

public Cliente(String nome) {

this.nome = nome;

}

//getters...

}

--- Pedido.java ---

public class Pedido {

private final Cliente cliente;

private Set items;

public Pedido(Cliente cliente) {

this.cliente = cliente;

this.items = new HashSet();

}

public void addItem(ItemPedido item) {

this.items.add(item);

}

public double getTotal() {

Iterator itItens = this.items.getIterator();

double result = 0.0;

while (itItens.hasNext()) {

result += itItens.next().getValorTotal();

}

return result;

}

}

--- ItemPedido.java ---

public class ItemPedido {

private String descricao;

private double valorUnitario;

private int quantidade;

public ItemPedido(String descricao, int quantidade, double valorUnitario) {

this.descricao = descricao;

this.quantidade = quantidade;

this.valorUnitario = valorUnitario;

}

public double getTotal() {

return this.valorUnitario * this.quantidade;

}

}



O exemplo é ridículo, eu sei. Mas o que eu quis mostrar aqui é que o que foi criado até agora foram CLASSES DE DOMÍNIO, ou seja, o que realmente interessa. Não tem DAO, não tem View, não tem IO, nem outra porquera qualquer por que isso é secundário e é o mais fácil de resolver. FOCO NO DOMÍNIO.

- Resolve primeiro o problema do cliente, pô. Sem frescura.

quarta-feira, 15 de julho de 2009

SOLID principles

- Hey boy! We will work in a brand new project. It's awesome, isn't it?
- Yes, it is. It's a chance to put some "best practices" to work.
- What you mean? What "best practices"?
- SOLID.
- SOLID!? WTF is that?
- OO principles:

Single responsability principle: a class must have just one reason to change.

Open-closed principle: a class behavior must be open for extension and closed for modification.

Liskov substitution principle: Derived classes must be substitutable for their base classes.

Interface segregation principle: Make fine grained interfaces that are client specific.

Dependency inversion principle: Depend on abstractions, not on concretions.

- Principles! Sounds great! Where can I find more information about them?
- At butunclebob.com.
- Ok! Let's start reading.

terça-feira, 9 de junho de 2009

Frase do dia IV

"The tests eliminates fear [of clean the mess]."
Robert Martin (Uncle Bob), in RailsConf2009

It was a great presentation about test driven development. It's worth to watch it.

sexta-feira, 1 de maio de 2009

Sorteio

Ei!
Que tal ganhar um Ipod touch?

O Jornal Tecnologia estará sorteando no aniversário de 1 mês. Clique aqui para concorrer.

E boa sorte.

Feedback Porto Alegre Agile Weekend

No último final de semana (25 e 26 de abril), estive participando de um grande evento de tecnologia do RS. Eu sei que já deveria ter postado alguma coisa antes, mas ainda não sou um bom blogueiro e estava aguardando os slides para poder dar um relato mais rico.

O Agile Weekend foi muito bom. Mais de 380 pessoas se reuniram no prédio 32 da PUC Porto Alegre para assistir a palestras, workshops e oficinas de profissionais do mais alto gabarito e de todos os cantos do Brasil.

A abertura do evento ficou por conta dos organizadores Daniel Wildt e Luiz Parzianello, falando sobre o uso de Lean em gerenciamento de projetos de software. Embora já tivesse lido algumas coisas a respeito, foi uma palestra muito bem conduzida e esclarecedora. Percebi que na Cantú & Stange cometemos alguns dos desperdícios mencionados na palestra.

Depois do coffee-break, assisti a apresentação de Adail Retamal, da Heptagon, sobre TOC e Corrente Crítica. Este deu dicas de como estimar a entrega do software através da Teoria das Restrições sobre a Corrente Crítica do projeto. Aprendi algumas coisas sobre FDD também.

Na hora do almoço, eu e meus colegas nos reunimos em uma mesa e começamos a falar sobre Scrum, já que eles tinham assistido a apresentação do Samuel Crescêncio dando uma introdução rápida sobre o assunto. O assunto tomou conta de todas as discussões do nosso grupo dali em diante.

De barriga cheia, fomos todos participar da oficina do Luiz e do Rafael Prikladnicki, entitulada "Jogos estatísticos para a promoção de práticas ágeis". O Luiz e o Rafael foram excelentes, iniciaram falando sobre a mudança de cultura exigida para se iniciar no mundo das Metodologias Ágeis. As dinâmicas nos fizeram compreender muito bem alguns dos princípios ágeis, como small releases e o trabalho em equipe sem distinção de funções.

Depois de outro coffe-break, fomos participar do workshop que eu mais esperava no sábado: "Simulação de um projeto scrum com uma mini Fábrica de aviões". O criador, Flávio Steffens, juntamente com o Rafael, nos fez perceber como podemos esquecer de certos aspectos ao iniciar um projeto, tal como ouvir todos os detalhes dos requisitos quando já temos uma idéia de como devemos desenvolver algo e como é fácil esquecer de requisitos implícitos. Além de tudo isso, foi uma aula sobre sprints, ajustes de equipe e estimativas. Foi excelente, atendeu a todas as minhas espectativas.

No domingo, eu estava particularmente ansioso para assistir ao case dos brasilienses da SEA. O Bruno Pedroso, Renato Willi e Alexandre Gomes trouxeram um relato riquíssimo sobre a implantação de metodologias ágeis na Força Aérea. Novamente foram os detalhes que mais me chamaram a atenção: a simplicidade com que foram implantando as técnicas um passo por vez, a maneira como foram conquistando o respeito do cliente, etc. Mas o que mais me chamou a atenção foi a sensibilidade da equipe, aqui relatada pelo Alexandre, de perceber que nem sempre software funcionando é trabalho bem feito. Temos de levar em consideração a doutrina, os costumes e as manias do cliente (no caso deles, era a Força Aérea). Respeitar o cliente para sermos respeitados por ele. Grande ensinamento.

Novo coffee-break para depois participar do case do catarinense Samuel Crescêncio, onde nos foi apresentado o framework para testes de performance desenvolvido por sua equipe na OnCast. O Lobo, como é chamado, é interessante pois segue o padrão XUnit e portanto é muito fácil de usar. Ele é capaz de gerar gráficos dos testes de performance em cada novo build da aplicação. Bem legal. Por enquanto não precisamos, mas se precisar, já sei onde encontrar. Ah, é a turma do Samuel que está organizando o Agiles 2009, evento latino-americano sobre metodologias ágeis, que ocorrerá em Florianópolis no mês de outubro. Reserve este final de semana na sua agenda. Vale a pena.

Logo depois, a palestra do Gustavo Casarotto reuniu metodologias ágeis e gestão de negócio. Gustavo, entre outras coisas, falou sobre a inversão da pirâmide: uma equipe motivada faz muito bem o seu trabalho, deixando o cliente satisfeito. Reflexos do Manifesto Ágil.

Depois do almoço, uma palestra excelente do Bruno Pedroso: "Agilizando seu projeto de software". Um passo a passo que reuniu a experiência dele, eu imagino, na implantação de metodologias ágeis nos clientes da SEA. Ele foi muito detalhado e com boa desenvoltura, foi como responder a todas as dúvidas de como conduzir uma equipe à excelência ágil. Parecia a palestra perfeita para mim e meus colegas da Cantú & Stange, todos newbies de metodologias ágeis.

A última palestra, entitulada "O uso de indicadores de desempenho em projetos ágeis", do Carlos Fabris, me fez perceber que podemos aplicar o conceito de indicadores muito facilmente na Cantú & Stange. Extremamente simples, o Carlos trouxe novamente os conceitos Lean e exemplificou como podemos medir o desperdício e as falhas em um projeto de software. A palestra foi muito útil, pois na segunda-feira seguinte ao Agile Weekend, o Fábio, gerente de atendimento a clientes da empresa onde trabalho, cedo pela manhã fez com que surgisse um indicador no nosso processo de desenvolvimento.

Resumindo (eu sei que o post ficou meio grande, mas eu queria dar um feedback para cada uma das palestras que assisti): foi excelente. Tudo isso sem falar das conversas de corredor e discussões paralelas nos intervalos. Todos os organizadores estão de parabéns.

Podem reservar um lugar para mim no Porto Alegre Agile Weekend 2010.

segunda-feira, 23 de março de 2009

Saia da jaula

Lendo esse post de Jeff Atwood hoje, tive vontade de expressar a minha opinião sobre um assunto bastante recorrente nas listas de discussão que participo.

Recentemente houve uma calorosa (e inútil, na minha opinião) discussão na lista Agile-Brasil sobre o software craftsmanship manifest. Não venho aqui falar do manifesto citado, mas sim da discussão em torno deste.

Muitos colegas, preocupados em conhecer e aplicar as melhores práticas em desenvolvimento de software devoram livros e livros e artigos e manifestos e... para fazer o melhor software possível. Isso é ótimo, também gosto disso. Um sólido embasamento teórico é fundamental para um bom desenvolvedor. Porém, alguns destes indivíduos ficam tão bitolados que acabam construindo uma espécie de jaula com esses princípios, regras e metodologias, sem nunca ir além, enxergar adiante. Ou seja, criam um dogma.

Não sou nenhum grande desenvolvedor de software, sou somente mais um tentando ganhar a vida neste meio. Porém, por mais ignorante que eu seja, não consigo deixar de criticar essa postura de alguns colegas.

Não falo só do fanatismo do mundo ágil, mas de todo fanatismo dentro do universo de TI, mais precisamente desenvolvimento de software. Algo como javeiros em relação a orientação a objetos, padrões de projeto ou padrões de arquitetura: “Essa classe não está bem construída, tal coisa não é responsabilidade dela.”, “Essa é uma atribuição da camada de infra-estrutura, não da camada de aplicação.”, “O padrão State não é assim, é assado, então você não está aplicando o padrão de projetos da forma correta. Pode até funcionar, mas está errado.”. Tudo bem, acho interessante você ter algumas regras para desenvolver um sistema eficiente, ou para ter um processo de geração de valor eficiente. Porém, eu acredito que manifestos, princípios, teorias e afins não são fatídicos (“isso DEVE ser assim, se NÃO for assim, está ERRADO”), mas sim, são guias, referências para ajudá-lo a desenvolver os seus próprios métodos, que seja seguindo o original, seja adaptando-o para a sua realidade.

Parece que não são capazes de pensar e agir por si mesmos. Ficam cavando teorias para seguirem o tempo todo, quase que cegamente. “Se Martin Fowler falou, então é assim que deve ser.”. Pôxa! Eu sou da opinião que a única diferença entre você e qualquer outro grande nome do cenário mundial são os projetos onde eles trabalharam, as oportunidades que tiveram. Não estou dizendo que eles não tenham talento, jamais quis dizer isso. Só estou tentando dizer que talvez você seja tanto quanto ou mais talentoso que eles, basta se lançar a desafios que exijam criatividade, ousadia e iniciativa.

Para mim, o único manifesto que você realmente DEVE seguir é o seu cliente sorrindo e você com dinheiro no bolso. Afinal, de nada adianta seguir 3497534 regras, princípios e manifestos se o cliente não fica satisfeito. De nada valeu estudar tanto e se matar para colocar o sistema dentro da “jaula” se o maior interessado no sistema não ficou satisfeito. É para o cliente que fazemos software, sem ele, nem existiríamos como programadores.

Então, estude, leia, se atualize, mas não se prenda ao que o maior cientista do mundo da computação disse. Adapte o que você aprende a sua realidade, não adapte a sua realidade ao que você aprende. Jogue fora o que não serve para você. Não perca semanas tentando formalizar uma funcionalidade em 3 padrões que o GoF escreveu se você consegue o mesmo resultado com a sua própria idéia, que é muito mais simples.

Ou seja: saia da jaula.

domingo, 25 de janeiro de 2009

DDD Aprenda em 24 horas

Um amigo meu (acho que deve ser o único leitor deste blog) me mandou o seguinte e-mail:


Oi,

saiu o novo curso de DDD da Microsoft:
http://www.codeplex.com/AppArch/Wiki/View.aspx?title=How%20To%20-%20Domain%20Driven%20Design&referringTitle=Home

Vamos fazer?


- Humm! - pensei. - Curso de DDD da Microsoft? Vale a pena dar uma olhadinha.

Depois de um minuto ou dois, respondi para meu amigo:

Vale a pena dar uma olhada.. mas pelo meu overview de 15 segundos.. já vi uma mistura de conceitos:


public class AccountFactory : IFactory
{
public object Create()
{
return new Account();
}
public object GetById( string Id )
{
using( AccountRepository repository =

new AccountRepository())
{
return repository.GetAccountById( Id );
}
}
}


Para quê uma factory para essas situações se ela simplesmente delega a função para outro objeto? Tá usando um padrão de projeto sim: o Chain of responsability, porém sem a mínima necessidade. Factories e Repositories são coisas diferentes no DDD, usa-se uma Factory para criar objetos que ainda não foram persisitidos (usando as palavras do mentor Eric: controlam o 'nascimento' do objeto'), enquanto que um Repository serve para manipular objetos já existentes - ou persistidos - (novamente, segundo o grande sábio: controlam o ciclo de vida do objeto DEPOIS do nascimento). As Factories DDD não tem a ver (a meu ver) com o padrãoFactory Method ou Abstract Factory do GoF, mas sim com o padrão - dos mesmos mestres - Builder.

Lógico... isso sob o ponto de vista do DDD. Na minha opinião, tudo deve ser adaptado para suas necessidades.


Não quero questionar o curso ou não. O objetivo deste post é apenas enfatizar que não existem regras rígidas para se desenvolver um bom software. A única regra que você realmente DEVE seguir é:

Ele funciona? E se funciona, funciona do jeito que o cliente quer?

Não adianta você desenvolver o melhor sistema para controle financeiro se o que o cliente precisa é um simples relatório de fluxo de caixa.

Ou seja, não adianta seguir padrões às cegas, gastar horas estudando como adaptar determinada situação às últimas tendências se no final o cliente vai dizer:

- Não era isso que eu queria!