Archive for the ‘plataformas’ Category

Objetos não são atributos + funções

Sunday, May 18th, 2008

Quando simplificamos demais ao ensinar conceitos acabamos criando problemas que demoram anos para se resolver, se é que são resolvidos. Um exemplo que eu observei hoje foi como algumas pessoas pensam sobre objetos.

É comum que seja ensinado no primeiro contato das pessoas com orientação a Objetos que objetos representam atributos e funções embaladas no mesmo saco. Bom, isso é uma simplificação extrema utilizada para fazer com que quem conheça programação procedural trabalhe com objetos de maneira mais simples, mas é uma simplificação tão grosseira que atrapalha algumas pessoas para o resto da vida.

Objetos não possuem propriedades + funções, eles possuem estado + comportamento. Você provavelmente vai usar atributos (i.e. variáveis de instancia) e funções (de instancia também) para implementar isso mas é um detalhe de implementação, não algo que deva ser exposto.

Um agravante deste problema são propriedades. Sejam propriedades bem resolvidas como as do C# ou meia-boca como do Java, elas representam apenas mais uma mensagem que o objeto recebe (já que ambas as linguagens são baseadas em troca de mensagens) e não “atributos” do objeto.

get/set em Java são herança de um modelo de componentes. Componentes não são necessariamente objetos, o que a (finada?) especificação JavaBeans fez foi utilizar classes Java para implementar componentes gráficos. Como não havia metadados (annotations em Java) naquela época o melhor era adotar uma convenção, daí os setXxx e getXxx da vida.

O problema é que este idioma saiu do controle. Ao invés de utilizarmos um método que faça sentido dentro do domínio preferimos criar um get/set burro, típico de arquiteturas BOLOVO.

Por exemplo, suponha que você possua uma classe Pedido que possui um status. Quando alguém vai atualizar o status do pedido para “finalizado” qual idioma é mais comum?

//1) set/get
pedido.setStatus(Pedido.Status.FINALIZADO);

//2) Mensagem
pedido.finalizar();

Creio que você concorda comigo que o primeiro é de longe mais utilizado. Qual o problema com ele? Como dissemos antes, Java é uma linguagem baseada em troca de mensagens. Uma mensagem é algo que o objeto recebe e decide o que fazer, no caso de Java isso acontece quando chamamos um método. Quem deve decidir o que deve ser feito não é o cliente e sim o destinatário da mensagem. Quando você diz setStatus(Status) você está dizendo para a classe que quer que os status dela seja o especificado. Pensa bem, é isso que você quer?

O que você quer em verdade é que o pedido seja finalizado. Como isso é feito, se muda status ou não, não é papel do código cliente, é papel do objeto (e deve ser documentado, especificado e verificado através de testes unitários).

Da mesma forma, quando você executa um getStatus() no objeto o que você faz com isso? Exceto em alguns casos específicos, um método getXxx() só deveria ser utilizado porque você precisa executar algo com ele que não vai envolver mudança de estado, como por exemplo exibir numa interface gráfica. Se você faz um getXxx() porque baseado no retorno você chama uma lógica ou outra provavelmente você está fazendo algo errado, já que é uma violação gritante da Lei de Deméter.

O que eu deveria fazer, então? Suponha que eu tenha o seguinte código:

