CLEAN CODE - BOAS PRÁTICAS
Abraão Duarte
Posted on June 10, 2021
Atualmente estou lendo o livro Clean Code, escrito por Robert C. Martin, conhecido como Uncle Bob, por isso, decidi escrever um artigo com algumas dicas importantes que encontrei na leitura e que tem me motivado a escrever códigos melhores.
Boa parte do tempo dos desenvolvedores de software é gasto escrevendo códigos, portanto devemos ter um cuidado em como escrevemos esses códigos, nós nos expressamos por meio dos códigos que escrevemos e, eles devem ser legíveis e de fácil compreensão.
Talvez você já tenha percebido que nos passamos grande parte de nosso tempo dando manutenção, seja em sistemas legados e antigos, seja nos nossos próprios códigos que escrevemos a pouco tempo, estamos sempre acrescentando algo novo, corrigindo erros, melhorando, etc. Justamente por causa disso que devemos nos esforçar por escrever códigos melhores, mais legíveis, para que a manutenção e mesmo a evolução do sistema seja mais fácil e menos dolorosa.
Quando nos deparamos em situações onde precisamos dar manutenção em algum código ruim, essa tarefa pode ser tornar demorada, difícil e cara, pois iremos gastar um tempo maior do que gastaríamos caso esse código estivesse mais legível 😠. E já vou adiantando, escrever código limpo não é uma tarefa simples e fácil, antes é algo trabalhoso, em outras palavras, você irá suar a camisa, nesse processo você irá errar, e também ver outros errarem, mas não desanime. No fim das contas como o próprio autor do livro diz:
Escrever código limpo é uma arte e vai tempo e prática. 😲
O que seria um código limpo? Juntando algumas definições que encontrei no livro, pode se dizer que: ‘um código limpo é elegante e eficiente, que faz somente uma coisa, aquilo que ele se propõe a fazer. É algo simples e direto, legível e claro. É um código bem testado, bem escrito’.
Para escrever código limpo precisamos estar atentos aos detalhes, pois eles são importantes e no fim das contas fazem a diferença.
Dado essa introdução, irei apresentar algumas sugestões que encontrei no livro e que acho válido compartilhar, os códigos de exemplo estarão em Javascript, porém os conceitos podem ser aplicados em qualquer linguagem.
Nomes são importantes, portanto seja cuidadoso.
Você já deve ter se deparado com nomes de variáveis, funções, métodos que eram obscuros e difíceis de compreender. Para entendermos esses nomes, gastamos um tempo maior que gastaríamos se o nome estivesse claro. Isso mostra que dar nomes corretos e claros fazem diferença.
1. Use nomes que revelam seu propósito.
Um nome deve ter significado que diz o que ele faz ou ao que ele se refere. Se um nome precisa de um comentário, então ele já não revela seu proposito.
Exemplo ruim: 🙈
const d = new Date();
const y = d.getYear();
const m = d.getMonth();
Exemplo bom: 😁
const date = new Date();
const year = d.getYear();
const month = d.getMonth();
2. Use distinções significativas
Exemplo ruim: 🙈
getDetails();
getData();
getRecord();
Às três funções parecem ser a mesma coisa, não existe uma distinção clara que diz o que essa função está fazendo.
Um exemplo melhor pode ser o seguinte: 😁
getUser(); // É melhor que os exemplos acima.
3. Use nomes fáceis de se pronunciar, ou pelo menos que sejam pronunciáveis.
Você já se deparou com nome de variáveis que são impronunciáveis? Isso é uma má prática.
Veja o seguinte exemplo: 🙈
const yyyymmdstr = ‘2021-06-09’;
É uma variável que não tem como pronunciar seu nome. Poderíamos rescrever da seguinte maneira: 😁
const currentDate = ‘2021-06-09’;
4. Use nomes que sejam fáceis de se buscar.
Por exemplo, nomes de uma letra só: const d = new Date();
são difíceis de se pesquisar e irá trazer uma infinidade de resultados
Outro exemplo: 🙈
setTimeout(blastOff, 86400000);
Pesquisar por número que não trazem nenhum significado não, é algo muito bom, e podem acabar retornando resultados inesperados, podemos escrever da seguinte maneira: 😁
const MILLISECONDS_PER_DAY = 86400000;
setTimeout(blastOff, MILLISECONDS_PER_DAY);
Dessa maneira você pode pesquisar pelo nome da variável e também está claro o que esse numero representa.
5. Nomes de classes devem ter nomes com substantivos
Exemplo: 😁
class User {}
class Customer {}
6. Nome de métodos é uma boa prática ter verbos
Exemplo: 😁
getUser();
deleteUser();
handleVote();
Escreva funções melhores
Estamos escrevendo funções a todo momento, é importante que essas sejam claras e legíveis.
Funções devem ser pequenas, você já deve ter se deparado em algum momento com funções com dezenas de linhas, que fazem várias coisas. Funções assim são difíceis de dar manutenção, pois é difícil entende-las.
Algumas dicas para escrever funções melhores
1. Faça apenas uma coisa
Funções devem fazer somente uma coisa e devem fazê-la bem.
Uma boa forma de sabermos se nossa função faz mais de uma coisa é se conseguimos extrair outras funções dela.
Exemplo ruim: 🙈
function emailClients(clients) {
clients.forEach(client => {
const clientRecord = database.lookup(client);
if (clientRecord.isActive()) {
email(client);
}
});
}
Essa função tem mais de uma responsabilidade, ela pega os dados do cliente e verifica se o cliente está ativo.
Poderíamos separar da seguinte maneire: 😁
function emailActiveClients(clients) {
clients.filter(isActiveClient).forEach(email);
}
function isActiveClient(client) {
const clientRecord = database.lookup(client);
return clientRecord.isActive();
}
Veja, cada função é responsável por fazer apenas 1 coisa.
As funções devem fazer uma coisa. Devem fazê-la bem. Devem fazer apenas ela. 😲
2. Um nível de abstração por função
Vários níveis de abstração dentro de uma função sempre geram confusão.
Exemplo: 🙈
function parseBetterJSAlternative(code) {
const REGEXES = [ // ... ];
const statements = code.split(" ");
const tokens = [];
REGEXES.forEach(REGEX => {
statements.forEach(statement => { // ... });
});
const ast = [];
tokens.forEach(token => { // lex... });
ast.forEach(node => { // parse... }); }
Veja essa função, é difícil entender o que acontece mesmo ela sendo pequena. Imagina uma função com o triplo do tamanho, fazendo várias coisas, é difícil dar manutenção nessas funções.
Veja como poderíamos escrever: 😁
function parseBetterJSAlternative(code) {
const tokens = tokenize(code);
const syntaxTree = parse(tokens);
syntaxTree.forEach(node => { // parse... });
}
function tokenize(code) {
const REGEXES = [ // ... ];
const statements = code.split(" ");
const tokens = [];
REGEXES.forEach(REGEX => {
statements.forEach(statement => {
tokens.push(/* ... */);
});
});
return tokens;
}
function parse(tokens) {
const syntaxTree = [];
tokens.forEach(token => {
syntaxTree.push(/* ... */);
});
return syntaxTree;
}
3. Use nomes descritivos
Mesma regra que usamos para variáveis, que sejam claro e legível e diga o que a função faz.
Não tenha medo de criar nomes extensos, pois eles são melhores que um pequeno e enigmático.
4. Parâmetros de funções
Devemos evitar passar vários parâmetros para uma função, o ideal é que nossas funções recebam no máximo 2 parâmetros.
Veja o seguinte exemplo: 🙈
function createMenu(title, body, buttonText, cancellable) {
// doSomething
}
createMenu("Foo", "Bar", "Baz", true);
Veja que é confuso e muito fácil esquecer de passar um parâmetro e quebrar a função.
Prefira fazer assim: 😁
function createMenu({ title, body, buttonText, cancellable }) {
// doSomething
}
createMenu({
title: "Foo",
body: "Bar",
buttonText: "Baz",
cancellable: true
});
Dessa maneira fica mais clara, você sabe o que é o que.
5. Parâmetros lógicos
Parâmetros lógicos é uma má prática, pois mostra explicitamente que a função faz mais de uma coisa.
Veja: 🙈
function createFile(name, temp) {
if (temp) {
fs.create(`./temp/${name}`);
} else {
fs.create(name);
}
}
O parâmetro temp
é um booleano, isso implica que a função tem mais de uma responsabilidade.
Poderíamos fazer: 😁
function createFile(name) {
fs.create(name);
}
function createTempFile(name) {
createFile(`./temp/${name}`);
}
Veja que evitamos passar valores booleanos como parâmetro de função.
6. Evite efeitos colaterais
Efeitos colaterais são mentiras. Sua função promete fazer apenas uma coisa, mas ela também faz outras coisas escondidas.
Efeitos colaterais são perigosos, e muitas vezes difíceis de se identificar.
Veja esse exemplo: 🙈
let name = "Ryan McDermott";
function splitIntoFirstAndLastName() {
name = name.split(" ");
}
splitIntoFirstAndLastName();
console.log(name);
A variável name
está sendo modificada na função splitIntoFirstAndLastName
isso é ruim, pois em um arquivo com dezenas de linhas, você se perderia para encontrar os lugares onde essa variável está sendo modificada. Você não saberia qual é o valor de name
uma vez que em cada função ela pode ter um valor.
Evite variáveis globais.
Veja como poderíamos fazer: 😁
function splitIntoFirstAndLastName(name) {
return name.split(" ");
}
const name = "Ryan McDermott";
const newName = splitIntoFirstAndLastName(name); console.log(name); // 'Ryan McDermott';
console.log(newName); // ['Ryan', 'McDermott'];
A variável name
é um parâmetro da função, e assim não tem nenhum efeito colateral ao alterar esse parâmetro na função.
7. Evite repetição
Duplicação de código pode ser um grande mal no seu software, sempre que você ver que você está repetindo muito código, extraia isso para funções.
Escreva comentários com responsabilidade
Por vezes o uso de comentários é para compensar o nosso fracasso em nos expressar no código.
É melhor você ter um código legível com poucos comentários do que um código complexo, difícil de ler com vários comentários.
Não insira comentários em um código ruim, refatore ele.
Comentários imprecisos são muito piores do que nenhum. O único lugar onde pode-se encontrar a verdade é no código. Só ele pode dizer o que ele realmente faz, comentários podem mentir.
Comentários ruins
- Comentários esquecidos no código.
- Comentários redundantes, por exemplo:
// Function that get users
const getUsers = () => {...}
- Comentários longos
- Comentários ruidosos
// Return the day of month
const getDayOfMonth = () => {...}
- Códigos como comentários
Conclusão
A conclusão é que se você é um programador você deveria se importar com seu código, se seguirmos essas dicas, ou pelo menos algumas delas, já estaremos escrevendo códigos melhores.
Ao escrever código limpo estaremos ajudando futuras pessoas que venham dar manutenção no nosso código, e também estaremos ajudando a nós mesmo, caso no futuro tenhamos que dar manutenção no código que fizemos.
Este é apenas alguns pontos que eu achei interessante nos primeiros 4 capítulos do livro, espero ainda trazer mais alguns artigos a respeito do assunto.
Fonte
Martin, Robert C. Código Limpo: Habilidades práticas do agile software. Ed. Revisada São Paulo: Alta Books, 2011.
Exemplos: https://github.com/ryanmcdermott/clean-code-javascript
Posted on June 10, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.