A maioria dos exemplos são retirados de Robert J. Martin's Código limpo. É um clássico da programação e sugiro que você leia todo o texto quando tiver tempo.

Como nomear variáveis ​​(e outras coisas)

"Existem apenas duas coisas difíceis na Ciência da Computação: invalidação de cache e nomes de coisas." - Phil Karlton

Há uma razão pela qual não usamos endereços de memória e, em vez disso, temos nomes: os nomes são muito mais fáceis de lembrar. E, mais importante, eles podem fornecer mais informações sobre a variável, para que outra pessoa possa entender seu significado.

Pode levar algum tempo para encontrar um bom nome, mas você e sua equipe economizarão ainda mais tempo no futuro. E tenho certeza de que a maioria dos leitores já enfrentou a situação em que você visita seu código apenas alguns meses depois e tem dificuldade em entender o que fazia antes.

Como criar nomes significativos

Não use comentários para explicar porque uma variável é usada. Se um nome requer um comentário, você deve renomear essa variável em vez de escrever um comentário.

"Um nome deve dizer por que existe, o que faz e como é usado. Se um nome requer um comentário, então o nome não revela sua intenção." - Código limpo

Mau:

var d; // elapsed time in days

Já vi esse tipo de código tantas vezes. É um equívoco comum que você deve esconder sua bagunça com comentários. Não use letras como x, y, a ou b como nomes de variáveis, a menos que haja um bom motivo (variáveis ​​de loop são uma exceção a isso).

Boa:

var elapsedTimeInDays;var daysSinceCreation;var daysSinceModification;

Esses nomes são muito melhores. Eles dizem o que está sendo medido e a unidade dessa medida.

Evite desinformação

Tenha cuidado com palavras que significam algo específico. Não se refira a um agrupamento de contas como accountList a menos que seu tipo seja realmente uma lista. A palavra tem um significado específico e pode levar a conclusões falsas.

Mesmo se o tipo for uma lista, contas é um nome mais simples e melhor.

Mau:

var accountList = [];

Boa:

var accounts = []

Evite palavras barulhentas

Palavras de ruído são aquelas que não oferecem nenhuma informação adicional sobre a variável. Eles são redundantes e devem ser removidos.

Algumas palavras barulhentas populares são:

  • O (prefixo)
  • Informações
  • Dados
  • Variável
  • Objeto
  • Gerente

Se sua classe for denominada UserInfo, você pode simplesmente remover as informações e torná-la Usuário. Usar BookData em vez de Book como nome de classe é apenas um acéfalo, já que uma classe armazena dados de qualquer maneira.

Você também pode ler a postagem do blog de Jeff Atwood sobre a nomenclatura de SomethingManager aqui.

Use nomes pronunciáveis

Se você não consegue pronunciar um nome, não pode discuti-lo sem parecer bobo.

Mau:

const yyyymmdstr = moment().format("YYYY/MM/DD");

Boa:

const currentDate = moment().format("YYYY/MM/DD");

Use nomes pesquisáveis

Evite usar números mágicos em seu código. Opte por constantes pesquisáveis ​​e nomeadas. Não use nomes de uma única letra para constantes, pois elas podem aparecer em muitos lugares e, portanto, não são facilmente pesquisáveis.

Mau:

if (student.classes.length < 7) {   // Do something}

Boa:

if (student.classes.length < MAX_CLASSES_PER_STUDENT) {    // Do something}

Isso é muito melhor porque MAX_CLASSES_PER_STUDENT pode ser usado em muitos lugares no código. Se precisarmos alterá-lo para 6 no futuro, podemos apenas alterar a constante.

O mau exemplo cria pontos de interrogação na mente do leitor, como qual é a importância do 7?

Você também deve usar as convenções constantes de nomenclatura e declaração de seu idioma, como final estático privado em Java ou const em JavaScript.

Ser consistente

Segue o uma palavra para cada conceito regra. Não use buscar, recuperar, e obter para a mesma operação em classes diferentes. Escolha um deles e use-o em todo o projeto para que as pessoas que mantêm a base de código ou os clientes de sua API possam encontrar facilmente os métodos que procuram.

Como escrever funções

Mantenha-os pequenos

As funções devem ser pequenas, muito pequenas. Eles raramente devem ter 20 linhas de comprimento. Quanto mais tempo dura uma função, é mais provável que ela faça várias coisas e tenha efeitos colaterais.

Certifique-se de que eles fazem apenas uma coisa

As funções devem fazer uma coisa. Eles devem fazer isso bem. Eles devem fazer isso apenas. – Código limpo

Suas funções devem fazer apenas uma coisa. Se você seguir esta regra, é garantido que eles serão pequenos. A única coisa que essa função faz deve ser declarada em seu nome.

Às vezes é difícil olhar para a função e ver se ela está fazendo várias coisas ou não. Uma boa maneira de verificar é tentar extrair outra função com um nome diferente. Se você puder encontrá-lo, significa que deve ser uma função diferente.

Este é provavelmente o conceito mais importante neste artigo e levará algum tempo para se acostumar. Mas assim que você pegar o jeito, seu código parecerá muito mais maduro e será mais facilmente refatorável, compreensível e testável com certeza.

Encapsular condicionais em funções

Refatorar a condição e colocá-la em uma função nomeada é uma boa maneira de tornar suas condicionais mais legíveis.

Aqui está um trecho de código de um projeto de escola minha. Este código é responsável por inserir um chip no tabuleiro do jogo Connect4.

o isValidInsertion O método cuida de verificar a validade do número da coluna e nos permite o foco na lógica para inserir o chip.

public void insertChipAt(int column) throws Exception {        if (isValidInsertion(column)) {            insertChip(column);            boardConfiguration += column;            currentPlayer = currentPlayer == Chip.RED ? Chip.YELLOW : Chip.RED;        } else {            if (!columnExistsAt(column))                throw new IllegalArgumentException();            else if (isColumnFull(column - 1) || getWinner() != Chip.NONE)                throw new RuntimeException();        }    }

Aqui está o código para isValidInsertion, se você estiver interessado.

    private boolean isValidInsertion(int column) {        boolean columnIsAvailable = column <= NUM_COLUMNS && column >= 1 && numberOfItemsInColumn[column - 1] < NUM_ROWS;        boolean gameIsOver = getWinner() != Chip.NONE;        return columnIsAvailable && !gameIsOver;    }

Sem o método, se a condição seria assim:

if (column <= NUM_COLUMNS && column >= 1 && numberOfItemsInColumn[column - 1] < NUM_ROWS  && getWinner() != Chip.NONE)

Nojento, certo? Concordo.

Menos Argumentos

As funções devem ter dois ou menos argumentos, quanto menos, melhor. Evite três ou mais argumentos sempre que possível.

Os argumentos dificultam a leitura e o entendimento da função. Eles são ainda mais difíceis do ponto de vista do teste, uma vez que criam a necessidade de escrever casos de teste para cada combinação de argumentos.

Não use argumentos de bandeira

Um argumento sinalizador é um argumento booleano que é passado para uma função. Duas ações diferentes são executadas dependendo do valor deste argumento.

Por exemplo, digamos que haja uma função responsável pela reserva de ingressos para um show e dois tipos de usuários: Premium e Regular. Você pode ter um código como este:

    public Booking book (Customer aCustomer, boolean isPremium) {      if(isPremium)        // logic for premium book      else       // logic for regular booking    }

Os argumentos da bandeira contradizem naturalmente o princípio da responsabilidade única. Ao vê-los, você deve considerar dividir a função em duas.

Não tem efeitos colaterais

Os efeitos colaterais são consequências não intencionais de seu código. Eles podem estar alterando os parâmetros passados, no caso de passagem por referência, ou talvez alterando uma variável global.

O ponto principal é que eles prometeram fazer outra coisa e você precisa ler o código com atenção para perceber o efeito colateral. Eles podem resultar em alguns bugs desagradáveis.

Aqui está um exemplo do livro:

public class UserValidator {      private Cryptographer cryptographer;      public boolean checkPassword(String userName, String password) {         User user = UserGateway.findByName(userName);        if (user != User.NULL) {          String codedPhrase = user.getPhraseEncodedByPassword();          String phrase = cryptographer.decrypt(codedPhrase, password);          if ("Valid Password".equals(phrase)) {            Session.initialize();            return true;           }        }        return false;       }}

Você pode ver o efeito colateral dessa função?

Ele está verificando a senha, mas quando a senha é válida, também está inicializando a sessão, o que é um efeito colateral.

Você pode alterar o nome da função para algo como checkPasswordAndInitializeSession para tornar esse efeito explícito. Mas ao fazer isso, você deve notar que sua função está realmente fazendo duas coisas e você não deve inicializar a sessão aqui.

Não se repita

A repetição do código pode ser a raiz de todos os males do software. Código duplicado significa que você precisa mudar as coisas em vários lugares quando há uma mudança na lógica e é muito sujeito a erros.

Use os recursos de refatoração do IDE e extraia um método sempre que encontrar um segmento de código repetido.

extract method
Método de extração IntelliJ

Bônus

Por favor não. Este é sério porque outras pessoas que virem o código terão medo de excluí-lo porque não sabem se ele está lá por um motivo. Esse código comentado ficará lá por muito tempo. Então, quando nomes de variáveis ​​ou nomes de métodos mudam, eles se tornam irrelevantes, mas ainda assim ninguém os exclui.

Basta excluí-lo. Mesmo que fosse importante, há controle de versão para isso. Você sempre pode encontrar.

Conheça as convenções do seu idioma

Você deve conhecer as convenções de seu idioma em termos de espaçamento, comentários e nomes. Existem guias de estilo disponíveis para vários idiomas.

Por exemplo, você deve usar camelCase em Java, mas snake_case em Python. Você coloca colchetes de abertura em uma nova linha em C #, mas os coloca na mesma linha em Java e JavaScript.

Essas coisas mudam de idioma para idioma e não existe um padrão universal.

Aqui estão alguns links úteis para você:

A codificação limpa não é uma habilidade que pode ser adquirida durante a noite. É um hábito que precisa ser desenvolvido mantendo esses princípios em mente e aplicando-os sempre que você escrever um código.

Obrigado por dedicar seu tempo para ler e espero que tenha sido útil.

Se você estiver interessado em ler mais artigos como este, você pode se inscrever no meu blog.