public void notificarMudancaEm(Pedido p){
 if(p.getStatus().equals(Pedido.Status.FINALIZADO){
     servicoEmail.enviamensagemConclusao(p);
 }
}

Isso parece bem razoável, não? A lógica de enviar um e-mail de conclusão não está no Pedido e sim em algum serviço próprio para isso. Ele provavelmente é um observador do pedido e cada vez que você chama setStatus() esta é notificado. Num caso real recente eu estava trabalhando numa aplicação legada com o código exatamente como o acima. De repente alguém decidiu que um Pedido também está finalizado se estiver em status CANCELADO.

Essa é a hora em que o programador xinga a mãe do analista de negócios e vai caçar um email de três meses atrás que contem uma documentação, assinada em sangue, que contraria isso. O gerente de projetos vê aquilo, dá um sorriso e manda um email para o cliente daquela consultoria de três letrinhas dizendo que é uma mudança de escopo e que vai precisar de 50 horas a mais para isso. Ele diz ao programador que na verdade só tem 5 horas porque as outras 45 ele vai usar como desculpa quando o projeto atrasar. De quem é a culpa?

Bom, de quem é a culpa é assunto para outro post mas eu te garanto que não é da Orientação a Objetos. O problema no código acima (e certamente este código está repetido em milhões de outros lugares) é que ele não cumpre o princípio básico de deixar o objeto ser responsável pela sua própria vida. Você precisa saber se o pedido está finalizado mas ao invés de perguntar isso ao objeto você pergunta qual seu status.

Imagine que ao invés do código acima você possuísse algo mais… OO:

public void notificarMudancaEm(Pedido p){
 if(p.isFinalizado()){
     servicoEmail.enviamensagemConclusao(p);
 }
}

E suponha que você tenha que alterar o que FINALIZADO significa. Qual é mais fácil?

É este tipo de coisa que você perde ao transformar objetos em atributos+funções. Ao invés de pensar “quais são os atributos deste objeto?” pense “quais mensagens este objeto responde?”.

Australian Architecture Forum 2008

Thursday, May 1st, 2008

Falando em coisas agitadas, fui convidado para palestrar no Australian Architecture Forum 2008. O título é “Lightweight SOA Through Web Widgets” e falar de SOA com REST num evento onde vai estar presente o impagável Jim Webber é algo bem diferente.

Como meu Google Analytics diz que ese blog é acessado por pessoas aqui na Austrália fica o convite.

Par de Jarros

Sunday, April 6th, 2008

Metodologias ágeis pensam sempre em times de especialistas generalistas. Isso é algo fantástico.

É óbvio que ter um especialista em banco de dados Oracle no time aumenta bastante a capacidade técnica, é óbvio que ter o James Gosling como programador Java aumenta a produtividade nesta linguagem mas é mais que óbvio que a grande, grande maioria dos projetos de software hoje em dia não precisam de especialistas extremos, precisam de gente boa o suficiente na tecnologia.

Isso nos coloca confortáveis para ao invés de um DBA dedicado termos apenas bons desenvolvedores, que ainda que não saibam diferenciar todos os tipos de tablespace possíveis conseguem fazer o sistema funcionar de forma razoável –e razoável significa dentro dos requisitos funcionais e não-funcionais.

Não consigo lembrar de nenhum projeto que eu tenha participado nos últimos três anos que não envolvesse mais de uma linguagem de programação, geralmente Java com Ruby, C++, JavaScript, C#, Bash e/ou PERL (alem das DSLs: HQL, SQL, etc.). Nos bons times não havia “desenvolvedor C#”, havia desenvolvedor, e isso significava que o cara usava as ferramentas que melhor servissem para o trabalho.

Mas o que isso quer dizer do ponto de vista do desenvolvedor? Quer dizer que ele vai ser exposto à tecnologias diferentes, o que é ótimo, mas também quer dizer que ele terá que abandonar algumas das suas preferências pessoais em favor do time, o que pode não ser tão bom.

Em um time ágil, todos os membros devem estar comprometidos com o projeto. Não tem essa de “a minha parte está feita, falta Fulano terminar a dele”, todos são responsáveis e todos vão ajudar. Se você foi contratado como programador SQL e precisamos de uma mão para terminar de escrever testes em Selenium é sua obrigação para com o time se voluntariar.

Mas isso, como tudo na vida, tem dois lados. Existem pessoas que não ligam para a tecnologia utilizada, elas gostam do projeto em si, mas no mundo do desenvolvimento existem muitas pessoas –e geralmente pessoas muito boas- que possuem suas preferências. O cara não gosta de programar em Ruby, ele prefere Java. Se o time precisar ele escreve Ruby mas por ele fazia tudo em Java -ele não acredita que Ruby tenha a mesma qualidade, ou algo do tipo.

Lembre-se que o manifesto ágil coloca pessoas acima do processo, se o processo diz que o desenvolvedor deve ser bombril multi-uso mas a pessoa não se sente a vontade nessa área você como gestor tem obrigação de fazer algo a respeito.

O que fazer? Deixar este desenvolvedor apenas nos projetos Java? Se isso for uma opção tudo bem, mas e em times pequenos? Eu vejo essa situação como um contrato entre as partes:

  • O desenvolvedor deve saber que sua preferência de linguagem/tecnologia/plataforma/framework/biblioteca não necessariamente é a melhor para o caso e/ou não é viável na atual situação.
  • O desenvolvedor deve se comprometer a utilizar a tecnologia em questão quando o time necessitar que ele o faça –e ele tem o direito de dizer até 3 palavrões por linha de código escrita
  • O gestor tem que garantir que o desenvolvedor tenha direito à expressar sua opinião quanto às escolhas do grupo
  • O gestor tem que saber que essa pessoa não está confortável nessa posição e fazer o possível para que isso seja amenizado

Da mesma maneira que o gestor do projeto ou do time sabe que não pode arriscar seu sucesso por uma birra do desenvolvedor com a linguagem, ele sabe que é muito difícil encontrar bons desenvolvedores e manter um ambiente de trabalho agradável. Na minha experiência o que eu mais vi foram casos onde o desenvolvedor cumpre a parte dele no contrato acima mas o gestor não. O gestor trata todos os desenvolvedores como iguais, ignorando completamente o caráter pessoal e social de um projeto de desenvolvimento.

O que “amenizar” significa depende do seu contexto. Você pode tentar mudar a pessoa de equipe, pode fazer com que ele tenha a opção de pegar outras tarefas que não seriam imediatamente executadas, oferecer treinamento… O que você não pode fazer é que o processo –ágil ou não- vença à razão e você tenha um desenvolvedor completamente desestimulado e frustrado na sua equipe, que enquanto você não olha está em um site de empregos.

Não deixe que para aquele desenvolvedor agile signifique trabalhar com algo que você não gosta.

Qi4j @ ThoughtWorks Community College

Thursday, April 3rd, 2008

Ontem tivemos mais um Community College na ThoughtWorks Melbourne, desta vez focamos no Qi4j.

É uma idéia interessante. Basicamente o qi4j (”quiforjêi”) usa micro-aspectos para modelar qualquer coisa. O problema é que a sintaxe atrapalha. Eles usam a Linguagem Java, com Language Adaptations e uma Factory mágica, provavelmente uma linguagem própria teria mais efeito.

Labirinto

Thursday, March 27th, 2008

A quantidade de dados disponível na Internet é algo interessante e quando temos a ferramenta certa algumas realidades são tão claras que chegam a ser constrangedoras. Para mim a rede social mais relevante hoje é o Linkedin. Apesar de haverem centenas de desesperados para arrumar um emprego e ganhar recomendações sem merecer é m sistema bem feitinho e de uma empresa que parece ter o pé no chão: nada de criar o novo Facebook, foco foco foco!

Bem, dia desses eu vi que eles lançaram páginas das empresas. Além de uma interação redondinha com a BusinessWeek o perfil da empresa possui diversos dados extraídos dos perfis dos seus funcionários e, como a experiência de trabalhar com alto volume de dados e acessos me mostrou, isso não é nada fácil.

Mas aí vem a parte engraçada. Pegue a página de uma empresa de três letrinhas qualquer. Veja o box “Related Companies” e perceba a quantidade de empresas de três letrinhas dos dois lados (antes de entrar na empresa, depois de sair). Agora clique em uma empresa de três letrinhas da lista. Tente achar uma delas que não tenha uma empresa de três letrinhas como “after”.

É óbvio que isso não é nenhum dado científico mas mostra a realidade que quem trabalha nessas empresas vive -falo isso de conhecimento próprio. A coisa mais comum para o desenvolvedor de sistemas no Brasil é viver entre consultorias, você fica um pouco em uma, recebe uma proposta melhor, vai para outra, tira um certificado, volta pra anterior, quer ganhar mais, muda de novo. Sair deste ciclo não é fácil, exige sorte e/ou muita vontade. Não é fácil arrumar um bom lugar para se trabalhar e ainda ganhar a mesma coisa, mas existe. Na verdade eu percebo que tirando poucas exceções a maioria das pessoas com nível técnico bom que eu conheço ou não estão mais neste ciclo ou estão saindo dele.

Existe uma onda de pessoas que estão indo trabalhar com produtos, fazer consultoria por conta própria ou abrir sua própria startup. Isso é ótimo, quebra o paradigma infeliz de que para um técnico ter uma carreira de sucesso e;e deve sair da área.

Aqui em Melbourne -e imagino que na Australia toda- existe um saudável mercado de pequenas consultorias. São empresas pequenas, de umas dez pessoas, que conseguem competir nesse mercado tão cheio de absurdos. Infelizmente no Brasil isso é meio impossível -e dá para entender o Viícius-, as consultorias ganham contratos na base do… bom, vocês são brasileiros e sabem do que eu estou falando. Aqui existem as grandes também, Melbourne é um centro mundial, mas ainda que as pequenas estejam longe das contas megalomaníacas elas conseguem se virar com empresas que precisam de resultado de verdade, e não apenas encher uma sala de gente que finge que desenvolve.

Afinal, quantas permutações você consegue fazer com três letrinhas?

Testadores Ágeis

Monday, March 24th, 2008

Todo mundo sabe que agilidade é sobre testes. Muitos testes. Bem, mais ou menos. Geralmente quando falamos de testes em metodologias ágeis estamos falando de testes escritos pelo desenvolvedor enquanto escreve código, e estes têm dois objetivos: feedback e bom design.

Feedback se consegue ao executar os testes. Quando você escreve uma classe que quebra um teste você sabe que existe algo errado imediatamente. Bom design se dá porque nada alem do necessário é criado, alem de que as tecnologias atuais de testes exigem que seu código siga alguns bons princípios para que seja testável, como bom gerenciamento de dependências.

Existe, entretanto, outro tipo de teste, geralmente feito por um profissional especializado, que chamamos de QA (Quality Assurance). Este teste valida o software de um ponto de vista diferente. Muita gente se engana achando que testes de desenvolvedor são suficientes para validar um sistema. Obviamente que assim como nem todo sistema exige um web designer profissional especializado nem todo exige um profissional de testes, mas a maioria dos projetos que já participei tinham nisso um benefício.

Estava lendo o artigo do Jeff Paton, ex-colega ThoughtWorker, sobre isso e lembrei das minhas experiências com testadores em time ágeis. Mas primeiro talvez seja melhor contar sobre as experiências em times não-ágeis.

Eu trabalhei em uma empresa muito interessante mas com um processo muito estranho. A empresa tem orgulho de usar waterfall para desenvolver seus produtos, ninguém está autorizado a escrever uma linha de código sem escrever 8 documentos. Obviamente todos os projetos atrasam e obviamente o software tem uma qualidade deprimente, mas eles conseguem fazer dinheiro neste cenário –ainda que pagando um preço muito alto.

Teste é uma coisa séria nesta empresa. Os produtos estão sujeitos à regulamentação de telecomunicações de diversos paises, e cada funcionalidade tinha que ser testada de acordo. O fluxo de desenvolvimento era o típico de waterfall, nós desenvolvedores criávamos nossos sistemas (programas em C++ para plataformas UNIX diversas) e enviávamos uma tag do Subversion para a equipe de testes. O testador teoricamente já lera todas as especificações funcionai do produto e já tinha os casos de testes escritos e, talvez, implementados.

Era aí que a brincadeira começava. Na melhor das hipóteses o testador encontrava um bug, rejeitava o pacote (usando um maravilhoso sistema interno desenvolvido em Lótus Notes) e enviava de volta. O desenvolvedor corrigia e o pacote era retestado. Isso nunca acontecia. O que acontecia era:

  • O pacote era aprovado. O desenvolvedor, com o sistema já em produção, olhava o plano de testes por curiosidade e via que eles não testavam absolutamente nada de relevante, ninguém garantia a qualidade do treco
  • O pacote era rejeitado. O desenvolvedor olha ao motivo da rejeição e via que o que estava sendo testado nem de perto era o que o sistema deveria fazer. O testador Não entendeu o documento, muitas reuniões explicando tudo novamente e o pacote era retestado sem modificações
  • O pacote era recebido pelo testador com total surpresa. Era uma aplicação de linha de comando e o testador esperava uma aplicação com interface web, ou o testador esperava que o sistema usasse banco de dados e ele mantinha tudo em memória, ou…
  • O testador rejeitava o pacote porque não sabia como testa-lo. O desenvolvedor não pensava no testador, o testador não pensava no desenvolvedor.

Claro que todos os membros do escritório de projetos (já falei que tínhamos CMMI?) sabiam a solução para estes problemas e é claro que para eles a solução passava pela criação de mais documentos, de 1 a 5 dependendo de quem você perguntasse.

Nas equipes ágeis que trabalhei a coisa era diferente. O testador senta ao lado do desenvolvedor, e por vezes eles trabalham em pair programming (pair testing, provavelmente). O testador está envolvido em todas as tarefas, validando que o que o analista de negócios pede é entregue, que confirma com as premissas do projeto e etc.

Para fazer isso ele está envolvido na elaboração das user stories e, principalmente, dos critérios de aceite definidos nela. Seu trabalho é verificar que os critérios de aceite são obedecidos pela implementação e que eles fazem sentido em primeiro lugar.

Um profissional come site perfil não pode ser simplesmente um usuário. Ele tem que conhecer sobre metodologia de testes de software (um campo enorme por si só), sobre o domínio do sistema e sobre desenvolvimento. Idealmente o testador é um desenvolvedor e sabe criar suas ferramentas. Um testador deve ser capaz de escrever seu próprio programa usando Selenium RC, ou suas fixtures no Fit.

Infelizmente nem sempre isso acontece. Em muitas empresas o cargo de testador é delegado à pessoas que possuem um conhecimento técnico muito baixo e executam tarefas do tipo “aperte o botão e verifique se quebra o layout”. Neste caso os desenvolvedores podem prover as ferramentas para os testadores mas ainda assim eles devem ter capacidade de escrever os casos de testes usando a ferramenta sozinhos.

O papel do testador não é dizer que a aplicação está homologada, na maioria das vezes isso é apenas uma ilusão que gerentes gostam de cultivar. O papel do testador é garantir a qualidade dele submetendo à testes rígidos. Não é um aceite formal, o testador não é quem aprova o software –o analista de negócios ou seu equivalente aprova o software- ele faz parte do desenvolvimento deste.

Minha experiência diz que assim como trabalhar com testadores apertadores-de-botão não agrega nada ao produto alem de burocracia desnecessária, trabalhar com testadores de verdade no time é uma das melhores coisas que pode acontecer num projeto de software.

No meu projeto anterior os testadores chegaram ao time apenas como apertadores de parafusos. Eles clicavam na tela e verificavam que a informação correta era disponibilizada. Como nossa participação no projeto era facilitar a adoção de metodologias ágeis isso tinha que mudar. A primeira coisa foi a participação dos testadores na definição das histórias, eles trabalham junto com o analista de negócios e o usuário definindo critérios. Eles também participam do sign-off da história –quando ela é apresentada aos desenvolvedores que vão executa-la- e quando conclui a história o desenvolvedor az um walkthrough dela para o testador. Em todas as etapas eles agregam informação, questionam as praticas e, principalmente, garantem que o software final é testável.

Foi adicionado ao time de facilitadores um testador especialista em automação –um desenvolvedor exercendo função de QA, basicamente-, a função dele era disponibilizar ferramentas e disseminar seu uso. Com o tempo desenvolvemos uma Internal DSL em Ruby para controlar nossa ferramenta de teste, o Selenium RC. A ferramenta é utilizada por desenvolvedores nos nossos testes de aceitação que fazem parte do build e pelos testadores na hora de dizer que uma história está concluída.

Os resultados desta adoção são excelentes. Quando nossa parte no projeto –facilitar a adoção das praticas- acabou a pessoas estavam aptas à continuar o bom trabalho por si mesmas. Os desenvolvedores ainda criam as ferramentas mas a gerencia, vendo os benefícios, agendou cursos de Ruby e Selenium para a equipe de QA.

J2EE Spider no InfoQ

Thursday, March 13th, 2008

Saiu no InfoQ uma matéria sobre o J2EE Spider, do Bruno Braga. Eu recebi um email do Bruno há algum tempo me convidando para fazer um review da nova versão da ferramenta, e dando ênfase no fato que não é um gerador abrace-o-mundo como vemos por aí.

Ainda não tive tempo de fazer o teste da ferramenta mas já deixo aqui os parabéns pela notoriedade.

Sinal de Vida

Wednesday, March 12th, 2008

Nossa, tanta coisa que nem sei o que postar. Neste tempo que fiquei afastado –quase um mês!- juntei um bando de idéias para postas mas agora falta tempo.

Neste período terminei mais um projeto. Estou alocado no mesmo cliente e temos dezenas de pequenos projetos que fazem parte de um projeto maior que faz parte de um projeto tão gigantesco que toda semana tem uma festa para comemorar que alguém lá em Perth terminou uma parte que você nem sabia que existia. Segunda-feira devo ser movido para outra parte, desta vez é apenas para prestar ajudar um grupo de desenvolvedores do cliente que está com problemas num sistema baseado em mensagens assíncronas. Deve durar até Maio, creio.

Mas não é o trabalho que me tem afastado, pelo menos não é o maior causador. O problema é a minha pesquisa. Eu tenho dedicado boa parte do meu tempo livre a me aprofundar nos assuntos necessários para uma boa compreensão de Language-Oriented Programming e Domain-Specific Languages.

Infelizmente existe duas áreas de Ciência da Computação nas quais eu nunca me interessei muito: linguagens de programação e inteligência artificial. IA é algo que eu ainda não estudo mas para entender DSLs uma das coisas mais importantes é entender como as linguagens são criadas. Isso está me fazendo tentar aprender em um mês o que eu negligenciei por anos, incluindo a leitura capa-a-capa do SCIP. Eu sei um pouco de Common Lisp mas ainda que não soubesse não seria problema, o livro usa Scheme mas você não precisa saber Scheme ara começar a ler –bem no estilo de Bertrand Meyer que ensina Eiffel no seu livro de OO.

Depois disso vem o Concepts, Techniques, and Models of Computer Programming - que é uma recomendação do Rafael- e The Seasoned Schemer. For a as dezenas de papers da ACM que tenho pesquisado.

É trabalhoso, é complicado mas é uma das coisas que me fizeram vir ara a Austrália e mudar de emprego. Na ThoughtWorks eu tenho acesso a um material seleto sobre iniciativas no mundo real destas tecnologias, e acesso à pessoas com um conhecimento sobrenatural sobre este assunto. Apesar de eu adorar fazer parte de um time fixo desenvolvendo um produto e focado em melhoria, trabalhar como consultor me dá mais liberdade para focar no meu interesse atual, que em grande parte é essa pesquisa. Eu trabalho de 9 as 17h no cliente -sem hora extra- levanto da minha mesa e em 15 minutos estou no meu apartamento.

Antes que comecem as especulações entre meus três leitores não, eu não pretendo fazer nada de útil com o resultado da pesquisa. O resultado, na verdade, não importa, para mim importa o que eu aprender no caminho.

Se tudo der errado eu faço uma aplicação em Lisp pro Facebook e fico rico :)

