Rails Summit 2009: “Yet Another Ruby Framework” em vídeo

19 de dezembro de 2009  |  Apresentações, Vídeos  |  6 Comentários  | 

A Locaweb disponibilizou através do seu portal no Vimeo os vídeos das palestras no Rails Summit 2009. No total são 13 vídeos, o suficiente para você se manter ocupado por todo o feriado.

Abaixo você pode ver a gravação da minha palestra no evento. A ideia geral é mostrar que Ruby on Rails embora tenha uma influência muito forte, não deixa de ser apenas “mais um framework Ruby”. Isto deve nos motivar a também buscar outras alternativas, ou até mesmo criar novos frameworks, quando Rails não mostrar ser a melhor opção para o desenvolvimento de um projeto.

Você também pode encontrar outras apresentações na minha página de palestras.

Rails 3: Uma nova forma de criar mensagens flash

18 de dezembro de 2009  |  Rails 3  |  4 Comentários  | 

Como a maioria deve saber, um dos grandes diferenciais do Rails vem de uma característica que também é marcante em seu criador. Ruby on Rails é um software de opinião. Atualmente DHH não é mais tão ativo no desenvolvimento do Ruby on Rails quanto no passado. Porém de tempos em tempos ele aparece com algumas inclusões polêmicas no framework.

Seu último patch é referente a inclusão das opções :alert, :notice e :flash no método redirect_to. Assim, se antes fazíamos desta maneira:

flash[:notice] = 'Post was created'
redirect_to(@post)

Agora podemos fazer assim:

redirect_to(@post, :notice => 'Post was created')

Esse sem dúvida é um recurso interessante e nos ajudará a diminuir a quantidade de linhas de código que escrevemos. Porém alguns desenvolvedores não gostaram desta implementação argumentando que não costumam utilizar flash[:alert] como sinalizador de problemas, mas sim flash[:error].

A resposta de DHH? “Nós estamos utilizando alert para tudo na 37signals. Isto realmente não importa. Só que exista um sinalizador para continuar e outro para parar”.

Aceitando ou não esta explicação é importante lembrar do fato de que desde o principio foram estas “convenções” que tornaram o Rails o que ele é hoje. Sendo assim, a melhor coisa a fazer é passar a adotar o padrão definido.

Outros exemplos extraídos da documentação:

redirect_to post_url(@post), :alert => "Watch it, mister!"

redirect_to post_url(@post), :status=> :found,
  :notice => "Pay attention to the road"

redirect_to post_url(@post), :status => 301,
  :flash => { :updated_post_id => @post.id }

redirect_to { :action=>'atom' }, :alert => "Something serious happened"

[Atualização 18/12/2009 18:20]

Uma informação importante é que existe uma boa chance deste novo recurso entrar em algum futuro release do Rails ainda na versão 2.3.x.

Além disso, também esqueci de mencionar que foram criados métodos mais convenientes para facilitar o acesso ao flash[:notice] e flash[:alert]. Podemos acessar estes recursos simplesmente assim:

<p class="notice"><%= notice %></p>

<p class="alert"><%= alert %></p>

Rails 3: Uma nova DSL para a configuração de rotas

14 de dezembro de 2009  |  Rails 3  |  5 Comentários  | 

Muitas novidades estão sendo preparadas para a próxima versão do Rails. Uma que já estamos observando a alguns dias é a nova DSL para a configuração de rotas.

O Rails 3 ainda está em desenvolvimento, isto significa que o código da DSL pode sofrer alterações até o lançamento oficial. De qualquer forma você pode ir matando a curiosidade analisando o novo arquivo config/routes.rb que está sendo gerado pelo Rails 3.0.pre neste momento. Eu tomei a liberdade de traduzir os comentários para facilitar o entendimento.

