Não Existe Bala de Prata

Desenvolvimento de Software5 July 2006 3:55 am

Ultimamente tenho me interessado muito pelo RubyOnRails, que ao meu ver trousse um novo ar para o desenvolvimento web. Realmente é fantástico ver como o Rails trata bem os principais problemas enfrentados pelos desenvolvedores. E a maneira como ajuda você a manter o princípio DRY (don´t repeat yourself) é realmente uma sacada genial.

RubyOnRailsPorém nem tudo é perfeito. Por ser uma linguagem ainda “nova” ela não possui uma IDE que seja boa o suficiente para acompanhar a genialidade do Rails. Das que eu conheço o RadRails parece ser o que chega mais próximo de uma IDE decente, porém ainda deixa muito a desejar, principalmente com relação ao code complete.

Mas você só percebe como uma boa IDE faz a diferença quando utiliza uma que seja realmente produtiva. E eu percebi isso agora que comecei a utilizar o VisualStudio 2005. Usando junto com o ReSharper essa IDE é simplesmente incrível. Não importa o quando a linguagem .Net estimule você a criar código do tipo copy-paste, a verdade éVisual Studio 2005 que você consegue aumentar muito a sua produtividade. Além disso, manter o código com boa manutenibilidade depende e sempre dependerá só de você.

Não pretendo abandonar o Rails, pois vejo nele uma fonte de inspiração sobre o que se pode fazer para ter um código consistente e coeso. Porém é difícil não levar em conta o quanto é importante, principalmente em desenvolvimento web, ter uma ferramenta que faça diminuir os seus prazos de entrega. E nesse ponto o VisualStudio é imbatível. A linguagem de programação é importante, mas a IDE faz toda a diferença.

Desenvolvimento de Software11 April 2006 8:55 am

Você está programando e se depara com um problema que não consegue resolver. Fica um bom tempo pensando e tentando solucioná-lo mas não chega a nenhuma conclusão. Fica parado olhando para a tela com o código e não vê uma maneira de fazê-lo funcionar como deveria.

Então você chama o programador do seu lado e começa a contar o seu problema e, de repente, a solução surge na sua mente como mágica. E o mais estranho de tudo: o outro programador não disse uma palavra!

Na realidade essa é uma situação muito comum e qualquer programador com certeza já passou por algo semelhante. E note que o programador que ouvia suas queixas nem precisou abrir a boca. Isso quer dizer que ele nem precisava ser um programador, poderia ser qualquer pessoa que estivesse passando por ali. Pensando bem, nem precisaria ser uma pessoa, poderia ser qualquer objeto, como um pato de borracha, ou mesmo o boneco do Homer Simpson.

Homer SimpsonEu só citei o pato de borracha porque é esse o nome que recebe essa "técnica":  Rubber Ducking. Aparente a explicação por trás dessa idéia é  que, ao expor o problema de forma verbal, você acaba exercitando outras áreas do cérebro que não estavam ativas enquanto você estava calado olhando para o monitor. Por isso que quando começou a explicar a situação em voz alta você passou a vê-la por um ângulo diferente, e conseguiu chegar sozinho na solução.

Claro que nem sempre isso irá funcionar, e além disso é sempre bom consultar outras pessoas e pedir para que elas analisem o problema com você. Mas a dica aqui é para que, antes de interromper o trabalho do colega ao seu lado, tenha um pato de borracha (ou qualquer outro brinquedo) junto ao seu monitor e converse com ele em voz alta. Explique o seu problema e preste atenção nos conselhos que ele lhe passar, mesmo que seja o Homer…

 

Desenvolvimento de Software1 April 2006 4:48 am

Essas são algumas dicas que realmente fazem diferença para quem quer ser um desenvolvedor profissional de software: 

