Todo programador passa por algumas etapas na curva de aprendizagem.

Aqui destaco as principais:

  1. Manutenção e mudanças em código alheio
  2. Desenvolvimento de projetos em equipe
  3. Responsabilidade sobre seus próprios projetos

Quando se inicia a carreira de programador (e eu tenho calos nos pés), você recebe uma mesa, um computador, projetos e prazos apertados.

Você está na primeira etapa de sua carreira e precisa trabalhar com inúmeros programas de outros profissionais dos quais você não participou dos projetos e provavelmente não faz ideia de quem sejam as mãos que codificaram o sistema antes das suas.

Geralmente algum ex-funcionário que recebeu uma proposta melhor do mercado e se foi, e com o sistema no ar, rodando, com inúmeros usuários conectados simultaneamente, o problema chega até você em tom de desespero.

Você precisa resolver o problema de algo cuja estrutura desconhece.

Eu já estive na sua pele, aceitei o desafio de trabalhar para o maior banco de dados de pessoa física da América Latina (não vou citar o nome da empresa por razões éticas) e abracei uma causa que nenhum outro programador queria. Foi assim que passei os 4 primeiros anos: resolvendo problemas nos projetos de desconhecidos sob pressão.

Nesta empresa fiquei 7 anos. Os próximos 3 fui convidado a integrar uma equipe de projetos que ainda não existiam (a 2ª etapa) e por fim na reta final liderei alguns projetos (3ª etapa).

Se você está na 1ª etapa, então este texto é para você, que está suando frio e que o relógio, o calendário e as linhas desconhecidas são seus inimigos.

Os demais, acredito que não encontrarão qualquer novidade.

Programar significa transformar uma ideia em código e para isto você precisa conhecer a linguagem de programação e ter uma boa ideia do fluxo que o programa deve seguir para produzir o resultado desejado.

Acontece que, isto não é o suficiente para sair resolvendo problemas em códigos alheios, se você partir apenas do conhecimento da linguagem, provavelmente encontrará barrancos inteiros de dificuldades.

O que você precisa entender é “análise“.

Análise significa decompor um objeto de estudo em suas partes para entendê-las.

É isto que nós vamos fazer, antes de programar vamos analisar.

A primeira pergunta que você deve fazer é:

  • O que este sistema faz? Qual sua finalidade?

A resposta desta pergunta te dará uma visão macro dos objetivos da tarefa. Sabendo o que o sistema faz, saberá de antemão os recursos que ele usa, como banco de dados, acessos a redes, tipos de gráficos, interações com os usuários, consultas a outros sistemas, autenticações e etc.

A segunda pergunta é:

  • Em qual parte do sistema eu vou trabalhar?

Sistemas grandes são divididos em partes menores, tenha em mente qual é a parte que você trabalhará e esqueça o resto. Se tentar aprender o sistema inteiro logo de cara, você não conseguirá cumprir os prazos determinados.

A terceira pergunta:

  • O que a parte que eu vou trabalhar faz?

Parece redundante mas não é. É uma questão importantíssima, pois assim você isola mentalmente quais são suas responsabilidades e foca no seu objetivo apenas. Liberar espaço em sua própria cabeça para pensar apenas no que precisa é uma necessidade inalienável para quem trabalha pensando. O trabalho do programador é boa parte do tempo com lógica e isto é o cerne do pensamento. Valorize sua energia focando em sua necessidade e deixe o resto para depois.

Agora que você já sabe o que o sistema como um todo faz, em qual parte você trabalhará e quais as atribuições de sua atividade, é hora de mapear quais recursos esta parte do sistema usa.

Programadores iniciantes costumam ter a ingenuidade de dar uma olhada no banco de dados, bater os olhos nas páginas de código e nas telas do sistema, e achar que já entenderam tudo: é neste ponto que seu pesadelo começa.

