image

Access unlimited bootcamps and 650+ courses

50
%OFF
Article image
Luiz Freitas
Luiz Freitas07/11/2025 21:56
Share

Além da Teoria: o Clean Code que se escreve com propósito

    Um olhar prático sobre código limpo em JavaScript, React e Node.js

    🚀 Introdução

    Se no artigo anterior compartilhei aprendizados sobre o porquê de escrever código limpo, agora quero falar sobre o como.

    Após o curso "Introdução a Clean Code" aqui da DIO, mergulhei mais fundo nesse tema com o conteúdo da Rocketseat, ministrado pelo Diego Fernandes, e percebi que Clean Code é muito mais do que um conjunto de boas práticas, é uma atitude diante do código e das pessoas que o leem.

    > 💬 Porque código limpo não é apenas sobre sintaxe: é sobre empatia, clareza e propósito.

    🧩 1. Clean Code é sobre contexto, não sobre perfeccionismo

    Uma das primeiras lições reforçadas pelo Diego é que Clean Code não tem nada a ver com Clean Architecture, DDD ou SOLID, e que a maioria dos projetos reais não segue arquiteturas complexas, mas ainda assim podem ter código limpo.

    Clean Code é sobre contexto: entender o propósito do código e o impacto das decisões de quem o escreve.

    Ele se apoia em três pilares essenciais:

    • Legibilidade: o código precisa contar sua própria história
    • Manutenibilidade: deve poder evoluir sem dores de cabeça
    • Previsibilidade: o comportamento precisa ser claro e confiável

    🧠 2. Nomes que contam histórias (JavaScript)

    No módulo de JavaScript, uma lição simples, mas poderosa:

    > "Nomes contam histórias."

    Escrever variáveis como data, obj ou res é o mesmo que criar capítulos sem título em um livro. Um bom nome revela o propósito, e não apenas o tipo do dado.

    // ❌ Código confuso
    function calc(p, d) {
    return p - (p * d / 100);
    }
    
    // ✅ Código claro
    function calcularDesconto(preco, percentualDesconto) {
    return preco - (preco * percentualDesconto / 100);
    }
    

    O código limpo não exige tradução mental. Ele conversa com o leitor.

    📚 3. Os 9 princípios práticos do Clean Code em JavaScript

    Durante o curso, realizei 9 desafios práticos que consolidaram princípios fundamentais:

    🔹 Desafio 1: Nomenclatura de variáveis

    Princípio: Evite diminutivos e nomes genéricos.

    // ❌ Código confuso
    const filtered = users.filter(u => u.name.startsWith('D'));
    ​
    // ✅ Código claro
    const usersStartingWithLetterD = users.filter(user => 
    user.name.startsWith('D')
    );
    

    Lição: Clareza > brevidade. Nomes longos e descritivos são melhores que abreviações crípticas.

    🔹 Desafio 2: Booleanos semânticos

    Princípio: Use prefixos que revelem o tipo boolean: is, has, can, should.

    // ❌ Confuso
    if (!ticket) throw new Error("Sem bilhete");
    ​
    // ✅ Claro
    const hasTicket = user?.ticket != null; // null ou undefined => false
    if (!hasTicket) throw new Error('Usuário não possui bilhete');
    

    Lição: Nomes booleanos devem responder perguntas diretas: "Is it active?" → isActive

    🔹 Desafio 3: Causa vs. Efeito

    Princípio: Nomeie pela causa, não pelo efeito.

    // ❌ Efeito
    const isLoadingUserInformation = true;
    ​
    // ✅ Causa
    const isUserInformationLoading = true;
    

    Lição: O nome deve refletir o que causa o estado, não o que acontece como consequência.

    🔹 Desafio 4: Código em inglês

    Princípio: Escreva 100% do código em inglês.

    // ❌ Mistura de idiomas
    const listaProdutos = [
    { title: "Macarrão", preco: "R$ 25,00" },
    { title: "Hamburguer", preco: "R$ 30,00" }
    ];
    ​
    // ✅ Código uniforme
    const productList = [
    { title: "Macarrão", price: "R$ 25.00" },
    { title: "Hamburguer", price: "R$ 30.00" }
    ];
    

    Lição: Código em inglês é universal, acessível para ferramentas e outros desenvolvedores.

    🔹 Desafio 5: Regras em condicionais

    Princípio: Extraia lógica condicional para variáveis descritivas.

    // ❌ Confuso
    if (studentGrade < 7 || studentAbsences > 100) {
    return { error: "Reprovado" };
    }
    ​
    // ✅ Claro
    const hasFailedGrade = studentGrade < necessaryGradeToBeApproved;
    const hasExcessiveAbsences = studentAbsences > numberOfAbsencesToFailSchool;
    ​
    if (hasFailedGrade || hasExcessiveAbsences) {
    return { error: "Estudante Reprovado" };
    }
    

    Lição: Condicionais legíveis = código autodocumentado.

    🔹 Desafio 6: Parâmetros e desestruturação

    Princípio: Use objetos para múltiplos parâmetros; evite ordem fixa.

    // ❌ Ordem rígida
    function updateUserRoute(body, params) {
    updateUserController(body.name, body.email, body.password, params.id);
    }
    ​
    function updateUserController(name, email, password, id) {
    userRepository.update({ name, email, password, id });
    }
    ​
    // ✅ Desestruturação flexível
    function updateUserRoute(body, params) {
    updateUserController({ 
      name: body.name, 
      email: body.email, 
      password: body.password, 
      id: params.id 
    });
    }
    ​
    function updateUserController({ name, email, password, id }) {
    userRepository.update({ name, email, password, id });
    }
    

    Lição: Desestruturação melhora legibilidade e facilita refatoração.

    🔹 Desafio 7: Números mágicos

    Princípio: Substitua números literais por constantes nomeadas.

    // ❌ Números mágicos
    function lookForUpdates() {
    // Código
    }
    ​
    setInterval(lookForUpdates, 60 * 30 * 1000);
    ​
    function calculateDiscount(priceInCents, discountAmountInPercentage) {
    // Código
    }
    ​
    // ✅ Constantes descritivas
    const INTERVAL_30_MINUTES = 60 * 30 * 1000;
    ​
    function lookForUpdates() {
    // Código
    }
    ​
    setInterval(lookForUpdates, INTERVAL_30_MINUTES);
    ​
    function calculateDiscount(priceInCents, discountAmountInPercentage) {
    // Código
    }
    

    Lição: Números têm significado. Dê-lhes nomes.

    🔹 Desafio 8: Comentários vs. Documentação

    Princípio: Código claro não precisa de comentários; use JSDoc para APIs públicas.

    // ❌ Comentários explicando código confuso
    async function registerUser(userInfo) {
    // Verifica se avatar é válido
    const isAvatarInvalid = userInfo.avatar;
    if (isAvatarInvalid) {
      return { error: 'avatar is required' }
    }
    
    // Verifica se nome é válido
    const isNameInvalid = userInfo.name;
    if (isNameInvalid) {
      return { error: 'name is required' }
    }
    
    // Verifica se email já está em uso
    const isEmailInUse = getUserByEmail(userInfo.email);
    if (isEmailInUse) {
      return { error: 'email already used' }
    }
    
    // Essa função foi copiada de um tutorial no YouTube
    // Link: https://github.com/rocketseat-education/example-repository/issues/1
    const convertedAvatar = convertImageToJPG(userInfo.avatar);
    
    const createdUser = await createUser({ 
      email: userInfo.email, 
      name: userInfo.name, 
      avatar: convertedAvatar 
    });
    
    return { createdUser }
    }
    ​
    // ✅ Código autodocumentado + JSDoc
    /**
     * Registers a new user in the system
     * @param {Object} userInfo - User data
     * @param {string} userInfo.email - User email
     * @param {string} userInfo.name - User name
     * @param {string} userInfo.avatar - User avatar URL
     * @returns {Promise<Object>} Created user or error
     */
    async function registerUser(userInfo) {
    const isAvatarInvalid = !userInfo.avatar;
    if (isAvatarInvalid) {
      return { error: 'avatar is required' }
    }
    
    const isNameInvalid = !userInfo.name;
    if (isNameInvalid) {
      return { error: 'name is required' }
    }
    
    const isEmailInUse = getUserByEmail(userInfo.email);
    if (isEmailInUse) {
      return { error: 'email already used' }
    }
    
    const convertedAvatar = convertImageToJPG(userInfo.avatar);
    
    const createdUser = await createUser({ 
      email: userInfo.email, 
      name: userInfo.name, 
      avatar: convertedAvatar 
    });
    
    return { createdUser }
    }
    

    Lição: Comentários explicam porquê. Código explica o quê.

    🔹 Desafio 9: Syntatic Sugars

    Princípio: Evite atalhos obscuros; prefira clareza.

    // ❌ Syntatic sugar obscuro
    function getFirstFiveRatings(ratings) {
    const ratingsBool = Boolean(ratings);
    
    if (ratingsBool) {
      const firstFiveRatings = getFirstFiveRatings + ratings;
      
      if (!firstFiveRatings) return { error: 'there must be at least 5 ratings' };
      
      let ratingsSum = 0;
      
      for (const rating of firstFiveRatings) {
        ratingsSum += Number(rating);
      }
      
      return { ratingsSum, created_at: Date.now() };
    }
    
    return { error: 'ratings is required' };
    }
    ​
    // ✅ Código explícito
    function sumFirstFiveRatings(ratings) {
    const ratingsBool = Boolean(ratings);
    
    if (!ratingsBool) {
      return { error: 'ratings is required' };
    }
    
    const firstFiveRatings = ratings.slice(0, 5);
    
    if (firstFiveRatings.length < 5) {
      return { error: 'there must be at least 5 ratings' };
    }
    
    let ratingsSum = 0;
    
    for (const rating of firstFiveRatings) {
      ratingsSum += Number(rating);
    }
    
    return { ratingsSum, created_at: Date.now() };
    }
    

    Lição: Código elegante não é código críptico. Escolha clareza sobre "esperteza".

    ⚛️ 4. React: separando o essencial do acessório

    Em aplicações React, o Clean Code se mostra na capacidade de separar o essencial do acessório. Nem todo componente precisa ser extraído; componentizar tudo não é sinônimo de organização.

    A lição é clara: isolar responsabilidades sem fragmentar o raciocínio.

    > 💡 "A pior parte de um código grande não é o HTML, é o JavaScript confuso dentro dele."

    A limpeza do React começa com uma pergunta: "O que esse componente precisa fazer de fato?"

    🎨 Pattern de Composição vs. Configuração

    Ao invés de criar um componente inflado:

    // ❌ Pattern de Configuração (inflexível)
    <Input 
    label="Nome completo"
    error="Digite seu nome corretamente"
    icon={<UserIcon />}
    iconPosition="left"
    labelProps={{ htmlFor: "name", className: "label-custom" }}
    />
    

    Use composição para flexibilidade total:

    // ✅ Pattern de Composição (flexível)
    <Input.Root>
    <Input.Label htmlFor="name" className="label-custom">
      Nome completo
    </Input.Label>
    <Input.Icon>
      <UserIcon />
    </Input.Icon>
    <Input.Field id="name" />
    <Input.ErrorMessage>
      Digite seu nome corretamente
    </Input.ErrorMessage>
    </Input.Root>
    

    Vantagens do pattern de composição:

    • Controle total sobre posicionamento de elementos
    • Acesso direto a propriedades nativas do HTML
    • Sem necessidade de criar props intermediárias
    • Extensibilidade natural

    🧹 Condicionais fora do render

    Mantenha a lógica fora do JSX:

    // ❌ Lógica no render
    return (
    <div>
      {todos.length === 0 && <p>Nenhum todo cadastrado</p>}
    </div>
    );
    ​
    // ✅ Lógica separada
    const isTodoListEmpty = todos.length === 0;
    ​
    return (
    <div>
      {isTodoListEmpty && <p>Nenhum todo cadastrado</p>}
    </div>
    );
    

    🖥️ 5. Backend: simplicidade é maturidade

    No backend, a maturidade está em evitar complexidade desnecessária. Como o Diego enfatiza: Clean Code ≠ Clean Architecture.

    Você pode escrever código limpo mesmo em aplicações simples, o segredo está em clareza e testabilidade.

    > "Se é fácil de testar, provavelmente é fácil de entender."

    A simplicidade é um traço de desenvolvedores maduros: usar o suficiente para resolver o problema, não o máximo que a linguagem permite.

    🎯 Testabilidade como métrica

    Ter testes automatizados é um dos principais sinais de que seu código é limpo. Se você consegue testar facilmente, seu código provavelmente está bem estruturado.

    💭 6. O código que se escreve com propósito

    Essa jornada pela Rocketseat reforçou algo que já havia aprendido no curso da DIO: Escrever código limpo é um ato de amor.

    Amor pelo futuro do projeto, pelos colegas de equipe e pelo seu "eu" de amanhã.

    Se no primeiro artigo eu falava sobre conceitos, agora falo sobre consciência.

    > "Bons programadores escrevem código que seres humanos podem entender."
    > — Martin Fowler

    🎓 Conclusão

    Clean Code não é uma lista de regras a seguir cegamente. É uma mentalidade de respeito:

    • Respeito por quem vai ler seu código
    • Respeito pelo projeto que vai evoluir
    • Respeito pelo seu tempo futuro

    Os 9 desafios do curso me ensinaram que transformar "código que funciona" em "código que faz sentido" não é perfumaria, é profissionalismo.

    🔗 Referências

    Share
    Recommended for you
    Binance - Blockchain Developer with Solidity 2025
    Neo4J - Análise de Dados com Grafos
    Cognizant - Mobile Developer
    Comments (0)