ActionController::Routing::Routes.draw do |map|
  # A prioridade é baseada na ordem da criação:
  # criado primeiro -> maior prioridade.

  # Exemplo de uma rota comum:
  match 'products/:id', :to => 'catalog#view'
  # Tenha em mente que você pode atribuir outros valores além de
  # :controller e :action

  # Exemplo de uma rota nomeada:
  match 'products/:id/purchase',
    :to => 'catalog#purchase', :as => :purchase
  # Esta rota pode ser invocada utilizando
  # purchase_url(:id => product.id)

  # Exemplo utilizando resources (mapeia verbos HTTP para ações do
  # controller automaticamente)
  resources :products

  # Exemplo utilizando resources com opções:
  resources :products do
    member do
      get :short
      post :toggle
    end

    collection do
      get :sold
    end
  end

  # Exemplo utilizando resource com sub-resources:
  resources :products do
    resources :comments, :sales
    resource :seller
  end

  # Exemplo mais complexo de uso de resources com sub-resources:
  resources :products do
    resources :comments
    resources :sales do
      get :recent, :on => :collection
    end
  end

  # Exeplo utilizando resource com um namespace:
  namespace :admin do
    # Direciona /admin/products/* para Admin::ProductsController
    # (app/controllers/admin/products_controller.rb)
    resources :products
  end

  # Você pode definir a home do seu site utilizando "root"
  # Lembre-se de apagar o arquivo public/index.html.
  root :to => "welcome"

  # Você pode listar todas as rotas disponíveis com "rake routes"

  # Deixe a rota padrão com a prioridade mais baixa possível.
  # Nota: A rota padrão torna todas as actions em qualquer controller
  # acessíveis via solicitações GET. Você deve considerar a remoção
  # ou comentar esta linha se estiver usando rotas nomeadas e recursos.
  match ':controller(/:action(/:id(.:format)))'
end

[ATUALIZAÇÃO 21/12/2009 3:00]

A DSL sofreu uma leve alteração que simplifica ainda mais a especificação de rotas.

# As duas linhas a seguir fazem a mesma coisa
match 'products/:id', :to => 'catalog#view'
match 'products/:id' => 'catalog#view'

Como montar um servidor de gems privado

9 de dezembro de 2009  |  Ruby  |  4 Comentários  | 

rubygemsNão é segredo para ninguém que eu estou exaustivamente trabalhando em um novo framework para o desenvolvimento de aplicativos sociais de forma ultra-rápida. Porém ainda não está na hora de liberar o projeto como open source, mas é certo que isto acontecerá em breve.

O framework já está em sua versão 0.5.2 e em pleno uso e desenvolvimento. Como decidimos não liberar o projeto até que ele esteja finalizado, não podemos simplesmente disponibilizar as gems em serviços como o Gemcutter. Assim, toda vez que precisamos instalar ou atualizar as bibliotecas em nossos servidores temos de fazer isto manualmente, copiando os arquivos .gem para o servidor e instalando a partir deles. Este processo é realmente irritante, então surgiu a necessidade de montar o no nosso próprio servidor de gems privativo.

A solução é ridiculamente simples. Mas como acredito que muita gente também pode se beneficiar disso, segue a receita de bolo.

A forma simples

A primeira alternativa é utilizar o seu próprio computador como um servidor de gems. Para fazer isto basta executar o seguinte comando no terminal:

gem server

Pronto! Desta maneira você já estará compartilhando todas a gems que estão instaladas em sua máquina através do endereço http://SEU_IP:8808.

Uma alternativa melhor

Como em nosso caso era importante manter o serviço o tempo todo no ar, a solução foi hospedar as bibliotecas em um servidor web.

O processo também é muito simples. Crie um diretório qualquer em uma área pública do seu servidor web (digamos que você criou um diretório com o nome de meusgems). Crie então um subdiretório chamado gems e copie todos os seus arquivos .gem para dentro dele.

Antes de continuar certifique-se de ter o RubyGems instalado em seu servidor. Então execute o seguinte comando dentro do diretório meusgems:

gem generate_index

Feito! Seu servidor privado de gems está no ar. Quando adicionar ou atualizar alguma biblioteca, basta executar o comando acima novamente.

Instalando gems a partir do seu servidor