A Beleza está nos detalhes 

  1. Aprimore suas habilidades.
    Por que passar a vida desenvolvendo software se você não se preocupa em fazê-lo direito?
  2. Reflita sobre o seu trabalho
    Desligue o piloto automático e assuma o controle. Constantemente critique e valide seu trabalho.
  3. Forneça opções. Não dê desculpas esfarrapadas
    Ao invés de desculpas, forneça opções. Não diga que não pode ser feito; explique o que pode ser feito.
  4. Não conviva com janelas quebradas
    Corrija designes pobres, decisões erradas e código ruim quando se deparar com eles.
  5. Seja um catalisador de mudanças
    Você não pode forçar as pessoas a mudarem. No entanto, você pode lhes mostrar como o futuro pode ser e convencê-las a participar da sua criação.
  6. Olhe o quadro geral
    Não mergulhe nos detalhes para não esquecer de olhar o que está acontecendo ao seu redor.
  7. Faça da qualidade um requerimento obrigatório
    Envolva seus usuários para conseguir capturar os requerimentos que impõem qualidades reais para o projeto.
  8. Invista regularmente no seu portfolio de conhecimentos
    Torne a aprendizagem um hábito.
  9. Analise de forma crítica o que você lê e ouve
    Não se abale com o que dizem os vendedores, a mídia especializada ou com dogmas. Analise a informação de acordo com a sua realidade e a do seu projeto.
  10. O que você diz e como você diz
    Nada adianta ter grande idéias se você não consegue comunicá-las de maneira eficiente.
  11. DRY – Don’t Repeat Yourself (Não se repita)
    Cada pedaço do conhecimento deve ter uma representação única, sem ambigüidades e de representativa  autoridade no sistema.
  12. Torne fácil de reutilizar
    Se for fácil de reutilizar, as pessoas reutilizarão. Crie um ambiente que favoreça a reutilização.
  13. Elimine o efeito de coisas não relacionadas
    Projete componentes que sejam auto-contidos, independentes e com um único propósito bem definido.
  14. Não existem decisões finais
    Nenhuma decisão é gravada em pedra. Pense em cada decisão como sendo gravada na areia da praia e prepare-se para as mudanças.
  15. Utilize o rastro das balas para encontrar o alvo
    O rastro que as balas deixam leva você para em direção ao alvo na medida em que você experimenta novas coisas e vê quão próximo conseguiu chegar do objetivo.
  16. Faça protótipos para aprender
    Prototipação é uma experiência de aprendizagem. O seu valor não está no código produzido, mas sim nas lições aprendidas.
  17. Programe próximo do domínio do problema
    Planeje e codifique utilizando o vocabulário do usuário.
  18. Estime para evitar surpresas
    Estime antes de começar. Você descobrirá quais são os problemas em potencial para o futuro.
  19. Interaja o cronograma com o código
    Use a experiência você adquire a medida que implementa para refinar suas estimativas de prazo.
  20. Mantenha o conhecimento com comentários claros
    Comentários claros nunca ficam obsoletos. Eles ajudam a alavancar seu trabalho e simplificam o debug e testes.
  21. Use o poder da linha de comando
    Use a linha de comando quando a interface gráfica não suprir suas necessidades.
  22. Use um único editor. E use-o bem
    O editor deve ser uma extensão da sua mão. Certifique-se de que o seu editor é configurável, extensível e adaptável as suas necessidades.
  23. Sempre use controle de versão
    O controle de versão é a máquina do tempo do seu trabalho – Com ele você pode sempre voltar atrás.
  24. Corrija o problema, não a acusação
    Não importa se o bug é uma falha de outra pessoa – ele ainda assim é um problema e portanto precisa ser consertado.
  25. Não entre em pânico quando estiver debugando
    Respire fundo e PENSE sobre o que pode estar causando o bug.
  26. "select" não está quebrado
    É raro você encontrar um bug no sistema operacional, no compilador, ou mesmo em programas e bibliotecas comerciais. Na maioria das vezes o problema está mesmo na sua aplicação.
  27. Não presuma. Prove
    Prove suas suposições no ambiente atual, com dados reais e para as condições de fronteira.
  28. Aprenda uma linguagem de manipulação de textos
    Você gasta grande parte do seu dia trabalhando com textos. Por que não deixar que o computador faça algo mais por você?
  29. Escreva código que escreva código
    Geradores de código aumentam sua produtividade e ajudam a evitar duplicidade.
  30. Você não pode escrever um software perfeito
    Software não pode ser perfeito. Mas proteja o seu código e seus usuários dos erros inevitáveis.
  31. Projete para contratos (Design by Contracts)
    Utilize contratos para documentar e verificar que o código não faz nem mais nem menos do que aquilo que necessita fazer.
  32. Falhe cedo
    Um programa morto costuma causar menos estrago do que um programa aleijado.
  33. Use asserções para prevenir o impossível
    Asserções validam suas suposições. Utilize-as para proteger seu código do mundo incerto.
  34. Use exceções para problemas excepcionais
    Exceções podem sofrer dos mesmos problemas de manutenção e legibilidade dos clássicos códigos em espaguete. Reserve as exceções para coisas realmente excepcionais.
  35. Acabe o que você começou
    Sempre que possível os métodos e objetos que alocam recursos devem ser responsáveis por desalocá-los.
  36. Minimize o acoplamento entre módulos
    Evite o acoplamento escrevendo código “tímido” e aplicando a lei de Demeter.
  37. Configure ao invés de integrar
    Implemente as escolhas tecnológicas de uma aplicação como opções de configuração, não como partes integradas da aplicação.
  38. Coloque a abstração no código e os detalhes em metadados
    Programe para o caso geral e coloque as especificidades fora da base do código compilado.
  39. Analise o processo para melhorar a concorrência
    Explore a concorrência dos processos dos seus usuários.
  40. Projete utilizando serviços
    Projete em termos de serviços independentes, com interfaces consistentes e para objetos concorrentes e bem definidos.
  41. Sempre projete para concorrência
    Permita a concorrência e você irá projetar interfaces limpas e com poucas suposições.
  42. Separe visões de modelos
    Ganhe flexibilidade a um baixo custo projetando suas aplicações em termos de modelos e visões.
  43. Use quadro-negro para coordenar processos
    Use quadros-negro para coordenar agentes ou fatos discrepantes enquanto mantém a isolação e independência entre os participantes.
  44. Não programe por coincidência
    Mantenha-se nas coisas confiáveis. Cuidado com complexidade acidental e não confunda uma feliz coincidência com uma regra geral.
  45. Estime a ordem dos seus algoritmos
    Faça uma estimativa do que algoritmo precisa suportar antes de escrever código.
  46. Teste suas estimativas
    Análises matemáticas de algoritmos não lhe dizem tudo. Tente medir o desempenho do seu código no ambiente real.
  47. Refatore cedo, refatore sempre
    Assim como você remove as ervas daninhas e rearranja o jardim, reescreva e reestruture o código constantemente. Corrija na raiz do problema.
  48. Projete para os testes
    Comece a pensar como testar antes de escrever uma linha de código.
  49. Teste o seu software; ou o seu usuário testará por você
    Teste arduamente. Não faça o seu usuário encontrar os erros que você deveria ter encontrado.
  50. Não utilize assistentes de código que você não entenda
    Assistentes podem gerar toneladas de código. Esteja certo de que você entenda tudo o que foi gerado antes de incorporá-lo ao seu projeto.
  51. Não colha os requerimentos – Procure por eles profundamente
    Requerimentos raramente estão na superfície. Normalmente eles estão soterrados sob várias camadas de suposições, preconceitos e politicagem.
  52. Trabalhe com o usuário para pensar como o usuário
    Esta é a melhor maneira conseguir inspiração sobre como o sistema será utilizado.
  53. Abstrações vivem mais do que detalhes
    Invista na abstração, não na implementação. Abstrações podem sobreviver às barreiras criadas pelas mudanças de implementação e pelas novas tecnologias.
  54. Use um glossário de projeto
    Crie e mantenha uma fonte única com todos os termos e vocabulários específicos do projeto.
  55. Não pense fora caixa – Encontre a caixa
    Quando confrontado com um problema impossível, identifique as verdadeiras limitações. Pergunte a você mesmo: “Isso precisa ser feito dessa maneira? Isso precisa ser feito por completo?”.
  56. Comece quando você estiver pronto
    Você adquire experiência durante toda a sua vida. Não deixe passar desapercebido as pequenas dúvidas.
  57. Algumas coisas são melhores feitas do que descritas
    Não caia na espiral da especificação – em algum momento você precisa começar a codificar.
  58. Não seja um escravo dos métodos formais
    Não adote uma técnica sem antes analisá-la no contexto de suas práticas de desenvolvimento e capacidade.
  59. Ferramentas caras não produzem projetos melhores
    Não se impressione somente pelo preço estampado na etiqueta. Julgue as ferramentas pelos seus méritos.
  60. Organize o time pela funcionalidade
    Não separe os designers dos programadores nem os testadores dos modeladores. Forme os times da mesma maneira que você organiza o código.
  61. Não use manual de procedimentos
    Um script ou arquivo de lote pode executar as mesmas instruções, na mesma ordem, o tempo todo.
  62. Teste cedo. Teste sempre. Teste automaticamente
    Testes que rodam a cada build são muito mais eficientes do que planos de testes empoeirados em uma prateleira.
  63. O código não está terminado até todos os testes rodarem
    E ponto final.
  64. Use sabotadores para testar seus testes
    Coloque bugs propositalmente em uma cópia separada do código para verificar se os testes irão apontá-los.
  65. Teste a cobertura de estados, não a cobertura de código
    Identifique e teste estados significativos do programa. Testar apenas linhas de código não é o suficiente.
  66. Encontre um bug uma única vez
    Quando um testador humano encontrar um bug deve ser a última vez que um humano encontre esse bug. Utilize testes automáticos para verificar esse bug a partir de então.
  67. O português também é uma linguagem de programação
    Escreva documentos da mesma forma que você escreve código: obedeça ao principio do DRY (não se repita), utilize metadados, MVC, geradores automáticos, etc.
  68. Crie documentação durante, ao invés de tentar encaixá-la depois
    Documentação criada separada do código muito mais chance de estar incorreta e desatualizada.
  69. Supere um pouco as expectativas dos seus usuários
    Compreenda quais são as expectativas do seu usuário e então entregue um pouquinho mais do que ele estava esperando.
  70. Assine o seu trabalho
    Mesmo os primeiros artesões ficavam orgulhosos de assinar seus trabalhos. Você também deveria ficar.

