quinta-feira, 10 de julho de 2014

Como ser um bom programador?

Como ser um bom programador? É uma pergunta interessante para fazermos a nós próprios. Isto obriga-nos a refletir sobre a arte do desenvolvimento de software. Também é uma boa pergunta para fazer aos nossos colegas. Ela pode desencadear algumas discussões interessantes sobre como podemos trabalhar em conjunto. Aqui estão cinco características que podem ser fundamentais, para ser um bom programador.

1. Decomposição do problema 

A programação trata da resolução de problemas. Mas antes de escrever qualquer código, é necessário ser claro sobre a forma de resolver o problema. Uma característica que os bons programadores têm é a capacidade de dividir o problema em partes cada vez mais pequenas, até que cada parte possa ser facilmente resolvida. Mas não basta simplesmente encontrar uma maneira de resolver o problema. Um bom programador encontra uma maneira de modelar o problema, de tal forma que o programa resultante é fácil de entender, fácil de implementar e fácil de testar.

Alguns dos programas mais complicados com que trabalhamos, só são complicados, em parte, porque a implementação não resolve bem o problema. Isso leva a um código que é difícil de entender. Quando o problema é bem modelado, temos que concordar com Bernie Cosell (excelente entrevista em Coders at Work):

“…há muito poucos programas inerentemente difíceis. Se estiver a olhar para um pedaço de código e parecer muito difícil - se não conseguir entender o que estas coisa é suposto fazer – isso é quase sempre um indício de que foi mal pensado. Nesta altura, não arregaça as mangas e tenta corrigir o código; vai dar um passo atrás e pensar sobre o problema, novamente. Quando pensar o bastante, vai descobrir que é fácil.”

2. Análise de Cenários

Os bons programadores têm a capacidade de considerar vários cenários diferentes para o programa. Isso se aplica tanto à lógica do programa, como aos eventos internos e externos que podem ocorrer. Para considerar os diferentes caminhos na lógica, eles fazem perguntas como: O que acontece se este parâmetro é null? E se nenhuma destas condições for verdadeira? Este método é thread-safe? Para descobrir quais os tipos de eventos com que o software necessita de lidar, eles vão fazer perguntas como: E se essa fila ficar cheia? E se não houver nenhuma resposta a este pedido? E se o outro servidor reinicia enquanto este servidor está a reiniciar?

Os bons programadores perguntam a si próprios: Como pode ocorrer um “break” no programa? Por outras palavras, eles têm a capacidade de pensar como testers. Em contraste, os programadores inexperientes, normalmente, consideram apenas o "caminho fácil" - o fluxo normal de controlo, quando tudo correr como esperado (o que acontece a maior parte do tempo). Mas, inevitavelmente, o inesperado acontece e o programa tem que ser capaz de lidar com isso.

3. Nomenclatura

A programação consiste em grande parte em dar nomes a coisas: classes, métodos e variáveis. Quando bem feito, o programa torna-se, em grande parte auto-documentado, o que significa que a função do programa é bastante clara apenas a partir da leitura do código fonte. Um dos efeitos do código auto-documentado é que, naturalmente, leva a existirem muitos métodos de pequena dimensão, em vez de poucos métodos grandes, simplesmente porque vão existir mais lugares para colocar nomes significativos (há outras razões pelas quais é benéfica a existência de muitos métodos pequenos).

Conseguir criar bons nomes é muito mais difícil do que parece. Uma boa citação (de Phil Karlton): "Há apenas duas coisas difíceis em Ciência da Computação: Invalidação de cache e dar nomes a coisas". Dar nomes é difícil, em parte, porque é necessário ser claro o que cada nome representa, na nossa mente. Às vezes isso não é imediatamente claro, mas só se torna evidente quando o desenvolvimento avança. Portanto, a renomeação é tão importante quanto a nomeação.

Dar nomes às coisas correctamente também inclui encontrar conceitos a serem utilizados e como esses conceitos devem ser chamados. Criar nomes distintos e bem pensados, para conceitos, que são vão ser usados ​​de forma consistente (no programa e quando se discute o domínio com programadores e não programadores), torna a escrita do programa muito mais fácil.

4. Consistência

Talvez o maior desafio na programação esteja em gerir a complexidade. A consistência é uma forma de combater a complexidade. Ela diminui alguma da complexidade, por nos permitir ver os padrões e inferir como as coisas são chamadas, usadas ​​e tratadas. Com consistência, não precisamos usar o poder do cérebro para nos lembrarmos de excepções e variações aleatórias. Em vez disso, podemo-nos concentrar na complexidade essencial, não na complexidade acidental.

A consistência é importante em toda a linha. Aplica-se a nomes de variáveis ​​e métodos, a divisão em módulos, a estrutura de directórios, o GUI, tratamento de erros, logging, a documentação, etc. Por exemplo, se algumas variáveis ​​estão relacionados e aparecem juntas (em declarações, chamadas a métodos ou como colunas numa BD), então devemos usá-las sempre na mesma ordem. Assim, torna-se mais fácil ver se alguma está a faltar, ou se foram misturadas ou confundidas. Para uma operação, se for chamada “Apagar” num dado lugar, não a chamar “Remover” noutro lugar – usar sempre o mesmo nome. Steve McConnell também tem alguns bons conselhos sobre o uso de opostos (precisamente em Code Complete). Por exemplo, begin/end são opostos, assim como são start/stop. Não misturar nomes de pares diferentes (p.ex., begin/stop) quando se trata de opostos.

Ao modificar um programa, podem ser introduzidas inconsistências. Programadores desleixados não verificam se o que acrescentam é consistente com o código existente ou não. Os bons programadores são incansáveis ​​no sentido de garantir que, mesmo os pequenos detalhes estão correctos. Eles sabem o quão importante é a consistência na luta global contra a complexidade.

5. Formação/Aprendizagem

Como programadores de software, estamos constantemente a aprender. Antes de adicionar um novo recurso, temos que entender o que ele é suposto fazer. Antes de adicionar código a um programa já existente, normalmente, temos que saber o que o código existente faz, a fim de ajustar a nova funcionalidade corretamente. Também temos que aprender sobre os sistemas circundantes, a fim de interagir com eles corretamente. Portanto, a capacidade de aprender rápido, faz de cada um de nós um programador muito mais eficaz.

Além disso, como o ritmo de desenvolvimento e evolução no campo da Engenharia de Software é tão alto, há um fluxo constante de novas linguagens, ferramentas, técnicas e frameworks para aprender. Podemos ver isso como bom ou como mau. Fred Brooks marca a aprendizagem como uma das alegrias do ofício. Aprender coisas novas é bom em si mesmo. Significa, também, que a vida como programador nunca é chata.

Conclusão

Todas as características e competências acima são genéricos - nenhuma delas é específica a qualquer linguagem, framework ou tecnologia. Quem as possuir, pode rapidamente aprender uma nova linguagem ou ferramenta, e escrever um bom software nesse ambiente. Além disso, porque elas são de natureza geral, não se tornam obsoletas num par de anos.

 

Tradução livre do artigo “What Makes a Good Programmer”, de Henrik Warne.

Sem comentários:

Enviar um comentário