Para fazer com que o comando gem install encontre as bibliotecas que estão no seu servidor, você deve adicionar o endereço na lista de fontes do RubyGems. Para isto execute o seguinte comando no computador onde os gems devem ser instalados:

gem sources --add http://gems.meu_servidor.com

Claro que você deve alterar o endereço acima para a URL correta do seu servidor. Depois disso basta instalar as suas bibliotecas normalmente, através do comando gem install nome_do_gem.

Caso seu repositório de gems comece a crescer muito, talvez seja interessante configurar o projeto Gemcutter em seu servidor.

Esta pode ser uma alternativa bem interessante para estimular a reutilização de código dentro de sua empresa, sem precisar liberar todas as suas bibliotecas como open source.

Ortogonalidade

1 de dezembro de 2009  |  Opinião  |  9 Comentários  | 

Infelizmente a maioria dos programadores que conheço nunca ouviram falar sobre ortogonalidade no desenvolvimento de software, embora este seja um principio fundamental para se escrever código de qualidade.

Em desenvolvimento de software, o termo ‘ortogonalidade’ passou a significar uma espécie de independência ou dissociação. A ideia é que componentes que conceitualmente não estão relacionados devem ser construídos de forma a não possuírem nenhuma dependência entre si. Adicionar um novo atributo a um objeto do ActiveRecord (na maioria das vezes) não deveria exigir uma alteração na interface com o usuário, por exemplo.

Foto de Voxphoto

Foto de Voxphoto

Em linguagens orientadas a objetos é muito fácil acrescentar dependências ao código. Em Ruby basta um simples ‘require‘ e seu projeto passa a depender de uma ou várias bibliotecas. Talvez devido a essa simplicidade este tende a se tornar um problema viral, já que nos estimula a estarmos sempre adicionando mais e mais dependências em nossos sistemas.

Queremos projetar componentes auto-suficientes e com um único propósito bem definido. Sistemas não ortogonais são difíceis de alterar. Em projetos onde seus componentes dependem uns dos outros não existem correções pontuais. Uma correção pode levar a um ou mais problemas em outra parte. E isto pode se tornar um ciclo sem fim.

Por outro lado, em sistemas onde os componentes são isolados uns dos outros, desde que você não mude a sua interface pública, você sabe que pode alterar um deles sem se preocupar com os outros.

Os ganhos em produtividade ao colocar em prática este principio são imensos. Uma abordagem ortogonal promove a reutilização. Como seus componentes serão bem específicos e com responsabilidades bem definidas é fácil reaproveitá-los em outros sistemas. Outro fator importante é que por possuírem apenas o código necessário para cumprir uma única tarefa, obviamente estas bibliotecas serão menores e mais simples de serem projetadas, implementadas, testadas e dificilmente precisaremos revisita-las para adicionar novas funcionalidades ou fazer correções.

O fato de serem componentes menores e com menos código também simplifica a criação de testes. E mesmo que um bug passe despercebido ele não será tão critico, pois o tempo de resolução será menor e a chance de o problema se espalhar por todo o sistema são mínimas, o que diminui os riscos.

Vamos considerar como exemplo o desenvolvimento de um e-commerce. O requisito original previa apenas uma interface web simples, mas as exigências foram alteradas para também contemplar uma interface web para telefones celulares e para compras através de uma central telefônica. Em um sistema projetado ortogonalmente, você precisaria alterar apenas os módulos associados com a interface do usuário para lidar com isso. Se o seu sistema foi bem estruturado, você deveria ser capaz de suportar todas essas interfaces com o mesmo código criado inicialmente para realizar as vendas. O paradigma MVC utilizado no Ruby on Rails funciona bem nestas situações.

Testes unitários são uma ótima forma de verificar a ortogonalidade de um componente. Se para realizar o teste é necessário carregar ou acessar uma grande quantidade de outras bibliotecas, então você encontrou um módulo que não está bem dissociado do resto do sistema. Outra forma menos interessante de realizar esta avaliação é ao corrigir bugs. Quando você faz uma alteração, outros problemas surgem misteriosamente? Esta é uma evidência de que seu código não é ortogonal.