Quando você acha que sabe de tudo e se mete a besta de trabalhar com o código alheio, encontra aberrações profissionais como péssima organização de arquivos e pastas, nomes de variáveis incompreensíveis, tabelas irracionais no banco de dados, acessos a redes com tokens, fluxos de código redundantes e desnecessários, indentação desorganizada, chamadas a outros programas perdidas no meio do código, rotinas sem comentário, entre outras.

Péssima organização de arquivos e pastas

Antes de começar, quando tiver respondido as 3 perguntas do início, você deve descobrir qual o fluxo de código que o programa percorre: onde começa, onde termina e por onde passa. Com isso você saberá quais os arquivos de código fonte são chamados e em quais momentos.

Já trabalhei com sistemas onde encontrei pastas chamadas “codigo“, “util“, “arquivos“, “pasta1“, “subpasta“, “outros“, entre outros. Por dentro eu costumava rir, embora estivesse sério por fora. Me imaginava indagando o programador:

– Os arquivos que estão fora da pasta “codigo”, não são códigos?
– Os arquivos fora da pasta “util”, não são úteis?
– Você chamou de “pasta1” para facilitar meu entendimento?
– O nome “subpasta”, foi escolhido para ter certeza que esta pasta está dentro de outras e não jogada no corredor ou perto da máquina de café?
– Os arquivos da pasta “outros”, servem para eu ter certeza que não são os mesmos da pasta anterior?

Ironias à parte: organizar o entendimento é responsabilidade sua, é a qualidade dos dados.

Para resolver inúmeros conflitos com a estrutura do sistema, o mercado já dispõe de soluções como o modelo MVC, que se propõe a separar a arte do designer do ofício do programador e funciona muito bem, mas nem sempre você encontrará estas facilidades.

Você precisa realmente separar os arquivos e entender as estrutura de diretórios, para realmente discernir o que afetará seu trabalho.

Nomes de variáveis incompreensíveis

Separados os arquivos, você deve descobrir quais as variáveis e constantes usadas. Isto é geralmente a maior dificuldade de compreensão dos programadores.

Num programa de loja virtual, escrito em PHP por mim, você encontrará variáveis como:

  • $peso, $altura, $largura, $comprimento, $moeda, $preco, $desconto

Num programa escrito por um inexperiente você encontrará:

  • $x, $y, $x1, $y1, $za, $ini, $i_atx

Perceba que no primeiro caso você sabe exatamente que tipo de dados aquela variável está carregando, no segundo caso você não faz ideia do que o programador estava tratando.

Antes de mergulhar neste inferno, mapeie, anote se necessário o que cada variável faz.

Tabelas irracionais no banco de dados

O passo seguinte são os recursos de banco de dados. Eu já tive que lidar com tabelas com 150 campos, dos quais mais de 75% eram absolutamente desnecessários, o banco de dados era no mínimo irracional.

Suponha um cadastro de clientes no qual os dados cadastrais podem ser múltiplos, como por exemplo os endereços e os telefones.

Um programador experiente proporá uma estrutura dividida em 3 tabelas, uma para os dados essenciais, outra para os endereços e outra para os telefones, e identificará os registros por um campo comum, geralmente o “id” do usuário.

Mas você poderá encontrar tabelas como as que eu encontrei (dentro de empresas grandes!) com 10 campos para os dados essenciais, mais “endereco“, “numero“, “bairro“, “cidade“, “estado” e “cep“, repetidos 5 vezes! E em seguida, como golpe mortal de misericórdia o desgraçado acrescenta 4 repetições de “ddd“, “telefone” e “tipo“.

Sabendo que banco de dados é um campo minado, é melhor você saber onde está pisando antes de começar: conheça as tabelas que você trabalhará antes de colocar a mão na massa.

Acessos a redes com tokens

Em sistemas antigos é muito comum encontrar (principalmente em mainframes) acessos controlados por tokens. O usuário se conecta, se autentica e recebe um token que fica gravado em algum lugar e que com ele você pode utilizar o sistema por um determinado tempo (geralmente 30 minutos) e ao final o token perde a validade e o usuário precisa se autenticar novamente.

