Escrevendo código como um Sênior

08 de março de 2025
Escrevendo código como um Sênior

Olhando para trás e analisando o que aprendi sobre liderança técnica em desenvolvimento de software, um dos pontos que mais se destacou e que foi indicado por muitos dos meus menores é capacidade de produzir código de alta qualidade. Essa habilidade deveria se sobrepor ao mero orgulho pessoal, impactando diretamente na eficiência, na colaboração e na confiança dentro de equipes multidisciplinares.

Imagine uma pessoa desenvolvedora enquadrada no nível de júnior enfrentando dificuldades para implementar uma funcionalidade complexa. Ao invés de longas explicações, essa pessoa recorre a um módulo similar, elegantemente escrito e bem documentado por uma pessoa que está no nível sênior. A clareza do código facilita o entendimento, a adaptação e a integração da nova funcionalidade, economizando tempo e recursos.

Código limpo e conciso serve como um guia prático, acelerando o aprendizado e reduzindo a necessidade de retrabalho. Isso evita o dispendioso cenário de reescrever código funcional apenas por sua complexidade ou falta de clareza.

Dica para o nível sênior: Priorize a legibilidade e a documentação do código. Utilize convenções de nomenclatura claras, escreva comentários concisos e organize o código em módulos coesos. Lembre-se, código bem documentado, com descrições claras e desacoplado para reutilização, facilita a compreensão por outros programadores, construindo confiança e respeito pelo seu trabalho.

Concluindo o esboço, Rabiscando o miolo, Lapidando o valor

Pessoas desenvolvedoras em nível sênior se distinguem pela capacidade de entregar soluções completas, não apenas funcionais. Em um ambiente de desenvolvimento ágil, onde a pressão por entregas rápidas é constante, essa habilidade se torna ainda mais crucial para a sustentabilidade e o sucesso do projeto.

Ao invés de simplesmente implementar uma nova API e considerá-la "pronta", aqueles em nível sênior se certificam de que todos os casos de uso foram testados, a documentação está atualizada e o código está otimizado para performance e segurança. Da mesma forma, em tarefas de correção de bugs, essa pessoa desenvolvedora se preocupa em entender a causa raiz do problema e não somente contornar a situação momentânea.

Muitas destas pessoas, sob diversas pressões do dia a dia, tendem a marcar tarefas como concluídas quando estão "quase prontas", acumulando dívida técnica. É um esforço do nível sênior reconhecer que a transparência sobre o status real da tarefa, mesmo que isso impacte o cronograma, é fundamental para evitar problemas futuros.

Para maior clareza, aqui está um exemplo simplificado de código:

package main

import (
    "encoding/json"
    "errors"
    "fmt"
    "io"
    "log"
    "net/http"
)

// Junior Approach - Incomplete Implementation
func fetchUserDataJunior(userID string) (map[string]interface{}, error) {
    resp, err := http.Get(fmt.Sprintf("/api/users/%s", userID))
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        return nil, err
    }

    var data map[string]interface{}
    err = json.Unmarshal(body, &data)
    if err != nil {
        return nil, err
    }

    return data, nil
}

// Senior Approach - Complete Implementation
func fetchUserDataSenior(userID string) (map[string]interface{}, error) {
    if userID == "" {
        return nil, errors.New("User ID is required")
    }

    resp, err := http.Get(fmt.Sprintf("/api/users/%s", userID))
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()

    if resp.StatusCode != http.StatusOK {
        return nil, fmt.Errorf("HTTP error! status: %d", resp.StatusCode)
    }

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        return nil, err
    }

    var data map[string]interface{}
    err = json.Unmarshal(body, &data)
    if err != nil {
        return nil, err
    }

    _, existsID := data["id"]
    _, existsName := data["name"]

    if !existsID || !existsName {
        return nil, fmt.Errorf("invalid user data received: %s", data)
    }

    return data, nil
}

Dicas e Pontos de Atenção que o tempo me ensinou

1. Conheça e use padrões, mas não fique preso a eles.

Padrões de codificação e arquitetura de software são cruciais para a manutenção e escalabilidade de um projeto. No entanto, é importante lembrar que esses padrões devem ser aplicados com flexibilidade e bom senso, sempre visando a entrega de valor como objetivo principal.

Seguir cegamente qualquer padrão ou metodologia, sem entender suas limitações e aplicações, pode levar a um desenvolvimento ineficiente e até mesmo prejudicial. A experiência e o contexto do projeto devem sempre ser levados em consideração na hora de escolher e aplicar qualquer padrão.

2. Refatorar ou Migrar?

Comece simples, expanda e desacople na medida que for se tornando necessário. Em determinados momentos não existem muitos caminhos a não ser migrar para outra arquitetura, refatorar o que já existe ou quem sabe quebrar tudo em serviços menores. Dica de Ouro: muitas vezes as pessoas escolhem caminhos que mais lhe convém e não que mais geram valor, então analise o que melhor se encaixa e traga retorno!

Seniores adotam uma abordagem sofisticada para refatoração, integrando-a ao fluxo de trabalho regular em vez de isolá-la em tarefas separadas. Essa estratégia sutil, mas eficaz, garante a evolução contínua da base de código sem gerar atrito com a gestão.

Como benefício dessas práticas podemos citar a prevenção da dívida técnica, reduzindo o acúmulo de pontos de melhoria, garantindo que o código permaneça limpo; facilita a implementação de novas funcionalidades; promove uma cultura de qualidade contínua e consequentemente incentiva a colaboração e o aprendizado entre os membros da equipe.