Ortogonalidade está intimamente relacionado com o princípio DRY (veja mais aqui e aqui). Enquanto DRY visa minimizar a duplicação dentro de um sistema, com a ortogonalidade você reduz a interdependência entre os componentes do sistema. Utilizar estes dois princípios combinados tornará nossos projetos muito mais flexíveis e fáceis de manter.


Este artigo é descaradamente ‘baseado’ no capítulo de mesmo nome do livro The Pragmatic Programmer.

Instalando a linguagem Go no Mac

13 de novembro de 2009  |  Open Source  |  3 Comentários  | 

logo-153x55O Google acabou de anunciar o lançamento de uma nova linguagem de programação chamada Go. A linguagem foi desenvolvida por um time formado por cinco engenheiros do Google, incluindo Ken Thompson e Rob Pike, que são famosos por terem trabalhado no UNIX.

De acordo com o Google, além de oferecer suporte integrado a processos concorrentes, Go tem a pretensão de combinar a velocidade de desenvolvimento de uma linguagem dinâmica com a performance de uma linguagem compilada.

Eu ainda não testei a linguagem o suficiente para poder expressar qualquer opinião. De qualquer forma, a melhor coisa a fazer é testar por si próprio e tirar suas próprias conclusões. Abaixo você vai encontrar um breve tutorial com os passos que percorri para instalar tudo o que é necessário para começar a brincadeira no meu Mac Os. Espero que ele seja útil para você também.

Instalando o Mercurial

Mercurial é uma ferramenta de controle de versão distribuído, assim como o nosso querido Git. É necessário instalá-lo para poder baixar o código fonte do Go.

Eu utilizei o instalador disponível para Mac na página de downloads no próprio site da ferramenta.

Após a instalação, você pode verificar se tudo deu certo digitando o comando abaixo no terminal:

$ hg version

No meu caso, uma mensagem de erro foi disparada e a solução foi configurar algumas variáveis de ambiente. Se isto também acontecer com você, abra o arquivo ˜/.profile e acrescente as seguintes linhas no final:

# Mercurial
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8

Configurando o ambiente para a instalação do Go

Aproveite que você já está com o arquivo .profile aberto e também acrescente as seguintes linhas no fim do arquivo. Estas linhas servem para configurar o seu ambiente para a instalação do Go.

# Go
export GOROOT=$HOME/Sources/go
export GOOS=darwin
export GOARCH=amd64
export GOBIN=$HOME/Development/Go/Binaries
export PATH=$GOBIN:$PATH

$GOROOT deve conter o diretório onde o código fonte da linguagem será baixado.

As variáveis $GOOS e $GOARCH servem para configurar o seu ambiente. As combinações validas são: linux/amd64, linux/arm, linux/386, darwin/amd64, darwin/386 e nacl/386. O código acima está preparado para a instalação no Mac OS 10.6.

E por último, a variável $GOBIN deve conter o diretório onde você deseja que os binários do Go sejam instalados. Se você optar por instalar os binários no diretório /usr/local/bin, aconselho ler esta discussão. Esta variável é opcional e o valor padrão para ela é o diretório $HOME/bin.

Para garantir que tudo está funcionando execute:

$ env | grep '^GO'

O resultado deve ser uma lista semelhante a esta:

GOBIN=/Users/carlosbrando/Development/Go/Binaries
GOARCH=amd64
GOROOT=/Users/carlosbrando/Projects/go
GOOS=darwin

Instalando

Após instalar o Mercurial, utilize o comando abaixo para recuperar o código fonte do projeto:

$ hg clone -r release https://go.googlecode.com/hg/ $GOROOT

Antes de continuar, certifique-se de criar o diretório que você configurou para receber os binários e execute os comandos abaixo:

$ cd $GOROOT/src
$ ./all.bash

Criando o primeiro programa

Se tudo correu bem, você já tem o seu ambiente pronto para começar a programar em Go. E nada melhor do que um “Hello, world” para começar. Crie um arquivo com o nome helloworld.go e adicione o seguinte código nele:

package main

import fmt "fmt"