Estas dicas foram extraidas do livro The Pragmatic Programmer

Desenvolvimento de Software, Humor24 March 2006 3:54 am

Se você já fez uma análise de requisitos para desenvolvimento de software muito provavelmente já se sentiu assim também…

Dilbert

A minha dica para você que está tentando descobrir o que o seu cliente quer do seu novo software é a seguinte:

  1. Em primeiro lugar nunca pergunte ao cliente o que ele quer que o novo sistema faça.
  2. Compreenda como são feitos hoje os processos do cliente.
  3. Pergunte ao cliente quais processos que ele sabe que funcionam bem no sistema atual. Faça o cliente explicar porque ele acha que funcionam bem.
  4. Descubra quais são processos atuais que existem mas ninguém usa.
  5. Baseado nessas informações desenvolva um protótipo do que você acredita que o cliente precisa. Quanto mais claramente esse protótipo puder ser compreendido pelo cliente melhor. Por exemplo, se for um cliente da área técnica você poderá lhe mostrar os casos de uso. Se for um cliente de negócio você vai precisar de algo mais visual…
  6. Faça (essa parte às vezes é difícil) o cliente analisar o seu protótipo.
  7. Sempre esteja cara-a-cara com ele enquanto estiver fazendo a análise.

  8. Assinale os requisitos que o cliente concorda e aqueles que ele discorda. Baseado nessas informações descubra se ainda existem pontos do processo que você não entendeu corretamente.
  9. Faça um novo protótipo. A partir daqui o processo se repete até que o cliente concorde com a maioria dos requisitos do sistema.