Gerenciando Débitos

Sunday, February 17th, 2008

Todo projeto que já participei, dos meus pet-projects até os com equipes imensas, possuem algum nível de tech debt. Sempre a mesma história: não temos tempo para isso agora, na próxima oportunidade corrigimos.

O problema é que em muitos casos o acúmulo de coisas que deixamos pelo meio do caminho é prejudicial à saúde do projeto. Mais que preciosismo de nerds e perfeccionistas, tech debt pode –e geralmente vai- atrasar o andamento do time.

Nos projetos que eu gerencio eu gosto de alocar um orçamento para resolver estes problemas. Durante o planning game eu deixo claro que precisamos resolver problemas enquanto estamos implementando funcionalidades e geralmente aloco alguns pontos na iteração para eles, normalmente algo perto de 20% do trabalho. Normalmente eu aceito que estas histórias técnicas tenham prioridade baixa e no geral tudo ocorre bem.

Se temos uma emergência então eu costumo não ser muito flexível em relação à solução do problema. As histórias técnicas neste caso ganham prioridade máxima dentro da iteração.

Como geralmente o cliente está satisfeito com a velocidade da equipe num processo ágil (se não está temos outro problema) quando sobra –e quase sempre sobra- tempo extra numa iteração geralmente eu preencho com tech debt, e em especial deixo os desenvolvedores priorizarem o que querem fazer. Muitas vezes não dá tempo para fazer homologação destas mudanças durante a iteração vigente e elas acabam indo para produção apenas na iteração posterior, mas é uma boa estratégia.

