Vamos falar sobre uma boa prática da programação, o Clean Code.
Eu não gosto de complicar muito o assunto e acho que alguns exageram (over-engineering). Claro que com o tempo e maior senioridade você vai muito além, mas quero demonstrar algumas coisas mínimas que eu acredito que todo Dev deve fazer.
Prática difundida devido ao livro do Robert C. Martin (Conhecido na comunidade como Uncle Bob). Ele percebeu que maior parte do tempo gasto em programação é para dar manutenção em código.
O objetivo do clean Code, ou código limpo, é ter o código simples, com uma leitura clara e objetiva.
Um código sujo pode ser um dos grandes problemas que causam todo esse tempo, considerando a dificuldade em entender o que foi feito por outro dev ou ter funções com várias responsabilidades, o que dificulta alterações.
Mas se você está começando na área agora, nem está procurando vagas, esquece isso. Foca em aprender o básico da programação, depois você vê sobre boas práticas.
Vou demostrar alguns exemplos em JavaScript, mas o conceito é aplicável em todas as linguagens.
Além desses que vou chamar de "Padrões de Mercado", há também os padrões definidos por times.
Disclaimer: Você não precisa fazer exatamente como eu demonstro, diferente pode não ser errado, se considerar os princípios de código limpo.
Nomes
// Bad
// Use explanatory variables
complete = true
elapsedTime = 5
date = moment().format('YYYY/MM/DD');
n = 'Raphael'
function addToDate(date, days) {
console.log(date.getDate() + days)
}
const date = new Date();
addToDate(date, 1);
No exemplo acima vemos que os nomes das variáveis e da função não deixa muito claro qual o valor. Aqui tem apenas um trecho de código então é fácil identificar, mas imagina em um projeto grande.
No Clean Code comentários no código devem ser usados exclusivamente para documentar e não explicar a função do código, o nome dele deve ser claro o suficiente.
Um bom exemplo:
// Good
isComplete = true
elapsedTimeinDays = 5
currentDate = moment().format('YYYY/MM/DD');
userName = 'Raphael'
function addDaysToDate(todayDate, days) {
console.log(todayDate.getDate() + days)
}
const todayDate = new Date();
addToDate(todayDate, 1);
Funções
O ideal seria que uma função não tivesse mais de 3 parâmetros. Para quem não a criou saber exatamente como os valores são esperados, quando há muitas, pode ser trabalhoso e também de gerar testes.
Uma função que tem mais de uma responsabilidade também não é considerada uma boa prática.
Primeiro princípio do SOLID
, Single Responsability Principle, ou Princípio da Responsabilidade Única, diz que “uma classe deve ter apenas um motivo para mudar”, ou seja, deve ter uma única responsabilidade. No Código abaixo a função tem duas responsabilidades, criar usuário e enviar email.
// Bad
// Use 2 or fewer ideally arguments
// The function must have single responsibility
function createUserAndSendEmail(name, city, jobId, active) {
console.log(name)
console.log('email sent')
}
createUserAndSendEmail('Raphael', 'Uberlândia', 5, true);
Ao invés de vários parâmetros, você pode passar um objeto.
Também pode separar as responsabilidades, tornando a função com
responsabilidade única.
// Good
function createUser({name, city, jobId, active}) {
console.log(name)
}
function sendEmail() {
console.log('email sent')
}
createUser({
name: 'Raphael',
city: 'Uberlândia',
jobId: 5,
active: true
});
sendEmail();
Condicionais
Podemos evitar If Else aninhados usando a prática de early return
, que consiste em você verificar o oposto do que deseja e retornar o mais rápido possível para encerrar a função.
// Bad
const checkShipping = (totalToFreeShipping) => {
if (!isNaN(totalToFreeShipping)) {
if (totalPrice> totalToFreeShipping) {
setFreeShipping();
} else {
calculateShipping();
}
} else {
console.log('Value is not valid!')
}
}
checkShipping(80);
Agora com early return.
const checkShipping = (totalToFreeShipping) => {
// Early return. Validate possible problems before the “happy path”
if (isNaN(totalToFreeShipping)) return console.log('Value is not valid!');
if (totalPrice > totalToFreeShipping) {
setFreeShipping();
return;
}
calculateShipping();
}
checkShippin(80);
Um exemplo com Object Literals
, evitando um switch.
// Bad
const {role} = Subscriber
switch(role) {
case ADMINISTRATOR:
return <AdministratorUser />
case EDITOR:
return <EditorUser/>
case Subscriber:
return <SubscriberUser/>
}
// Good
const {role} = Subscriber
const components = {
ADMINISTRATOR: AdministratorUser,
EDITOR: EditorUser,
Subscriber: SubscriberUser
};
const Component = components[role];
return <Componenent />;
Componentização no Front-end
Com componentes menores temos a reutilização de trechos de código, o isolamento de contexto e a melhor legibilidade.
Links
Repositório com os exemplos: https://github.com/raphaelramos/cleancode-examples/
Você também pode conferir em vídeo onde demostro em live coding: