Archive for the ‘engenharia’ Category

Expressividade no Código

Friday, December 28th, 2007

Um post no GUJ mais uma vez rende uma resposta maior do que se supunha. A thread em si é bastante útil mas existe muito ruído então vou tentar sumarizar:

Vocês pegam códigos que te faz passar horas e horas tentando entender o que está sendo feito? Valores que você nem imagina de onde estão vindo?

Eu sou muito ruim ou isso é normal?

E logo surge alguém sugerindo que deveria haver documentação. Existem casos onde documentação, seja JavaDoc, especificação funcional ou etc. é fundamental mas neste caso é diferente. JavaDoc, especificação textual e etc. devem ser uma fonte importante quando que está interessado nessa informação não vai lero código, é como reutilizar uma biblioteca ou um framework. Ninguém quer abrir o Spring para entender como utilizá-lo, precisamos de documentação para isso.

Um cenário completamente diferente é quando você recebe de presente um código já existente para dar manutenção. Neste caso o código tem que fazer sentido, tem que dizer algo. Tem que ser expressivo, mostrar suas intenções claramente.

NOTA: O trecho abaixo foi escrito direto no editor de texto, sem ajuda de compilador ou IDE. Por favor me corrijam.

Qualquer programador meia-boca sabe sua linguagem. Sabe o domínio dela. Veja o trecho abaixo:

abstract class A{
 public abstract int d(){
 }
}

class B extends A{

 int z= 0;
 int x=-1;

 public B(int z, int x){
  this.z=z;
  this.x=x;
 }

 public int d(){
   if(z==15) return x + x* 0.15;
   esle return x;
 }

}

Você entendeu muito bem, tenho certeza, que A é uma classe abstrata implementada por B. Que B tem um construtor que recebe dois inteiros, os armazena e usa numa computação simples com uma ramificação abaixo. Ótimo.

Imagine que você recebeu um email do seu usuário dizendo: “Precisamos fazer com que clientes do sexo feminino que comprem mais de R$1000,00 ganhem 10% de desconto.”. Tente implementar isso no código acima enquanto eu vou almoçar.

E aí, terminou? Sim, sim, claro que é impossível sem saber d que se trata. Então depois de procurar bastante você encontra no diretório onde fica a documentação do projeto um arquivo que pode te ajudar a entender. Após umas cinquenta páginas de diagramas de alto nível inúteis explicando tudo que acontece no container web você chega a uma descrição de algo como:

A classe A tem a lógica abstrata de uma venda. As vendas são sempre feitas de acordo com critérios específicos por isso existem classes que implementam vendas específicas. No momento (01/10/2003) só existe uma implementação, na classe B, que é a venda para uma pessoa física.

A primeira coisa que você pensa é: se desde 2003 ninguém precisou de outra implementação para que essa maldita classe abstrata? Mas ants de mexer no código precisamos entendê-lo, então vamos em frente.

O méodo e questão recebe três argumentos: a quantdade em reais vendida, o sexo da pessoa (segundo código vindo do mainframe na tabela ETXS32) e se a compra é casada ou não (um booleano).

De acordo com o caso de uso UC171 o sexo do comprador é utilizado para aplicar descontos.

TABELA ETXS32
15 -> masculino
22 -> feminino

Se a compra for casada o processamento é feito delegando para outra classe, mantendo o padrão Strategy, Composite e Adapter do Decorator. Note que o Chain of Responsibility do Bridge é usado com Visitors para passar as instâncias de Flyweight pelos Interpreters[...]

Após a sequência de buzzwords de padrões é bom parar. Acho que a informação necessária já está aí em cima e olha que não se passaram nem 4 horas de procura! Vamos lá: recebemos o valor, o sexo segundo um código numérico sem lóica que vêm de outro sistema. Também é passado um boolean.. cadê o boolean?

Procurando no histórico deste arquivo no CVS (poxa vida, eles ainda usam CVS!) você vê que no meio de 2005 alguém tirou o boolean de lá com um comentário ‘Removido compra casada. Ninguém usa isso e ninguém entende isso. Ninuém vai sentir falta’. Acho que a pessoa estava correta mas ela esqueceu que existem uns 300 documentos que precisam ser revistos porque todos fazem referência a esta tal venda casada, do caso de uso, diagrama de domínio até diagrama de deployment. Cada mudança simples implica em editar 300 documentos… provavelmente mais tempo atualizando a tal documentação que o código… dá pra culpar o desenvolvedor?