Tentar fazer com que todos os requisitos sejam validados e aprovados pelo cliente pode consumir muito tempo. Se o cliente já concordou com a maior parte então está na hora de colocar a mão na massa e começar o desenvolvimento. Quanto aos requisitos que não foram aprovados eles fazem parte dos requisitos que iriam mudar de qualquer jeito…

Desenvolvimento de Software22 March 2006 4:06 am

Desde quando o desenvolvimento de software se tornou uma atividade profissional milhares de pessoas têm tentado medir a produtividade dos seus programadores. E a primeira “métrica” que se imaginou, e talvez a mais famosa, é o loc ou lines of code.
A idéia é bem simples: basta contar quantas novas linhas de código o programador escreveu em cada dia, colocar tudo em uma planilha, e verificar se ele está rendendo mais ou menos.

Claro que hoje é fácil de perceber que não pode haver uma idéia mais absurda do que essa para se medir o trabalho de um programador. Acho que a estória que melhor ilustra essa incoerência foi o que aconteceu com um programador que participava do desenvolvimento do sistema operacional do Lisa, da Apple, em 1982.

Apple Lisa OS - 1983
Naquela época, os gerentes do projeto decidiram que cada desenvolvedor iria anotar semanalmente quantas linhas de código eles tinham produzido. Um desses desenvolvedores, Bill Atkinson, estava trabalhando na otimização de uma parte de código e acabou reescrevendo toda aquela seção de uma maneira mais genérica e que ainda por cima rodava seis vezes mais rápido. Como conseqüência, esse novo trecho acabou sendo bem mais conciso e acabou economizando 2000 linhas de código.
Quando teve que preencher o relatório de quantas linhas de código tinham sido produzidas, Bill anotou -2000 linhas. Isso mesmo, ele anotou um número negativo, o que deve ter criado uma grande inconsistência nos resultados de acompanhamento do projeto. Algumas semanas depois os gerentes pararam de cobrar a quantidade de linhas de código dos desenvolvedores.
Como desenvolvedor, acredito que qualquer tentativa de medir o progresso através de informações de baixo nível, como o código fonte, não mostra absolutamente nada de conclusivo. Mesmo existindo várias outras métricas mais aprimoradas que derivaram da loc mesmo assim são indicadores de quase nada. Mas o que fazer se, como disse Lord Kelvin, “o que não pode ser medido não existe”?

Progress Bar
Eu só vejo uma solução: se você quer medir o progresso do desenvolvimento de um sistema então precisa medir funcionalidades macro. Por exemplo, medir quantos casos de uso foram implementados ou quantas funcionalidades de alto nível estão prontas para serem usadas. Tentar medir em níveis mais baixos que isso pode até gerar planilhas recheadas de números, mas que irão dizer absolutamente nada.