O que importa é não deixar o tech debt acumular. Se você tem duvidas dos problemas que o acúmulo de histórias técnicas causam basta lembrar a última vez que você entrou em um projeto para dar manutenção em um sistema pré-existente. Eu nunca vi um caso onde o sistema antigo não tenha toneladas de problemas causados por “deixar para depois” mudanças que não eram urgentes mas foram crescendo em urgência com o tempo.

E claro que meu projeto atual não é diferente. Trata-se da conversão de boa parte de um sistema legado em Java para Ruby (não Rails, Ruby). Como todo projeto deste tipo o orçamento não contempla uma reescrita do sistema, apenas uma conversão. Isso quer dizer que se um módulo assovia e chupa cana em Java ele, teoricamente, vai assoviar e chupar cana em Ruby.

O bom de trabalhar em um time ágil é que não é porque no início do projeto não se pensou em melhorar as coisas que isso precisa ser verdade até o fim dele. Após a equipe (desenvolvedores, analistas de negócios e gerente de projetos) percebemos que alguns itens realmente estavam atrapalhando o andamento do projeto. Nossos dias estão cercados de tarefas repetitivas que existem apenas para contornar alguma “gambiarra” que o sistema original tinha e nós estamos reproduzindo de maneira burra. Levamos a questão aos clientes e fizemos entender que se gastarmos alguns pontos nestas tarefas em algumas iterações nossa velocidade irá aumentar, e muito.

