Uma função é uma relação matemática estabelecida entre duas variáveis.
No capitulo 3 da incrível jornada pelo mundo do código com o Tio Beto, ele nos apresenta o conjunto do que pra ele são as boas práticas em funções.
Primeiro de tudo, como na definição matemática, para o tio Beto, funções precisam ser apenas uma relação. Ou seja, executar apenas uma operação. Elas precisam ser pequenas. Vejamos a função abaixo:
bool existsPossibilityToDrink({required Person person}){
if(DateTime.now().year - Person.age.year <= 18){
return false;
}
if(person.Sick != null && person.Sick.medicine.contraindicated){
return false;
}
final bool result = person.callMommyToAsk();
return result;
}
Notaram o rolê até ter a resposta da questão? Vamos tentar usar o conselho do tio Beto e fazer um conjunto de pequenas funções.
Primeiro, vamos começar verificando se o cara é maior de 18 anos, pois todo mundo aqui segue a lei. Eu espero muito.
bool hasLegalAge(Person person){
return (DateTime.now().year - Person.age.year >= 18);
}
Depois, podemos verificar se a pessoa tem alguma doença que não possa ingerir alcool com o seu medicamento, pois caso seja sim, não pode ingerir álcool.
bool hasSick(Person person){
return (person.Sick != null && person.Sick.medicine.contraindicated);
}
E por fim e muito mais decisivo que todas as outras opções anteriores, a pessoa tem que ligar para a mãe, caso ela diga não... vocês já sabem, é não.
bool askToMommy(Person person){
return person.callMommyToAsk();
}
A partir destas pequenas funções que só fazem uma única coisa, montamos outra função que só vai fazer uma única coisa, que será decidir se esta pessoa irá beber ou não!
bool existsPossibilityToDrink({required Person person}){
return hasLegalAge(person) && !hasSick(person) && !askToMommy(person);
}
Outro conselho super válido que o chato, digo, o Tio Beto nos dá é sobre o bloco de código. Se o código tem if, else e while, eles devem chamar apenas a função relacionada a sua lógica de execução. Vamos ao exemplo.
Game playToDog({required Person kid}){
if(kid.energy == exhausted){
final Game game = new Game(name: 'play on youtube videos dog for
distract...',
object: 'tv',
duration : Duration(minutes:30),
dogSatisfaction: DogSatisfaction.neutral,
);
return game;
}
final Game game = new Game(name: 'play pique-esconde with dog',
object: null,
duration : Duration(minutes:60),
dogSatisfaction: DogSatisfaction.high,
);
return game;
}
Vamos criar duas funções, uma para o caso da criança estar exausta, e outra para o caso da criança estar com o pique de dez pilhas duracell.
A primeira função:
Game getGameExhaustedKid(){
return Game(name: 'play on youtube videos dog for
distract...',
object: 'tv',
duration : Duration(minutes:30),
dogSatisfaction: DogSatisfaction.neutral,
);
}
a função para a criança encapeta... digo, bem disposta:
Game getGameWillingKid(){
return Game(name: 'play pique-esconde with dog',
object: null,
duration : Duration(minutes:60),
dogSatisfaction: DogSatisfaction.high,
);
}
Agora chamando novamente no bloco de código, temos:
Game playToDog({required Person kid}){
if(kid.energy == exhausted){
return getGameExhaustedKid();
}
return getGameWillingKid();
}
Ainda sobre funções, algo que intriga muito o tio Beto é o conjunto delas, afinal, se vamos fazer várias funçõezinhas, quer dizer que vão existir várias e que a ordem delas dispostas no código deve levar alguma lógica. O Tio Beto nos dá a alternativa da Regra decrescente, ou seja, a leitura do código deve ser feita de cima para baixo. Vamos utilizar o código já existente do nosso amigo que quer beber, visto lá em cima e vamos pensar que este código está localizado em um código do BarController
class BarController extends Controller{
@overrited
controlled(Person person){
super.person;
}
bool hasLegalAge(Person person){
return (DateTime.now().year - Person.age.year >= 18);
}
bool hasSick(Person person){
return (person.Sick != null && person.Sick.medicine.contraindicated);
}
bool askToMommy(Person person){
return person.callMommyToAsk();
}
bool existsPossibilityToDrink({required Person person}){
return hasLegalAge(person) && !hasSick(person) && !askToMommy(person);
}
}
Reparem que do começo da classe ao fim você chega na função que junta todas as funções e dá sentido a existência das demais. Filosófico né? Eu particulamente acho uma chatice desse velho. Sou a favor de separar em funções menores uma função que seja extensa mas essa pataquada de storytelling de funções? ora meu senhor, é falta de bug? falta de task no board? vá caçar um teste unitário para fazer vá!
Um conselho realmente bom que este senhor, o tio Beto dá logo em seguida a todo esse estresse é definir uma quantidade razoável de quantos parâmetros se deve receber em uma função.
O tio Beto acha que é aceitável uma função receber normalmente até (olha a ênfase aqui) reparou na ênfase? 3 parâmetros. Mais do que isso, é necessário pensar em uma solução. Seja uma estrutura de dados, seja uma classe auxiliar, seja um método de injeção. Não é natural uma função receber 68 parâmetros. "AH MAS POR QUÊ?" porque nem sei se esse por que é junto ou separado e porque indica que essa função não é tão simples quanto necessária para ter apenas uma funcionalidade relacionada a ela. Se existe muito parâmetro é por que existe muito o que se fazer dentro daquela execução, então tire o seu cavalinho da chuva e separe esta função.
Pra finalizar este capítulo tão controverso, quero comentar que foi um dos capítulos do livro que mais discordei do tio Beto, mas a vida do adulto é assim, vou xingar no twitter depois para passar a raiva, porém foi com ele que há anos atrás na primeira leitura do livro tirei a minha primeira grande lição do mundo de software.
Criar um software é como qualquer outro tipo de escrita. Ao escrever um artigo, você primeiro coloca seus pensamentos no papel e depois os organiza de modo que fiquem fáceis de ler. O primeiro rascunho pode ficar desastroso e desorganizado, então você, reestrutura e refina até que ele fique como você deseja.
Top comments (2)
Estou adorando essa série! Parabéns!
Obrigaada