Bom, agora você entende o que o código faz ao menos. Ele está aplicando um desconto de 15% para homens, você não conseguiu achar isso no caso de uso mas se ninguém está reclamando em produção é porque deve ser assim mesmo. Amanhã (afinal, você perdeu o dia inteiro hoje na ‘documentação’ do sistema) você faz a mudança.

Novo dia e você está pronto para alterar este código. Hmm… alterar pode ser muito rápido e sujo ou devagar e bem feito. Como disse o Uncle Bob recentemente sujo nunca é rápido então você opta pelo caminho com mais qualidade (e mais ético).

Como desenvolvedores profissionais escrevem testes (e gerar você deve começar por aí. Você sabe muito pouco sobre este sistema e o teste vai te dar alguma garantia que a menos esta pequena parta que está mexendo vai continuar funcionando após suas modificações. Vamos lá:

class TestVenda extends TestCase{
 public void testDeveAplicarDescontoSeSexoDoCompradorForMasculino(){
  B vendaParaUmHomem = new B(15, 100);
  assertEquals("Valor final sofreu 15% de desconto", 85, vndaParaUmHomem.d());
 }

 public void testDeveNaoAplicarQualquerDescontoSeVendaNaoCaiEmNenhumaPromocao(){
  B vendaParaUmHomem = new B(9999, 1);
  assertEquals("Valor final intacto", 1, vndaParaUmHomem.d());
 }
}

Os testes executam. Agora vamos alterar um pouco esta classe, pensando no pobre coitado que for mexer nela após você. Vamos começar agregando nomes mais expressivos:

abstract class VendaAbstrata{
 public abstract int vender(){
 }
}

class Venda extends VendaAbstrata{
 static final int NAO_INFORMADO = -1;
 static final int MASCULINO = 15;
 static final int FEMININO = 22;

 int sexoDoComprador= NAO_INFORMADO;
 int valorDaCompra=-1;

 public B(int sexoDoComprador, int valorDaCompra){
  this.sexoDoComprador=sexoDoComprador;
  this.valorDaCompra=valorDaCompra;
 }

 public int vender(){
   if(sexoDoComprador==MASCULINO) return valorDaCompra - valorDaCompra* 0.15;
   esle return valorDaCompra;
 }

}

Já está bem melhor, não? Compare com a primeira versão do código Os testes passam? Então é hora de commitar (eu acho esse neologismo horrível mas alguém sugere algo melhor?).

Vamos para o segundo round: pequeno refactoring. Já é possível fazer a alteração neste código mas anda temos tempo para deixá-lo um pouquinho mais legível, mais claro, mais expressivo. Vamos alterar:

abstract class VendaAbstrata{
 public abstract int vender(){
 }
}

class Venda extends VendaAbstrata{
 static final int NAO_INFORMADO = -1;
 static final int MASCULINO = 15;
 static final int FEMININO = 22;

 int sexoDoComprador= NAO_INFORMADO;
 int valorDaCompra=-1;

 public B(int sexoDoComprador, int valorDaCompra){
  this.sexoDoComprador=sexoDoComprador;
  this.valorDaCompra=valorDaCompra;
 }

 public int vender(){
   int valorFinalDaCompra = aplicarDescontosSobreValorDaCompra();

   return valorFinalDaCompra;

 public int aplicarDescontosSobreValorDaCompra(){

  int valorComDesconto= valorDaCompra;

  if(sexoDoComprador==MASCULINO)
   valorComDesconto = descontarPorcentagem(15, valorDaCompra);

  return valorComDesconto;
 }

 public int descontarPorcentagem(int porcentagem, int valorOriginal){
  return valorOriginal * (porcentagem / 100.0);
 }

}

Agora que tal esta versão do código + teste unitário contra a versão antiga + trezentos documentos e especificações? A implementação da regra nova ficou fácil? Acho que sim, tanto que deixo como exercício ao leitor, bem como algumas dezenas de refactorings que vão deixar o código acima decente.

A resposta curta para a thread do GUJ é: geralmente o problema não é seu mas de quem escreveu o código.

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.

-Martin Fowler, “Refactoring: Improving the Design of Existing Code “

Apresentação sobre Agile para Analistas de Negócio

Sunday, December 16th, 2007

Lendo os ThoughtBlogs hoje achei uma ótima apresentação feita por John Johnston. A idéia é introduzir os conceitos de agilidade no ponto de vista de um analista de negócios.

Já Temos Tecnologia o Suficiente

Monday, December 3rd, 2007

Estava pensando sobre o texto que escrevi ontem sobre modelos de negócio afetados por escolhas tecnológicas e acho que posso ter confundido alguém. Minha idéia não é dizer que modelo de negócio não é importante, pelo contrário este é a coisa mais importante numa empresa, apenas atentei para o fato de que as escolhas tecnológicas afetam o modelo de negócios. O caso de exemplo era sobre uma empresa com ótimo modelo e tecnologia não adequada.

Na verdade, provavelmente a tecnologia existente há alguns anos é mais que suficiente para modelar de excelente maneira qualquer domínio. O problema é que ainda somos (como indústria) amadores no desenvolvimento de software.

Veja por exemplo meu primeiro dia no projeto novo. Uma das maiores empresas da Austrália precisa migrar milhões de dados sobre seus clientes do sistema legado para o novo. Eu cheguei no meio do projeto e minha primeira tarefa é atuar no sistema que faz uma checagem ara ver se os dados foram mirados corretamente. Moleza.

Até a hora do almoço meu par e eu tínhamos escrito todo o script Ruby que conecta com o servidor do sistema legado, obtém o resultado da consulta desejada como HTML, faz parsing dele com o hpricot, armazena num banco de dados utilizando ActiveRecord, chaa os scrits e comparação, faz caching em disco e retorna um resultado em XML. Tudo isso rodando numa task do rake e testado com RSpec. Moleza.

O difícil foi fazer os scripts de comparação. A tecnologia já oferece mais que suficiente para criar este mecanismo, já fizemos uma arquitetura baseada no padrão Chain of Responsibility que vai validar todos os casos mas e entender as regras do negócio?

Sempre vai ter aquele que diz “ora, tá tudo documentado em caso de uso, diagrama de domínio e etc.’. Já tive o desprazer de trabalhar em diversos projetos que acreditavam que isso é verdade e invariavelmente o resultado era que o novato só ficava produtivo depois de um mês e pouco.

Hoje, no meu primeiro dia no projeto novo, já consegui ser produtivo e implementar boa parte de uma história. A mágica não está no Ruby, não está no Mac, não está no Java nem no SOA. Está em uma palavrinha que eu coloquei no texto lá no início e talvez tenha assado despercebida:

Até a hora do almoço meu par e eu tínhamos escrito todo o script[...]

Na chegada eu fui recebido com uma visão geral do sistema, seus objetivos e arquitetura. Em uma hora eu estava programando uma parte importante e para me mantêr dentro do domínio havia ma pessoa com anos de experiência na casa pareando comigo. Acredito que amanhã pela manhã tenhamos completado a user story que estávamos implementando.

A tecnologia vai continuar evoluindo e nos levando para luares fantásticos mas o que a maioria das empresas precisa é de uma faxina no modo de pensar das pessoas, tanto do alto quanto do baixo escalão.

Modelo de Negócios e Tecnologia

Sunday, December 2nd, 2007

Há alguns anos eu trabalhava para uma grande empresa que cria produtos em um nicho muito específico. Dá última vez que eu vi alguém fazer uma estatística 90% dos produtos eram em C, 5% em C++ (”muito lenta”) e o restante em PERL, Python e Java.

A coisa que eu mais gostava sobre essa empresa era como o modelo de negócios deles era movido por inovação. Quando alguém tinha uma boa idéia ele era convidado a montar um protótipo em laboratório que seria oferecido à clientes. Haviam muitos ganhos para os bem-sucedidos, meu chefe, diretor regional de tecnologia, subiu ao seu cargo após duas idéias convertidas em produto (além de ganhar uma boa grana).

No entanto, apesar da inovação presente nos novos produtos lançados simplesmente não havia inovação técnica. Não importa o software, tudo era feito em C. Eu fui contratado para um novo time que cuidava das alicações Java. Estas aplicações só foram criadas porque os clientes exigiam interfaces web e RMI para os produtos da empresa e porque contratar programadores C sempre foi um problema. Mesmo trabalhando basicamente com Java (e naquela época o sonho de todo mundo era arrumar um emprego “100% Java, nada de PHP ou VB”) boa parte do meu trabalho era escrever e testar interfaces em C que se comunicavam com o sistema “de verdade” (o feito em C).

Certa vez me mandaram por 10 dias, que viraram 20, numa viagem de trabalho. O lugar não era muito amigável com turistas então passei boa parte do tempo no quarto de hotel tentando entender a televisão. Como não tinha Internet liberada eu passava no dia baixando PDs e páginas completas para ler à noite e nos fins-de-semana. Com o tempo pensei: e se eu reconstruisse o sistema em Java? Obviamente que não consegui reproduzir o sistema todo dado o tempo mas se o sistema antigo tinha 5% em Java eu consegui que fosse unas bons 30%. Chegue no escritório doido para mostrar ao meu chefe.

Obviamente foi um banho de água fria. A pessoa ficou feliz por eu me interessar pelos projetos internos e disse que iria ver o sistema, um dia. Esse dia nunca chegou. Após alguns meses eu pedi demissão da empresa.

Dia desses estava falando com um amigo que ainda trabalha lá e soube que 50% dos clientes foram embora. Na época que eu trabalhava nessa empresa ela tinha quase que o monopólio de um dado tipo de sistema, com tempo concorrentes foram surgindo. O sistema da empresa era claramente superior aos outros mas era muito menos flexível. Ele era muito bom no que fazia mas quando precisávamos que ele fizesse a coisa um pouquinho diferente o projeto durava meses. Os concorrentes chegaram com linguagens como C++ e Java e apesar de não terem um produto com 10 anos de bons serviços prestados eles conseguiam mudar rapidamente.

Há dez anos a escolha por utilizar C e IPC de UNIX na mãozona era certa. Nenhuma plataforma da época oferecia o desempenho aceitável. Infelizmente as pessoas acabam construindo as piores coisas do mundo com desculpa de performance e o sistema era completamente monolítico e depende tanto do SO que mudar de uma versão minor para a outra leva um ano com um time de 3 pessoas completamente dedicados.

Se esta empresa acompanhasse os movimentos da indústria veria que existiam plataformas que já ofereceriam performance aceitável (eu já trabalhei em sistemas Java mais eficientes que aquele em ouros lugares) e que iriam oferecer a flexibilidade necessária. Infelizmente só repararam isso quando a concorrência invadiu o mercado.

A empresa continua com produtos ótimos em suas idéias mas ninguém consegue esperar 2 anos para colocar algo no ar. As coisas mudaram e escolher a tecnologia certa para cada caso é cada vez mais o qe define sucesso ou fracasso de um projeto. Ou de uma empresa.

Como Nasce um Framework Significativo?

Wednesday, November 7th, 2007

DHH responde:

In the beginning, there was no Rails, there was only Basecamp. After working on Basecamp for a while, though, I eyed the option of giving all the generic pieces a life of their own. But even then, I continued to work on Basecamp first. Which meant that all the functionality of Rails came as extractions of a real application, not of a “what somebody might need some day” fantasy, so prevalent in framework design.

Programadores Profissionais Escrevem Testes, Ponto Final.

Wednesday, October 31st, 2007

O tópico já tem oito páginas. Acho que chega à 10. Por mais que minha mão coce para comentar lá eu não vou, simplesmente porque já tive problemas demais com o pessoal do Mentawai.

De qualquer forma sempre me preocupa a possibilidade de algum desenvolvedor ler o tópico e pensar “Poxa, se esses caras que fazem todos estes frameworks não usam testes por que eu vou usar?”.

Desenvolvedores profissionais escrevem testes. Simples assim.

Uma pessoa que não ganha milhões de dólares mas escreveu uma das obras mais clássicas deste ramo deixa bem claro em sua primeira aula que programar é gerenciar complexidade. Nós precisamos gerenciar complexidade o tempo todo, por isso criamos funções, objetos e tudo mais. Não adianta, mesmo Einstein teve que provar que suas fórmulas e execuções estavam corretas, que poderiam ser verificadas. Na faculdade aprende-se isso desde as cadeiras básicas (e o fato de ser esquecido como “coisa teórica inútil” me faz novamente perguntar sobre o valor do ensino formal).

Existe uma grande diferença entre fazer Test-Driven Development e testar. TDD é sobre modelagem de objetos e especificações, não sobre testes (tanto que Behaviour Driven Development está se consolidando como algo mais eficiente que TDD) apesar de que no final você acaba ganhando uma suíte de testes de graça.

É muito difícil achar um projeto open-source relevante que não tenha testes. Na verdade os projetos decentes só aceitam um relatório de bug ou um patch se vier acompanhando por um caso de testes. Imagine uma aplicação feita colaborativamente por diversas pessoas, como saber que o que eu acabei de fazer commit não vai quebrar o que você modificou ontem? Boas práticas de orientação a Objetos? Não se iludam, OO não foi feita para este tipo de verificação! Com boas práticas você consegue minimizar o impacto de mudanças diminuindo dependências mas você não vai ter certeza disso.

Eu sinceramente não sei que técnica é essa que faz programação defensiva evitar testes. Eu já li bastante sobre Orientação a Objetos e programação defensiva e não vi nada deste tipo, pelo menos não vindo de uma fonte com um mínimo de credibilidade. Um exemplo simples, imagine que o framework web imaginário Pagai possui um código parecido com este:


Acao acaoSendoExecutada = controladorPrincipal.acao(requisicao.acaoDesejada());

Simples, não? Agora imaginemos que o código do método acao(String) seja algo assim:


public Acao acao(String pathInvocado){
//verifica se acao possui o formato desejado, deve ter uma barra e deve ter dois itens separados por barra apenas
if((pathInvocado.indexOf("/") == -1) || (pathInvocado.split("/").size < 2)) throw new IllegalArgumentException("Path invocado ["+pathInvocado+"] nao possui o formato adequado (consulte a documentacao XYZ)");
//lógica...
}

Isso é programação defensiva: eu não estou aceitando o que me passam, eu verifico se é o que deveria e se for eu continuo, se não eu paro ali mesmo e deixo alguém tomar conta do problema, seja a classe em questão ou alguma outra mais acima.

Imagine que eu por engano commitei um código que utilize “” em vez de “/” nesta requisição. Se for numa parte central do código é bem possível que uns testezinhos peguem mas imagine que é utilizado apenas em um caso específico e que, por um acaso, eu baseei meu sistema de controle de jatinhos particulares 9meu chefe tem muitos jatinhos) nele. Quando eu fiz o comit não alertou. Quando eu fiz o build não alertou. Quando eu fiz meus testezinhos não alertou. Quando foi para a produção eu tive erro.

Ok, acontece. Programadores de qualquer tipo cometem erros. Eu vejo o problema muito rapidamente e o corrijo, temos uma versão beta em 15 minutos no ar, fantástico. Aí daqui há um mês outro programador comete o mesmo erro. Quando fizer o build não vai alertar. Quando fizer seus testezinhos não vai alertar. Quando for para a produção… Isso não é profissionalismo.

O que eu preciso é de uma suite de testes, unitários e de integração, que me digam que o sistema está incorreto já no processo de build, sem lançar jars beta, alfa ou gama.

Mas se tem um argumento nessa história toda que realmente me irrita é quando as pessoas dizem que “num mundo capitalizado não há tempo para testes” ou que “o cliente não quer saber como é feito, ele quer que funcione”. O cliente realmente não quer saber como funciona, ele quer que funcione. Mas ele também não vai querer saber que você alterou uma classe que usava barra para barra invertida e tudo parou de funcionar, ele quer que o problema não aconteça e se acontecer que seja corrigido rapidamente. Se seu sistema não tem qualidade -e testes fazem parte de qualidade- você não consegue isso. TI gasta fortuna das empresas reescrevendo sistemas simplesmente porque não foram feitos por profissionais, e profissionais se preocupam com a qualidade do que fazem. E isso inclui testes.


Não seja um amador.

Arquiteturas Simples Duram Mais

Wednesday, October 24th, 2007

Um amigo outro dia me perguntou que tipo de arquitetura eu usaria num caso bem peculiar. Basicamente ele foi encarregado de definir a arquitetura corporativa de um grande banco, ou seja: definir hoje a forma como aplicações serão construídas pelas próximas décadas. Basicamente ele vai se ro cara que vai ser xingado por algumas centenas de programadores nos próximos tempos, não importa que arquitetura escolha.

Há poucos dias atrás falamos aqui sobre arquiteturas de referência e seu efeito danoso. Geralmente quando alguém tem à frente um desafio desse ele logo pensa em um modelinho que mostra obriga o uso de uma meia dúzia de frameworks e padrões (clássico moderno: Struts/JSF e JPA, clássico vintage: Struts 1.1 e EJB/DAO). Para melhorar ainda é incorporado um conjunto de classes “utilitárias” feitas com práticas que talvez tenham servido para um projetinho piloto mas hoje em dia só atrapalham.

Ainda assim uma arquitetura corporativa é algo interessante. Quando empresas grandes não possuem uma macro-arquitetura acabam crescendo de maneira desordenada e criando dezenas de aplicações redundantes e gambiarras de integração entre sistemas. Note no entanto que uma arquitetura corporativa não é uma arquitetura de referência, a arquitetura corporativa não fala sobre como implementar aplicações mas sim provê guias sobre como integrá-las, define as relações previstas em no ecossistema que é uma grande empresa.

Quais são as melhores macro-arquiteturas que você conhece? Eu consigo pensar em algumas: Apache, UNIX, World Wide Web… Nestes ecossistemas aplicações novas surgem, são alteradas e morrem todos os dias há décadas, um sistema criado com a tecnologia mais recente de 2007 vai rodar tranqüilamente neste ambiente. Por quê?

Porque estas arquiteturas se baseiam em primitivas e contratos, não em especificações rígidas. Criar um módulo para o Apache , um programa para rodar em UNIX ou uma site é basicamente criar um programa de computador em uma das plataformas suportadas que obedeça a um contrato.

Uma boa arquitetura corporativa vai definir algumas políticas e contratos para a aplicação se relacionar com o meio-ambiente e só isso. No caso do banco, poderíamos definir que uma aplicação deve disponibilizar via uma interface POX/REST seus WebServices, que ela deve utilizar a API do Mogile FS para guardar dados em disco, que cache deve ser feito utilizando a API do memcached.

E se o arquiteto quiser sair do padrão? Ótimo, saia, mas ele deve oferecer compatibilidade com o ambiente.

E se eu já tiver comprado um sistema que faz WebServices via SOAP? Eu preciso criar um meio de disponibilizar estes serviços via POX/REST também. Pode ser uma adaptador simples, um ESB, o que quer que seja. É como quando você compra um equipamento eletrônico com tomada americana, você não vai mudar uma tomada na sua casa para o padrão exótico, vai é comprar o adaptador necessário para plugar ele nas tomadas do seu ambiente.

Mas e se não precisarmos de filesystem distribuído? E se já estivermos utilizando uma solução de cache que faz mais sentido nesta aplicação?

Ótimo, use. O uso de filesystem X, cache Y, banco de dados Z deve ser um guia. Toda vez que alguém precisar de uma solução de cache, filesystem, etc. ele olha o guia da empresa, se não servir ele usa algo que sirva. O que importa é que o uso fique encapsulado no sistema. Imagine que ao invés do Oracle 10g eu resolva usar um MySQL na minha aplicação. Está ótimo mas eu devo manter essa peculiaridade interna à minha aplicação. Os outros sistemas que vierem a se comunicar com o meu não devem precisar saber sobre a existência deste banco, eu não posso usar este banco para comunicação entre aplicações (o que já é uma coisa péssima para se fazer de qualquer forma).

O que importa é:

  1. O arquiteto tem liberdade para resolver seu problema da maneira mais adequada
  2. O novo sistema é compatível com o meio-ambiente

Para ser um bom arquiteto não é necessário ter tanta experiência assim, basta saber olhar os casos de sucesso e aproveitar o que funciona. Geralmente as técnicas utilizadas nestas arquiteturas são também catalogadas como Padrões Arquiteturais em livros. Um bom arquiteto tem que ser um ávido leitor de livros e de código.

Conexão Java 2007

Tuesday, October 23rd, 2007

Mais um ano vai, outro ano vem e o Conexão Java está aí. Este é certamente o evento mais descolado da comunidade Java do Brasil.

O CJ é um grande encontro entre as pessoas que participam em fóruns como o GUJ, o PortalJava e o RioJUG. O foco do evento são os mini-cursos que agem na formação de novos profissionais. Bem, formação não exatamente, ninguém sai de um curso de meioa dúzia de horas especialista em nada mas é uma boa oportunidade de ter contato mão-na-massa com algumas tecnologias e técnicas.

Este ano a estrela do evento é ninguém menos que Carlos Villela. Radicado em Londres pela ThoughtWorks há… bem, há alguns anos… o cv vem falar de algo bem atual: o declínio dos arquitetos monoglotas.

Também teremos algo um pouco diferente. Possivelmente deve haver um repeteco da minha palestra sobre arquitetura do JustJava 2007 (infelizmente sem o Paulo que vai estar de férias) mas enquanto isso é confirmado ficamos com mais uma atração: Oficina do Arquiteto.

Essa é uma idéia meio maluca que acabamos de fechar, vai funcionar mais ou menos assim: alguém traz uma arquitetura -seja de um projeto existente, livre ou de uma empresa, ou desenhado na hora- e nós debatemos esta. Na conversa vão sobrar padrões arquiteturais, guidelines e uma boa dose de bate-papo sobre o que nós, arquitetos, estamos fazendo por aí. Se você já tiver alguma idéia me adiante por email para organizar melhor as coisas, eu vou preparar algumas arquiteturas clássicas para usarmos quando não houver nenhuma na roda. A idéia é bem simples: debate, informação e diversão.

Aldo Dórea vs Fred Brooks

Tuesday, October 23rd, 2007

Eu não tenho nada contra a maioria dos gerentes de projetos mas se tem alguma coisa que me irrita é alguém que acha que gerenciar projeto de software e levantar um prédio é a mesma coisa. Veja bem: eu tenho uns bons dez anos de experiência com projetos e recomendo fortemente uma abordagem ágil, iterativa e incremental para eles, mas estou falando de projetos de software, não de projetos em geral. Eu não tenho a menor idéia se isso funcionaria para levantar um prédio, sei que funciona para software e por isso você não vai encontrar neste blog ou em alguma publicação minha qualquer dica para gerenciar a reforma do seu banheiro. Na verdade eu até evito comparações com outras engenharias porque elas sempre são danosas (o próprio conceito por trás do nome ‘engenharia de software’ é danoso).

Neste cenário temos o número atual da Mundo PM e um artigo de Aldo Dórea Mattos, M. Sc.. Aldo é um profissional com bastante experiência no mundo da construção civil. Segundo seu mini-curriculum na revista ele é engenheiro, advogado, mestre, já trabalhou em projetos em 4 países e é autor do livro “Como Preparar Orçamento de Obras”. Aldo escreveu um artigo com o título muito interessante de “Por que os cronogramas ‘furam’?”.

Em seu artigo Aldo foca em um relatório apresentado num grande congresso do PMI com este tema. O relatório foca… construção civil. Eu realmente achei que era uma leitura interessante até porque eu sempre tenho a dúvida se só nós sofremos com tantos problemas quando alguém cisma de usar técnicas de waterfall e controle total nos nossos projetos, mas o autor faz questão de citar este infeliz exemplo:

[...]O desenvolvimento de um cronograma é feito a partir de premissas de planejamento, que são pressupostos assumidos pelo GP e sua equipe. As premissas de planejamento estão na definição das produtividades que geram as durações das atividades - por exemplo produtividade do pedreiro no levantamento de uma parede de alvenaria (em m² /h), produtividade de um programador no desenvolvimento de linhas de programação (linhas/dia), produtividade de uma máquina na fabricação de componentes industriais (un/h)[...]

-Mundo PM #17, Pg 34

O que está errado na frase acima? Eu imagino que Aldo tenha muito conhecimento sobre construção civil, não imagino quanto de conhecimento ele tem sobre indústrias mas definitivamente não creio que ele saiba muito sobre programas de computador e quem os escreve.

Veja bem: ele compara o levantamento de uma parede -algo que é feito por um profissional com conhecimento meramente operacional- ou a produtividade de uma máquina à de um programador. Enquanto ainda não faz tal comparação infeliz o texto diz:

[...]A quantidade de recursos pode definir a duração da atividade ou, ao revés, ser determinada por ela. É só pensar numa tarefa alvenaria, cujo quantitativo seja de 600m² e cujo recurso prioritário seja pedreiro, com uma produtividade de 10m²/dia. Pode-se proceder de duas maneiras[...]fazer a parede em 15 dias, são requeridos 4 pedreiros; ou[...]com uma equipe de 5 pedreiros levanta-se a alvenaria em 12 dias[...]

-Mundo PM #17, Pg 33

Posso tirar pelo trecho seguinte, mostrado acima neste post, que o autor não faz distinção entre o tal pedreiro e sua parede do programador e seu código.

Como vocês estão carecas de saber eu já fui consultor, tanto autônomo quanto associado à uma empresa, incluindo empresas de três letras. Já entrei em muitos enormes clientes ansiosos por uma resposta aos seus problemas: por que eles não conseguem sequer prever o prejuízo num projeto de software? E sei que um artigo deste tipo cai como uma bala de prata.

Ops, bala de prata? Já que estamos neste tema vamos chamar ao diálogo Frederick Brooks, autor do paper seminal chamado “No Silver Bullet”. Fred também é uma pessoa importante no seu meio. Hoje dá aulas na Universidade da Carolina do Norte -onde fundou o departamento de Ciência da Computação- mas é mais conhecido como “o pai do Operating System/360″, um dos maiores projetos de software já realizados. Por este trabalho ele ganhou a medalha nacional de tecnologia dos EUA em 1985. Seu livro “Mythical Man-Month, The: Essays on Software Engineering” ganhou um dos prêmios mais importantes do mundo da computação, o Turing Award.

E lá vem Brooks discordar:

Finally, there is the delight of working in such a tractable medium. The programmer, like the poet, works only slightly removed from pure thought-stuff. He builds his castles in the air, from air, creating by exertion of the imagination. Few media of creation are so flexible, so easy to polish and rework, so readily capable of realizing grand conceptual structures. (As we shall see later, this very tractability has its own problems.)

Yet the program construct, unlike the poet’s words, is real in the sense that it moves and works, producing visible outputs separate from the construct itself. It prints results, draws pictures, produces sounds, moves arms. The magic of myth and legend has come true in our time. One types the correct incantation on a keyboard, and a display screen comes to life, showing things that never were nor could be.

–Mythical Man-Month, The: Essays on Software Engineering, Anniversary Edition, Capítulo 1

Não faz muito sentido comparar isso com um muro de tijolos, faz? E quem será que entende mais de software? E sobre recursos em um projeto?

The second fallacious thought mode is expressed in the very unit of effort used in estimating and scheduling: the man-month. Cost does indeed vary as the product of the number of men and the number of months. Progress does not. Hence the man-month as a unit for measuring the size of a job is a dangerous and deceptive myth. It implies that men and months are interchangeable.

Men and months are interchangeable commodities only when a task can be partitioned among many workers with no communication among them (Fig. 2.1). This is true of reaping wheat or picking cotton; it is not even approximately true of systems programming.
[...]
When a task cannot be partitioned because of sequential constraints, the application of more effort has no effect on the schedule [...]. The bearing of a child takes nine months, no matter how many women are assigned. Many software tasks have this characteristic because of the sequential nature of debugging.

–Mythical Man-Month, The: Essays on Software Engineering, Anniversary Edition, Capítulo 2

Não adianta você adicionar mais mulheres ao processo, a gestação dura quase sempre nove meses. Você não pode calcular progresso apenas pelo número de pessoas dividido pelo número de tarefas, isso é cálculo de padaria inútil no caso de software.

O problema não é nem a confusão feita pelo autor com relação à o que é um trabalhador relativamente operacional -pedreiro-, o que é uma máquina industrial e o que é um trabalhador de criatividade como um programador. O deslize de um é o de menos. O problema é que esse tipo de informação publicado numa revista que atinge a um mercado tão seleto quanto aos gerentes de projeto do Brasil (e que custa a bagatela de R$23,90) vai influenciar negativamente todo o mercado.

Eu tive que copiar trechos da SafariBookshelf (serviço que uso e recomendo) para fazer este post. Eu tenho o livro do Brooks, ou pelo menos tinha. Em algum momento de 2004 eu emprestei o livro para meu então Gerente de Projetos e ele nunca mais devolveu. Dia desses estive com ele e perguntei do livro, ele ficou de me devolver. Perguntei se ele leu e ele disse que não. O livro está na mesa dele há 3 anos e ele não leu, mas sei que ele assina a Mundo PM. A literatura ‘fácil’ ganha da literatura adequada, eu diria.

Eu continuo sem saber se construção civil e construção de software são parecidos o suficiente para utilizarem as mesmas técnicas de gerenciamento de projetos. O exemplo infeliz da revista me faz acreditar que não são, mas tem algo curioso nele: O artigo em si é sobre diversos problemas que resultam em atraso, problemas presentes em construção civil no caso mas que também acontecem em construção de software. As soluções que o autor propõe talvez funcionem em engenharia civil mas eu já as vi aplicadas à construção de software e… bem, não funcionam. Algo que tem funcionado com relativo sucesso para desenvolvimento de software, entretanto, é inverter os conceitos do artigo e tentar algo mais simples: metodologias ágeis. Se a construção civil sofre tanto de atrasos talvez, só talvez, seja a hora de uma das mais antigas engenharias aprender algo com uma das mais novas. Mas só talvez.

Se você quer saber como não fazer seus cronogramas ‘furarem’ em vez de gastar R$23,90 fiquem com uma frase de alguém que realmente entende de ciência da computação:

1. Estimates of the length of an activity, made and revised carefully every two weeks before the activity starts, do not significantly change as the start time draws near, no matter how wrong they ultimately turn out to be.

–Mythical Man-Month, The: Essays on Software Engineering, Anniversary Edition, Capítulo 14

E pensem em como sua metodologia apóia este tipo de revisão de estimativa, como seu cronograma pode se adaptar a isso. Se não achou nada no seu cenário atual, mude.

Adaptação de Linguagens

Thursday, October 18th, 2007

Mais um texto no philcalcado.com, desta vez algo mais genérico sobre modificações em linguagens. Eu ando lendo bastante sobre linguagens embutidas em outras (DSLs Internas) e outras formas de modificação de linguagem como Fluent Interfaces. É bem complicado chegar à qualquer conclusão em temas tão abstratos mas a experiência no uso destas técncias no dia-a-dia e no laboratório me mostraram que existem diferenças entre as formas de alterar uma linguagem. Em Language-Oriented Programming você cria linguagens, com Fluent Interfaces não.

Bom, mais sobre isso em Language Adaption.