func main() {
  fmt.Printf("Hello, world\n");
}

Primeiro compile o arquivo com o comando:

$ 6g helloworld.go

Para “linkar” o arquivo utilize:

$ 6l helloworld.6

E para executar:

$ ./6.out
Hello, world

Agora é só continuar no tutorial criado pelo próprio time de desenvolvimento. E não deixe de compartilhar suas experiências com a linguagem deixando um comentário.

Por que reuniões são tóxicas? (ou por que programadores odeiam reuniões)

11 de novembro de 2009  |  Opinião  |  4 Comentários  | 

546730647_ff1ea80217Muitas reuniões são convocadas apenas para auto-afirmação dos gestores quando poderiam ser evitadas e todos os assuntos resolvidos com um simples e-mail. Não existe nada mais tóxico à produtividade do que uma reunião.

Paul Graham escreveu um artigo intitulado “Maker’s Schedule, Manager’s Schedule” que explica o motivo de nós programadores odiarmos tanto reuniões. Acontece que o nosso cronograma funciona de uma forma diferente que o das outras pessoas. Reuniões nos custam mais caro.

A agenda do gerente segue o modelo tradicional, onde cada dia é dividido em intervalos de um hora. Programar uma reunião é apenas um problema de ordem prática, basta encontrar um intervalo em aberto na sua programação e escrever “reunião”. Quando se gerencia o tempo desta maneira, você pode reservar algumas horas para uma única tarefa se for necessário, mas por padrão você pode mudar o que está fazendo a cada hora.

Mas programadores (e outros profissionais) gerenciam o tempo de outra maneira. Eles geralmente costumam dividir sua agenda em dois períodos: manhã e tarde. Não é possível desenvolver software bem em unidades de uma hora. Isso não é tempo suficiente nem para começar.

É por este motivo que programadores odeiam tanto reuniões, afinal uma única reunião pode acabar com uma tarde inteira de trabalho, dividindo-a em dois pedaços pequenos demais para fazer qualquer coisa importante.

Eu sei que pode soar um pouco sensível demais, mas em alguns casos mesmo uma rápida reunião no meio da tarde pode deixar um programador improdutivo por um dia inteiro. Se eu sei que a tarde será quebrada, então eu sou menos propenso a iniciar algo ambicioso no período da manhã.

Nós entendemos a importância das reuniões. Tudo o que estamos pedindo aos gerentes é que eles entendam os custos.

A principal habilidade do programador não é codificar

6 de novembro de 2009  |  Opinião  |  7 Comentários  | 

PDHeadInSand

Programadores são naturalmente introvertidos e não sabem se comunicar. Deve ser por isso que existem tantos programadores ruins. Programar é um exercício de comunicação.

Anos de experiência desenvolvendo software, conhecer muitas linguagens de programação, escrever códigos de qualidade, nada disso tem valor se você não conseguir se comunicar com outras pessoas. De nada vale ter muito conteúdo e guardar isto só para você.

Aqueles que desejam uma carreira bem sucedida como programadores, além possuir um conhecimento técnico acima da média também precisam estar constantemente melhorando suas habilidades de comunicação.

Inevitavelmente passamos horas em reuniões. Precisamos interagir com clientes e entender as suas necessidades. Escrevemos propostas e relatórios. Estamos em uma luta sem fim tentando convencer nossos companheiros e empregadores a adotarem uma nova tecnologia ou prática que tornará nosso trabalho mais produtivo e divertido. E acima de tudo: escrevemos muito código.

O código é uma combinação de signos utilizados para transmitir uma mensagem. Porém a comunicação só se concretizará se o receptor souber decodificar a mensagem. Computadores costumam fazer isto muito bem, mas não estamos escrevendo código apenas para máquinas. Um código mal escrito e cheio de ruído dificultará o trabalho de outros programadores quando houver a necessidade de estudá-lo.

Nosso trabalho se resume a pura e simplesmente comunicar-se, por isso é tão importante fazer isso bem.

