Saga do programador

18Aug/103

Especificações, código e como mantê-los unidos?

Já faz algum tempo que testes de unidade, ou unitários, tem sido assunto frequente, e as vezes acalorado, em listas de discussões. Apesar de fazer tempo que este assunto é discutido o argumento mais famoso para não adoção da técnica continua sendo o curto prazo dos projetos. Alega-se que se os desenvolvedores começarem a escrever testes, os prazos para realizações das tarefas serão aumentados, o que consequentemente aumentaria o prazo final do projeto.

Aquela velha historia

A maioria dos projetos, tem uma documentação inicial, onde são colocadas as necessidades do cliente. Num projeto tradicional, ou não, esta documentação será entregue aos desenvolvedores para fazer o milgre de transformar texto impresso no papel, em software. Até agora não contei novidade alguma, mas a coisa vai ficar mais interessante a partir de agora.

Os desenvolvedores começam então, a escrever o software baseado nas informações contidas na documentação entregue a eles. Agora imagine que boa parte do software já está implementada e o gerente de proejetos está super feliz em ver o gráfico do project bonitinho, mostrando que o projeto está até adiantado. Quando... acontece o que sempre acontece em projetos de software. Uma grande mudança, uma alteração tão radical que afetará varios pontos do sistema. Vocês já viram este filme, e sabem que numa situação dessas é comum ter que fazer tudo pra ontem e sem prejuizo ao cronograma. O que se traduz em horas extras e trabalho nos finais de semana. O ambiente de trabalho legal para os desenvolvedores costuma acabar neste ponto. Como as alterações são todas urgentes, é muito comum que a equipe concentre forças na alteração do código fonte, enquanto a alteração da documentação fica pra depois. Um depois que geralmente nunca acontece.

TDD e Documentos... onde você quer chegar?

Pronto agora cheguei onde queria =). Comecei falando de TDD e no paragrafo anterior falei de documentação desatualizada. Que relação essas coisas podem ter?

Bem, a documentação incial do projeto, em papel, descreve o que o software deve fazer (comportamento), os métodos das classes escritas pelos desenvolvedores são responsáveis por realizar este comportamento. Em um cenário, como posso dizer, "mais comum" depois do desenvolvedor implementar o software, uma pessoa seria encarregada de testar o comportamento do software, para isso ela precisaria recorrer a documentação do projeto. Mas depois da mudança a documentação vai estar desatualizada o que abre margem para problemas maiores.

Uma maneira de resolver este problema seria automatizando os testes, e neste ponto entram os testes de unidade. Imagine que nossos desenvolvedores escreveram testes de unidade automatizados para checar o compotamento de cada um dos métodos implemetados por eles. Agora não precisarimos de mais uma pessoa para testar, e o mais importante, agora temos uma documentação executável. Isso mesmo pense nos testes de unidade como sendo uma documentação executável, uma documentação que quebra se não for atualizada.

Documentação Executável

Como todos sabem a documentação mais atualizada de um software é o código fonte. O problema é que ele não é "amigavel e legivel" para todos.  Pode ser pouco agradavel ter de ficar olhando varios arquivos, classes e métodos para entender o que eles fazem realmente. Na tentativa de melhorar, esse cenário pessoas passaram a utilizar uma técnica para escrita de testes que tenta expressar mais a intenção daquele comportamento. Esta técnica é conhecida como Behaviour Driven Development (BDD), foi um termo cunhado por Dan North mais informações aqui. Mas continua sendo muito código, e fica ainda complicado identificar o que é uma pré-condição, o que realmente está sendo testado é o que é a pós-condição. No JUnit por exemplo, a responsabilidade de descrever o comportamento testado fica no nome do método, que pode ficar quilometrico (nada contra), como por exemplo: deveSerCapazDeCriarUmaListaDePedidosAPartirDoXML.

Na tentativa de tornar os comportamentos mais evidentes, sugriam framework's como RSpec utilizado por desenvolvedores ruby.
Veja abaixo um exemplo de código do RSpec

describe "Uma Conta"
it "nao deve permitir saques superiores ao valor de seu saldo" do
   conta = Conta.new
   conta.deposita 100
   lambda{ conta.saca 200}.should raise_error ArgumentError
end

Apesar de ter menos "ruido", muito também devido a linguagem ruby,  este código ainda tem muito apelo programático. Fica dificil usar um negocio desses com seu cliente, ou especialista de negocios. Então o bacana mesmo seria escrever especificações/documentação, usando o bom e velho português, e ter algum vodoo que tornasse essa documentação executável.

7Feb/1010

DRY e Blocos de Código com Ruby

O Iuri já mostrou num post anterior, como criar métodos (funções) em ruby. Sendo assim somos praticamente craques em construir funções ruby. Neste post vamos explorar recursos avançados e interessantes das funçoes ruby, para isso, utilizaremos um array com alguns nomes.

Problema Inicial:

Devemos criar um  método que seja capaz de percorrer um array, exibindo seus elementos. (Ok, tudo bem nós sabemos que todo array possui um método each. Mas vamos fingir que esse kra não existe)

lista = ["sergio","roberto", "iuri","luiz"]
def mostra_elementos( array )
  for elemento in array
    puts elemento
  end
end
mostra_elementos(lista)

Ótimo! Atingimos nosso objetivo. O codigo acima exibira os nomes contidos no array.

Os requisitos mudaram:

Agora nós queremos  percorrer o array exibindo cada um de seus elementos ao contrario, por exemplo, "sergio" será exibido como "oigres". Podemos criar um novo método para isso, então vamos ao trabalho:

 
24Nov/0910

Não é por que é dinâmico que a tipagem é fraca.

Há algum tempo atrás recebi o seguinte comentário em um dos primeiros posts quer escrevi aqui no blog:

Bom artigo amigo, porém penso que esteja havendo alguma confusão sobre o que é “tipagem forte” e o que é “type casting implícito”, em minha opinião a linguagem é fracamente tipada, haja visto que se pode atribuir uma referência de qualquer TIPO de objeto a uma variável, porém a linguagem não realiza o TypeCasting de tipos de forma implícita e arbritária como caso de algumas “Linguagens Chatas” (tomei a liberdade de utilizar seu termo…).

Como o post era antigo acabei demorando para ver o comentário e consequentemente enviar uma respota, porém o comentário aborda um assunto tão interessante, que resolvi escrever um post para esclarecer o assunto, por tanto gostaria antes de mais nada  agradecer o seu comémtario, e aqui vai a minha resposta :)