Apos conseguirmos 25% dos pontos de uma iteração para histórias técnicas veio a questão: temos dezenas de problemas, o que faremos primeiro? Como é um time grande cada um tem seu ponto de vista sobre o que está errado e o que precisa melhorar, então fizemos da maneira ágil: disciplina e flexibilidade.

Marcamos uma reunião com o time e coletamos em cartões todos os problemas que conseguíssemos pensar. Os cartões foram pregados na parede, divididos entre coisas do dia-a-dia e coisas que realmente indicam a visão que o sistema deve tomar, aspectos arquiteturais.

14022008446.jpg

Depois cada um recebeu 5 votos para distribuir entre os cartões. Quase todas as histórias eram importantes então precisamos limitar o numero de votos para entender o que realmente é critico.

14022008445.jpg

Apos este exercício nós criamos um backlog paralelo para o produto, apenas com histórias técnicas. Este backlog foi estimado e baseado nele o time decide que história técnica entra nos 25% de pontos disponíveis.

13022008442.jpg

Uma das vantagens dessa abordagem já foi percebida. Nosso sistema é um fluxo de operações em sequência. Operações em sequência são uma ótima área para programação procedural e isso fez com que os desenvolvedores originais do sistema seguissem este paradigma.

Claro que quando se mistura uma linguagem orientada a Objetos com código procedural é necessária muita cautela, e a maioria das pessoas acha que para o código ser procedural basta usar atributos públicos nas suas classes. Existem muitas métricas para qualidade de código procedural (a maioria das métricas de código OO são evoluções ou adaptações destas, na verdade) e nosso código não seguia nenhuma.