Não importa se você está escrevendo um livro/relatório/e-mail ou se preparando para uma reunião, planejamento é tudo. Um dos segredos dos bons comunicadores é saber o que dizer, antes de sair abrindo a boca e despejando pensamentos. Pergunte-se: “Se eu falar desta maneira, será que todos entenderão com clareza a informação que eu estou tentando passar?”. Repita esta pergunta para si mesmo até que esteja convicto disso. Anote estas ideias e planeje como aborda-las.

Comunicação é repassar informações. Para que isto seja possível é vital que todas as pessoas presentes entendam o que você está dizendo. Antes de começar a argumentar sobre as vantagens de se utilizar um banco de dados não relacional no projeto, certifique-se de que todos sabem do que você está falando. Caso contrário, você não estará impressionando ninguém. Estará apenas sendo chato.

Se você está vendendo uma ideia, certifique-se de conhecer cada uma das pessoas envolvidas na negociação e fale somente o que ela precisa ouvir, nem mais nem menos. Talvez você precise convencer o seu gerente, o pessoal de marketing, o usuário final do aplicativo e até outros desenvolvedores. Trate cada grupo de forma individual.

Tão importante quanto dizer a coisa certa, é dizer na hora certa. Pegar seu gerente no corredor, logo após o seu supervisor lhe chamar a atenção por ele ter entregue um aplicativo cheio de bugs é uma excelente oportunidade para convencê-lo a adotar testes automatizados nos próximos projetos. Mas também será uma péssima hora para pedir um upgrade na sua máquina.

Para ser tornar um bom escritor é necessário ler muito, seguindo o mesmo principio se você deseja falar bem é importante escutar. Programadores tem sérios problemas para escutar. Durante uma reunião, assim que o cliente começa a explicar uma funcionalidade do novo aplicativo, a mente do programador abandona a sala e automaticamente já começa a trabalhar no código que precisará ser desenvolvido. Deste momento em diante tudo o que for dito na sala será ignorado. Concentre-se. Se você não escutar o que os outros estão dizendo, como espera ser ouvido?

Lembre-se disso: Não é somente o que você diz, mas também como você diz. A menos que você esteja trabalhando sozinho dentro de uma bolha, você deve ser capaz de se comunicar. E quanto mais eficaz for a sua habilidade de comunicação, mais influente você se tornará.

Seu conhecimento tem um prazo de validade

27 de outubro de 2009  |  Opinião  |  8 Comentários  | 
3289805507_4b5a5e6c06

Foto de James Yeung

Deus ajuda quem cedo madruga. De acordo com este antigo provérbio se você tem o hábito de acordar cedo e trabalhar por horas a fio com muito afinco e dedicação, então você se dará bem na vida. Mas isto também vale para a carreira de um programador? Muita dedicação e trabalho duro são o suficiente para atingir a imortalidade?

Embora exista muita gente esforçada que literalmente dá a sua vida pela empresa em que está trabalhando, não é o trabalho braçal que determinará o seu sucesso. O seu conhecimento e experiência é que são o seu maior patrimônio profissional.

Mas infelizmente nessa área de atuação o nosso conhecimento tem um prazo de validade muito curto. Novas tecnologias, linguagens de programação e metodologias aparecem quase que diariamente e é cada vez mais difícil acompanhar este ritmo. Por outro lado, não acompanhar estas mudanças pode torna-lo obsoleto para o mercado.

Profissionais mais antigos já estão acostumados com isto, só que até pouco tempo atrás a necessidade de se reciclar não exigia tanta velocidade. Quando uma nova tecnologia era lançada, normalmente demorava um tempo até que o primeiro livro fosse publicado e para que outros profissionais e empresas começassem a adota-la.

Agora dado a quantidade crescente de novos artigos, livros, screencasts e blogs na internet, isto tem acontecido cada vez mais rápido. Existem estudos que indicam que a soma da informação do mundo dobra a cada 80 dias. Analisando desta forma, se você permanecer três meses sem se atualizar, já pode se considerar obsoleto.

