3 regras simples para ter um código mais limpo e profissional
Sabemos que existem dezenas de design patterns por aí cada um com bonus/onus. Chegar nesse nível, de usar design patterns com maestria, é algo que se aprende somente com o tempo!
Mas, mesmo para quem está começando, é possível aplicar técnicas simples no seu código de forma a deixá-lo mais profissional!! Dentre estas regras, eu deixo aqui 3 que considero importantes. Se houver mais, deixe nos comentários.
1ª regra
Não use ifs encadeados, muito menos else
Exemplo ruim:
function verificarIdade(idade) {
if (idade < 0) {
return "Idade inválida";
} else {
if (idade >= 0 && idade < 18) {
return "Menor de idade";
} else {
if (idade >= 18 && idade < 60) {
return "Adulto";
} else {
if (idade >= 60) {
return "Idoso";
}
}
}
}
}
A solução para esse monte de if encadeado é separar cada um deles, da seguinte forma:
function verificarIdade(idade) {
if (idade < 0) {
return "Idade inválida";
}
if (idade < 18) {
return "Menor de idade";
}
if (idade < 60) {
return "Adulto";
}
return "Idoso";
}
Lembre-se que é possível sempre transformar um código encadeado de ifs em algo mais simples. Vc pode usar o chatgpt pra isso!
2ª Regra
Transforme todos os comentários de código em funções com nomes bem definidos! Não crie uma função que faça duas coisas distintas, separe !!!!
Por exemplo, se você for lançar um foguete, esse tipo de código nao seria muito bem vindo:
function lancarFoguete() {
// Verificar se todos os sistemas estão prontos
let sistemasProntos = true;
let temperatura = 30; // temperatura dos motores em graus Celsius
let pressao = 90; // pressão nos tanques de combustível em psi
if (temperatura > 50 || pressao < 80) {
sistemasProntos = false;
}
// Iniciar a contagem regressiva
if (sistemasProntos) {
console.log("Contagem regressiva iniciada...");
for (let i = 10; i >= 1; i--) {
console.log(i);
// esperar 1 segundo antes de prosseguir
const data = new Date();
let tempoAtual = null;
do { tempoAtual = new Date(); }
while (tempoAtual - data < 1000);
}
// Acionar os motores
acionarMotores();
// Monitorar o progresso
let altitude = 0;
let velocidade = 0;
while (altitude < 200000) { // o foguete sobe até 200 km de altitude
altitude += calcularAltitude(velocidade); // função para calcular a altitude baseada na velocidade
velocidade += calcularVelocidade(); // função para calcular a velocidade baseada na força dos motores
if (temperatura > 100 || pressao < 60) { // verificar se há problemas
abortarLancamento();
return;
}
}
// Chegar à órbita
console.log("Foguete alcançou a órbita!");
} else {
console.log("Lançamento abortado. Problemas nos sistemas.");
}
}
Veja que, apesar de termos alguns métodos como "acionarmotores()", essa funcao está claramente confusa. Nesse ponto, podemos dividir o máximo possível as tarefas em métodos, por exemplo
class Foguete {
constructor() {
this.sistemasProntos = false;
this.motoresAcionados = false;
this.emOrbita = false;
}
verificarSistemasProntos() {
// verificar se todos os sistemas estão prontos
this.sistemasProntos = true; // exemplo, considerando que todos os sistemas estão prontos
}
iniciarContagemRegressiva() {
// iniciar a contagem regressiva
for (let i = 10; i > 0; i--) {
console.log(`Contagem regressiva: ${i}`);
sleep(1000); // esperar 1 segundo
}
}
acionarMotores() {
// acionar os motores
this.motoresAcionados = true; // exemplo, considerando que os motores foram acionados
}
monitorarProgresso() {
// monitorar o progresso do lançamento
console.log("Monitorando progresso do lançamento...");
// exemplo, considerando que o lançamento foi bem sucedido
this.emOrbita = true;
}
checarOrbita() {
// verificar se o foguete está em órbita
if (this.emOrbita) {
console.log("Foguete em órbita!");
} else {
console.log("Foguete não atingiu órbita desejada...");
}
}
lancarFoguete() {
this.verificarSistemasProntos();
if (!this.sistemasProntos) {
console.log("Erro ao verificar sistemas. Lançamento abortado.");
return;
}
this.iniciarContagemRegressiva();
this.acionarMotores();
this.monitorarProgresso();
this.checarOrbita();
}
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
const meuFoguete = new Foguete();
meuFoguete.lancarFoguete();
Em algumas linguagens é possível, para cada método da classe, retornar ela mesma, de forma que possamos fazer um encadeamento de métodos:
const foguete = new Foguete();
foguete
.verificarSistemas()
.iniciarContagemRegressiva()
.monitorarProgresso()
.chegarEmOrbita()
.lancarFoguete();
3ª Dica
Transforme vários parâmetros de um método em um objeto. Ao invés de termos um:
function salvarUsuario(nome, email, dataNascimento, telefone) {
const erro = { descricao: "Parâmetro inválido" };
if (!nome) return erro;
if (!email) return erro;
if (!dataNascimento) return erro;
if (!telefone) return erro;
// Aqui vai a lógica para salvar o usuário
return { sucesso: true };
}
Podemos ter algo do tipo:
function salvarUsuario(user) {
const erro = { descricao: "Parâmetro inválido" };
if (!user.nome) return erro;
if (!user.email) return erro;
if (!user.dataNascimento) return erro;
if (!user.telefone) return erro;
// Aqui vai a lógica para salvar o usuário
return { sucesso: true };
}
É claro que tendemos a usar objetos para que possamos ter um tipo. No exemplo anterior, podemos ter em typescript:
interface Usuario {
id?: number;
nome: string;
email: string;
dataNascimento: string;
telefone: string;
}
interface Erro {
descricao: string;
}
function salvarUsuario(user: User): User | Erro {
const erro: Erro = { descricao: "Parâmetro inválido" };
if (!user.nome) return erro;
if (!user.email) return erro;
if (!user.dataNascimento) return erro;
if (!user.telefone) return erro;
user.id = UsuarioService.save(user).getId();
return user;
}
Neste exemplo, podemos ver que tanto User quanto Erro são classes de tipo (também chamadas de interface). Claro que existem algumas formas de reescrever esta função, já que alterar um objeto que foi passado por parâmetro nao é uma boa prática! Deixo como exercicio a solução.
Eu acredito que, seguindo essas três regras, seu código ficará melhor estruturado a um nível mais profissonal, mesmo que você não entenda muito de design patterns.