Aproveitando o nosso orçamento para histórias técnicas nós introduzimos um sistemas de jobs, uma implementação do padrão Chain of Responsibility. Até agora 50% das funções já foram convertidas para o modelo novo e a cada iteração mais são convertidas.

O resultado das ultimas iterações mostra um aumento consistente de 10% na velocidade. Todos os envolvido creditam esta melhoria à mudança e ainda estimamos que quando todo o sistema for convertido para a nova arquitetura teremos por volta de 25% de aumento total.

Existem coisas simples que podem decidir se um projeto vai ser um sucesso ou fracasso. Não esconder sujeira debaixo do tapete é uma delas.

Revendo Grupos de Usuários

Friday, February 1st, 2008

Há uns 4 ou 5 anos eu faço parte do RioJUG (mesmo na Austrália ainda faço parte do grupo) e nos últimos anos viajei e conheci JUG e outros grupos de usuários no país todo.

Acho que existem três grandes padrões para grupos brasileiros. O primeiro é do estilo do RioJUG: uma apresentação à cada X dias com uma palestra. Pouca participação do público, pouco networking. No Rio ainda é mais complicado porque as reuniões vão até tarde e as pessoas mal tem tempo para o lanche no final.

Outro padrões é o de Dojo. Pessoas se reúnem e resolvem um problema com código, aprendendo sobre ferramentas e plataformas no caminho. Muito networking, muita participação mas geralmente o conteúdo só se espalha até todos terem um razoável conhecimento sobre ele,não existe a figura de uma pessoa que apresenta algo muito novo ou experimental. Além disso no Brasil temos poucos notebooks nas mãos das pessoas -apenas gerentes líderes e etc.- o que elitiza os frequentadores.