Pegue como exemplo o Ruby Inside Brasil. Lá são publicados artigos quase que diariamente sobre um único tema: Ruby. Temos uma equipe relativamente grande e muito motivada tentando cobrir as principais noticias relacionadas a esta linguagem de programação e mesmo assim isso algumas vezes tem se tornado uma tarefa árdua dado a grande quantidade de informação gerada em cima deste único tópico.

Assim como o seu conhecimento, o seu valor para uma empresa ou cliente também vai diminuindo com o tempo. Precisamos trabalhar para que isto nunca aconteça. Não existe nada pior do que continuar empregado apenas por ter muito tempo de casa.

Qual é a sua estratégia para se manter atualizado?

Qualidade demais pode arruinar seu software

18 de outubro de 2009  |  Opinião  |  14 Comentários  | 
3280667337_34ccf55864

Foto de Ernest Descals

Não entendo muito de pintura, mas os amigos que apreciam este tipo de trabalho sempre dizem que uma das coisas mais difíceis sobre pintar é saber quando parar. Entender que o trabalho terminou. Uma pincelada a mais pode arruinar um lindo quadro.

Acredito que o mesmo acontece com software. Programadores profissionais sempre defenderam refatoração, testes, integração contínua e outras práticas que visam deixar nosso código mais limpo e livre de falhas. Mas existe um limite para a aplicação dessas práticas? É possível que a preocupação exagerada com a qualidade do software acabe prejudicando o projeto?

Ferramentas como Flog, Flay e Heckle foram criadas para que pudéssemos estressar nosso código ao limite. Ter um código limpo, sem repetições e com testes bem feitos é essencial para o sucesso de um projeto, sem dúvida nenhuma. Mas o fato é que vivemos em um mundo imperfeito e o sonho de um software livre de bugs é um objetivo impossível de ser alcançado. O tempo, as pessoas e até a nossa amada tecnologia, tudo conspira contra nós. Então quando é a hora de parar e declarar o trabalho como finalizado?

A primeira coisa que precisamos ter em mente é que um projeto de software bem-sucedido não é necessariamente livre de bugs, mas sim um software que atende aos requisitos exigidos pelo seu cliente ou usuário. Isto não quer dizer que você deve jogar tudo para o alto e deixar seu código apodrecer. Mas que você deve considerar o quão importante é a ausência de falhas ou a qualidade do código para o seu cliente.

Se você estiver desenvolvendo um software que controlará algum equipamento médico ou uma aeronave ou estiver trabalhando em uma biblioteca open source que será amplamente utilizada, então você não tem escolha e suas opções serão mais limitadas. Porém, este tipo de projeto é uma exceção. Na maior parte do tempo estaremos trabalhando em produtos comerciais mais simples onde seu cliente terá um cronograma de entrega baseado em promessas feitas a seus superiores e sua empresa certamente terá um fluxo de caixa apertado.

Da mesma forma como seria pouco profissional aceitar prazos impossíveis e deixar testes de lado para terminar um projeto dentro do prazo, também não seria nada profissional ignorar as necessidades do seu cliente/usuário simplesmente para adicionar uma nova funcionalidade ou refatorar o código mais uma vez.

Depois de mais de dez anos trabalhando com software, posso dizer empiricamente que muitos usuários preferem usar um software com algumas arestas soltas do que esperar um ano por uma versão livre de falhas. Muitas vezes é melhor um software ótimo agora do que um software perfeito amanhã.

Ainda há uma outra vantagem nessa abordagem. De acordo com o livro Getting Real: “A coisa mais importante em desenvolvimento de software é motivação. Motivação é localizada—se você não está motivado pelo que está trabalhando neste instante, as chances de que isso não saia tão bom são grandes . Na verdade, isso provavelmente vai ficar ruim”. Ciclos de entregas longos e demorados são assassinos de motivação.

Se você dá algo para seus usuários brincarem no início, as suas reações muitas vezes levarão a uma solução melhor.

Programar é como pintar. Tudo começa com um quadro branco, seguido por um esboço, uma pintura maior e então com o preenchimento dos detalhes. Se seu olhar for critico demais, você não saberá quando parar até que tenha estragado a sua pintura.