SwiftHTML & CSSSolidityDesenvolvimento de JogosSolana/Rust
30.11.2024

Lição 180: Legibilidade e Manutenibilidade do Código

No mundo do desenvolvimento de software, especialmente no domínio da blockchain, a legibilidade e a manutenibilidade do código são de suma importância. Escrever contratos inteligentes em Solidity requer não apenas conhecimento técnico, mas também uma compreensão de como outros (e seu futuro eu) irão ler e manter seu código. Esta lição foca nas melhores práticas que podem ajudar a melhorar a legibilidade e a manutenibilidade do seu código em Solidity.

1. Use Convenções de Nomenclatura Descritivas

Uma das maneiras mais simples de aumentar a legibilidade do código é através de nomenclatura expressiva. Os nomes devem transmitir claramente o propósito de uma variável, função ou contrato. Evite abreviações ambíguas.

Exemplo:

contract Token {
    mapping(address => uint256) public saldos;

    function transferir(address destinatario, uint256 quantia) public returns (bool) {
        require(saldos[msg.sender] >= quantia, "Saldo insuficiente");
        saldos[msg.sender] -= quantia;
        saldos[destinatario] += quantia;
        return true;
    }
}

Neste exemplo, é claro o que saldos, transferir, destinatario, e quantia se referem.

2. Comentários e Documentação

Embora o código deva ser o mais autoexplicativo possível, comentários ajudam a fornecer contexto. Use comentários para explicar lógicas complexas ou o raciocínio por trás de certas decisões. O Solidity suporta comentários NatSpec para documentar funções.

Exemplo:

/// @title Um contrato simples de token
/// @autor Seu Nome
/// @notice Este contrato permite que usuários transfiram tokens
contract Token {

    mapping(address => uint256) public saldos;

    /// @notice Transfere tokens da conta do chamador para outra conta
    /// @param destinatario O endereço para o qual os tokens serão enviados
    /// @param quantia A quantidade de tokens a enviar
    /// @return sucesso Um valor booleano indicando se a operação foi bem-sucedida
    function transferir(address destinatario, uint256 quantia) public returns (bool sucesso) {
        require(saldos[msg.sender] >= quantia, "Saldo insuficiente");
        saldos[msg.sender] -= quantia;
        saldos[destinatario] += quantia;
        return true;
    }
}

3. Divida Funções Complexas

Se uma função está fazendo muitas coisas, considere dividi-la em partes menores e mais gerenciáveis. Isso não só aumenta a legibilidade, mas também facilita os testes unitários.

Exemplo:

function processarTransacao(address destinatario, uint256 quantia) public returns (bool) {
    validarTransferencia(quantia);
    executarTransferencia(destinatario, quantia);
    return true;
}

function validarTransferencia(uint256 quantia) internal view {
    require(saldos[msg.sender] >= quantia, "Saldo insuficiente");
}

function executarTransferencia(address destinatario, uint256 quantia) internal {
    saldos[msg.sender] -= quantia;
    saldos[destinatario] += quantia;
}

4. Formatação Consistente

A formatação consistente melhora a estrutura visual do seu código. Use um estilo de indentação, espaçamento e comprimento de linha consistentes. Considere usar ferramentas como Prettier ou Solhint para manter seu código padronizado.

Exemplo com Formatação Consistente:

contract Token {
    mapping(address => uint256) public saldos;

    function transferir(address destinatario, uint256 quantia) public returns (bool) {
        require(saldos[msg.sender] >= quantia, "Saldo insuficiente");

        saldos[msg.sender] -= quantia;
        saldos[destinatario] += quantia;

        return true;
    }
}

5. Use Eventos para Mudanças de Estado

Usar eventos ajuda a registrar mudanças e torna mais fácil acompanhar o que está acontecendo em seus contratos. Isso é crucial para desenvolvedores front-end e para qualquer um que mantenha seu código depois.

Exemplo:

contract Token {
    mapping(address => uint256) public saldos;
    event Transferencia(address indexed de, address indexed para, uint256 quantia);

    function transferir(address destinatario, uint256 quantia) public returns (bool) {
        require(saldos[msg.sender] >= quantia, "Saldo insuficiente");

        saldos[msg.sender] -= quantia;
        saldos[destinatario] += quantia;

        emit Transferencia(msg.sender, destinatario, quantia);

        return true;
    }
}

6. Escreva Testes Unitários

Embora isso possa parecer menos sobre legibilidade e mais sobre robustez, escrever testes unitários para seus contratos inteligentes contribui para a manutenibilidade. Um contrato bem testado é mais fácil de entender e modificar.

Exemplo de um Teste Unitário Simples:

const Token = artifacts.require("Token");

contract("Token", (accounts) => {
    let instanciaToken;

    beforeEach(async () => {
        instanciaToken = await Token.deployed();
    });

    it("deve transferir tokens corretamente", async () => {
        const saldoInicial = await instanciaToken.saldos(accounts[0]);
        const quantiaTransferir = 10;

        await instanciaToken.transferir(accounts[1], quantiaTransferir, { from: accounts[0] });

        const novoSaldo = await instanciaToken.saldos(accounts[0]);
        assert.equal(novoSaldo.toNumber(), saldoInicial.toNumber() - quantiaTransferir, "A quantia não foi deduzida corretamente");
    });
});

Conclusão

Escrever código Solidity legível e manutenível é essencial, não apenas para projetos pessoais, mas especialmente em ambientes colaborativos e cenários de produção. Ao adotar convenções de nomenclatura claras, comentários eficazes, dividir funções complexas, manter formatação consistente, utilizar eventos e escrever testes unitários, você pode melhorar significativamente a qualidade de seus contratos inteligentes. Código de qualidade não é apenas sobre funcionalidade; é sobre quão facilmente pode ser entendido e continuado pelos outros – e por você no futuro.

Video

Did you like this article? Rate it from 1 to 5:

Thank you for voting!