Outro tipo é quando as pessoa apenas se reúnem para conversar. A comunidade de Software Livre é especialista nisso e geralmente a conversa começa ou termina no bar.

Todos são legais. A comunidade Java brasileira cresceu muito basicamente com este tipo de divulgação. Mas eu, sinceramente, enchi o saco.

Hoje estou no escritório da ThoughtWorks em Melbourne, onde estou baseado. Temos aqui o encontro do grupo de usuários de Ruby de Melbourne, que é hospedado aqui no escritório (também teremos aqui o BarCamp Melbourne em Fevereiro). Este grupo tem uma estrutura de reunião bem interessante.

Começa com a eventual apresentação pelo coordenador, bem rápida. Depois, durante vinte minutos, pessoas conversam sobre coisas interessantes que viram, comentários rápidos e indicações de onde achar mais informação. Depois uma apresentação sobre um tema de meia hora. Um intervalo com pizza e refrigerante (oferecidos pela anfitriã) e nos trinta minutos restantes temos lightining talks, palestras muito rápidas -cinco à dez minutos- sobre coisas aleatórias no mundo Ruby/Rails. No fim vai todo mundo para o pub, como bons australianos. Como em Melbourne anoitece às 21h nessa época do ano a noite ainda nem começou.

A palestra principal foi sobre TreeTop mas falamos sobre Faker, benchmarks de servidores web, ImageMagik, a LnuxConf Melbourne que está rolando esses dias e dezenas de outras coisas. Não haviam espectadores, todos eram participantes.

Fazia muito tempo que não tinha uma noite nerd tão agradável.