Este tipo de sistema é um inferno pois, ou você renova o token a cada ação do usuário, ou corre o risco de que ele “caia” do sistema no meio de alguma operação e quando isso acontece, o seu telefone vai tocar com alguém puto da vida, sem entender o que houve.

A explicação é simples: o sistema foi projetado para poucos usuários e com o tempo (muito tempo mesmo) cresceu de forma desregrada.

Você pode perder horas de análise de código (horas e até dias) tentando descobrir porque o sistema está desconectando aleatoriamente os usuários, alguns realizam suas atividades, mas outros caem sem explicação: é o maldito token.

Em sistemas modernos há soluções que servem-se de token também, como o OAuth, muito usado pelos desenvolvedores em redes sociais de diversas naturezas, inclusive e-commerces grandes, market places de respeito, como Mercado Livre.

Estude os acessos e sistemas de autenticação antes de começar.

Fluxos de código redundantes e desnecessários

Quando se trata da lógica, tudo parece que vai fluir perfeitamente: se acontecer isso então aquilo (if), faça isto enquanto aquilo (while), faça tal até tal ponto (do), repita tal instrução tantas vezes (for), escolha entre as opções tais e quais (switch), enfim, tudo parece óbvio partindo do ponto em que você conhece a linguagem.

É outro calcanhar de Aquiles de todo programador.

Geralmente este é o motivo pelo qual você será chamado para dar manutenção: uma falha de lógica.

Um programador experiente, no ato de projeto pensará em como aumentar a velocidade, eliminando cálculos e rotinas desnecessárias, e preparando os dados essenciais antes do programa começar a processar.

Exemplo: suponha um projeto comercial onde se elabora um pedido do cliente.

Sabemos que no ponto do pedido, o sistema deverá saber os dados do cliente, a especificação dos produtos, os cálculos de frete e comissão de vendas, no mínimo.

O código gerado pelo programador inteligente será organizado, numa sequência parecida com esta:

  • Separar dados do cliente
  • Separar coleção de dados dos produtos
  • Preparar critérios de frete
  • Preparar critérios de comissão

A seguir destes passos é que o processamento realmente começará, efetuando os cálculos e registrando os resultados em banco de dados, para só no final apresentar na tela o pedido ao cliente.

Acontece que este acima é o cenário ideal, é o céu: está tudo organizado e perfeitamente racional.

Caso você seja chamado (e será, pode se preparar), encontrará dados coletados esparsamente pelo código, consultas desnecessárias aos diversos dados que o processamento requer, gravações na base em momento errado, condições aninhadas sem necessidade, enfim, um inferno de lógica.

Entenda o que o código faz antes de começar a alterá-lo, ou seu tempo será consumido por testes infinitos.

Indentação desorganizada

Este é o caso mais odioso.

Um programa é um fluxo de instruções que processa informações para alcançar um objetivo e o computador o entende perfeitamente.

Acontece que você não é um computador parceiro e na medida que o programa cresce, se torna mais complexo e as vezes precisa inclusive ser separado em programas menores (a técnica de modularização ensinada nos primórdios da computação por Peter Norton) e programadores preguiçosos focados em “fazer e fazer logo!” ou “entregar de uma vez!“, se esquecem de que no máximo em 3 dias ele estará em outro sistema trabalhando e que ele mesmo se esquecerá (completamente) do código anterior. Sem contar que, além dele mesmo, do terrível autor da porcaria sem qualidade, outros seres humanos darão manutenção no programa.

Há manuais de “best practices” para indentação de cada linguagem em sites diversos que podem ser encontrados facilmente no Google.

Você odiará de todo coração quando descobrir que o tamanho da página de código é de mais de 800 linhas e que a organização é a seguinte:

se condição 1
faça 1
se condição 2
faça 2
se condição 3
faça 3
faça 4
faça 5
se condição 4
faça 8
fim da condição 4
faça 7
fim da condição 3
faça 6
fim da condição 2
fim da condição 1

É simplesmente inapreensível, é porco.

Mas você se alegrará se encontrar o mesmo programa escrito da seguinte forma:

se condição 1
  faça 1
  se condição 2
    faça 2
    se condição 3
      faça 3
      faça 4
      faça 5
      se condição 4
        faça 8
      fim da condição 4
      faça 7
    fim da condição 3
    faça 6
  fim da condição 2
fim da condição 1

Antes de começar a mexer no código: indente, o código não é seu, mas o tempo para entendê-lo é.

Chamadas a outros programas perdidas no meio do código

Este é um pesadelo menor, mas comum em softwares integrados no mesmo servidor.

Esta espécie de erva daninha é encontrada principalmente nas planícies de linguagens interpretadas e zonas temperadas com programadores desesperados. O sujeito não quer ter que digitar parte do código novamente, o que é louvável, mas ao invés de criar uma biblioteca de funções ele separa o código solto, em arquivos insuspeitos, sem qualquer explicação ou aviso prévio.

De repente, do mais absoluto nada você se depara com uma variável, constante ou função que não está presente em parte alguma do código e se pergunta: “de onde o miserável tirou isto?!

Acreditando ser um mero erro de programação, você depura o código apresentando o valor do dado e para sua pior surpresa o bendito dado está lá preenchido de alguma forma e necessário para o programa.

Num dos tópicos anteriores eu abordei o nome de variáveis e constantes incompreensíveis, mas isto também pode acontecer com funções e geralmente o caso é este. No meio da página de código você encontra uma bela chamada para “retornaX()“, “processaInfo()“, “ab1()“, entre outros casos que soam até como falta de respeito e consideração com os demais profissionais que atuam no mesmo trabalho, a desconhecida função está lá perdida em algum arquivo esquecido em pasta desconhecida e até parece pegadinha.

Se você tiver seguido os passos recomendados até aqui, este tipo de surpresa será facilmente solucionada, você saberá em quais arquivos procurar e já terá noção do que faz cada um. Do contrário, encontrará solicitações de arquivos de código fonte espalhadas no meio do código sem nenhum pudor.

Este tipo de problema só pode ser previamente solucionado seguindo as dicas que dei anteriormente. Não há solução senão a análise.

Rotinas sem comentário

Comentários são a linha que separam os homens e os meninos.

Um código comentado ajudará todos os programadores a orientarem-se pelo fluxo dos programas.

Um programa bem comentado é o sinal de um bom profissional: se o seu funcionário comenta o código, dê-lhe um prêmio, do contrário demita-o sumariamente por filha-da-putice e mencione o motivo na demissão.

O processo de análise de um sistema geralmente é trabalhoso e é o que precede os trabalhos propriamente ditos.

Um programador que tenha entendido o sistema será imensamente mais produtivo que um outro que esteja fazendo sucessivas tentativas de depuração eternas, mais perdido que cego em tiroteio.

Durante o processo de análise, enquanto entende o sistema em suas partes comente o código, isto servirá para você e para os demais no futuro.

Conclusão

A linha de raciocínio segue abaixo organizada:

  • Mapear quais os arquivos que o programa precisa para sua atividade
  • Mapear as variáveis e constantes, tomando consciência dos nomes, dos valores que carrega e quais operações são feitas sobre elas
  • Conhecer o banco de dados, pelo menos as tabelas que você trabalhará
  • Conhecer os sistemas de autenticação que influenciem no seu trabalho
  • Estudar os fluxos de código dos processos que você lidará
  • Indentar as páginas de código que você trabalhará
  • Comentar o código, mesmo que alheio

That’s all!

Se alguém precisar de ajuda, é só ligar o bat-sinal e me chamar, geralmente estou na área.

Anúncios