<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Marcus Xavier</title>
    <description>The latest articles on DEV Community by Marcus Xavier (@marcusxavierr).</description>
    <link>https://dev.to/marcusxavierr</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F593992%2Fa4e1adab-16b2-41ea-a705-6dfc47b92346.png</url>
      <title>DEV Community: Marcus Xavier</title>
      <link>https://dev.to/marcusxavierr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/marcusxavierr"/>
    <language>en</language>
    <item>
      <title>Como as linguagens de programação são criadas?</title>
      <dc:creator>Marcus Xavier</dc:creator>
      <pubDate>Sun, 04 Aug 2024 19:30:24 +0000</pubDate>
      <link>https://dev.to/marcusxavierr/como-as-linguagens-de-programacao-sao-criadas-5ggd</link>
      <guid>https://dev.to/marcusxavierr/como-as-linguagens-de-programacao-sao-criadas-5ggd</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Nós usamos linguagens de programação diariamente, e as vezes pode parecer que o computador está fazendo uma mágica: você escreve um arquivo de texto e o computador magicamente executa as operações que esse arquivo descreve.&lt;/p&gt;

&lt;p&gt;Quando eu era criança, existia um desenho animado chamado "De onde vem?". A cada episódio algo era explicado, como por exemplo, "De onde vem o vidro?". Era uma explicação simples e de fácil entendimento, porém bem satisfatória.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5t5jlxsbgnhxcry2i2ci.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5t5jlxsbgnhxcry2i2ci.png" alt="Capa do programa " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com isso em mente, a ideia desse artigo, é explicar um pouco sobre &lt;em&gt;de onde vêm as linguagens de programação&lt;/em&gt;. Nesse post, eu pretendo explicar um pouco sobre como uma linguagem pode ser implementada, e por fim, trazer alguns materiais de estudo bem interessantes para quem deseja se aprofundar e quem sabe programar a sua própria linguagem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Para que uma linguagem tome vida, é preciso &lt;em&gt;implementá-la&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Antes de mais nada, precisamos separar muito bem dois conceitos: a ideia abstrata da linguagem, e a sua implementação concreta (um interpretador ou compilador).&lt;/p&gt;

&lt;p&gt;Uma linguagem nada mais é do que uma forma de se comunicar, é uma sequência de letras organizadas de forma a passar uma mensagem.&lt;/p&gt;

&lt;p&gt;O problema é: computadores não entendem palavras, nem mesmo sequências esquisitas de letras (o comando &lt;code&gt;LDS&lt;/code&gt;, por exemplo). Tudo o que o computador entende, são instruções pra sua CPU. Então é necessário ter algum software capaz de pegar as operações descritas na nossa linguagem (o &lt;code&gt;print('hello world')&lt;/code&gt;, por exemplo), e transformar isso em instruções para o computador interpretar, de alguma forma.&lt;/p&gt;

&lt;p&gt;Ou seja, precisamos de uma &lt;strong&gt;implementação concreta&lt;/strong&gt; para que nossa &lt;strong&gt;linguagem&lt;/strong&gt; possa ser executada. Nesse artigo, sempre que eu falar "linguagem", eu estou me referindo à essa implementação concreta e prática que traz utilidade para o amontoado de texto colorido que escrevemos.&lt;/p&gt;

&lt;p&gt;E esses programas capazes de executar linguagens têm nome: &lt;strong&gt;interpretadores e compiladores&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que são interpretadores e compiladores? E qual a diferença entre eles?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  O que é um compilador?
&lt;/h3&gt;

&lt;p&gt;De forma muito resumida, um compilador é um programa que transforma o seu código fonte, em outro tipo de representação, que geralmente é uma forma mais eficiente para o computador executar. O software que pega seu código C, e transforma em binário executável, é um compilador. Mas o software que pega o código typescript (&lt;code&gt;main.ts&lt;/code&gt;), e transforma em javascript (&lt;code&gt;main.js&lt;/code&gt;) para ser executado no navegador, &lt;strong&gt;também&lt;/strong&gt; é um compilador.&lt;/p&gt;

&lt;p&gt;Ou seja, um compilador não é necessariamente um programa que lê código numa linguagem X e cospe código binário. Esse programa basicamente tem a responsabilidade de transformar seu código em algo alguma representação que possa ser executada de alguma forma, mas essa representação pode ter várias formas.&lt;/p&gt;

&lt;h3&gt;
  
  
  O que é um interpretador?
&lt;/h3&gt;

&lt;p&gt;Por outro lado, um interpretador é um programa que lê o seu código fonte, e de alguma forma, executa as instruções que ele contém. Só isso, então quando você passa código javascript para o Nodejs, ele está agindo como um interpretador: lendo código fonte, e &lt;strong&gt;interpretando-o&lt;/strong&gt;. E algumas &lt;strong&gt;interpretadores&lt;/strong&gt; usam &lt;strong&gt;compiladores&lt;/strong&gt; para os auxiliarem no processo de interpretador uma linguagem.&lt;/p&gt;

&lt;p&gt;A linguagem PHP por exemplo, tem uma espécie de máquina virtual chamada Zend, que recebe uma representação compilada do seu código fonte, e executa as instruções dessa representação.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pera, então linguagens interpretadas também podem ser compiladas?
&lt;/h3&gt;

&lt;p&gt;Sim, isso é algo um pouco confuso no início, mas a ideia principal é que interpretadores e compiladores não são opostos. Um compilador tem um papel muito claro, e esse papel é diferente de um interpretador.&lt;/p&gt;

&lt;p&gt;Muitas linguagens interpretadas usam a técnica de ter uma espécie de máquina virtual, extremamente otimizada, que recebe uma coisa que chamamos de &lt;strong&gt;bytecode&lt;/strong&gt; e executa isso. Então, a máquina virtual de linguagens como &lt;code&gt;PHP&lt;/code&gt; e &lt;code&gt;Python&lt;/code&gt;, não são capazes de entender seu código e por isso precisamos da ajuda de compiladores, para gerar &lt;code&gt;bytecode&lt;/code&gt; a partir do seu código (imagine como um assembly para uma máquina virtual).&lt;/p&gt;

&lt;p&gt;No fim das contas, quando falamos que uma linguagem é "interpretada", simplesmente queremos dizer que você precisa sempre passar o seu código fonte para um programa (o &lt;code&gt;node&lt;/code&gt; ou &lt;code&gt;python&lt;/code&gt;, por exemplo), e esse programa já vai rodar o seu código.&lt;/p&gt;

&lt;p&gt;E quando uma linguagem é "compilada", primeiro você precisa passar seu código fonte para um programa (o &lt;code&gt;gcc&lt;/code&gt; ou &lt;code&gt;tsc&lt;/code&gt;, por exemplo), que irá gerar um novo arquivo, e daí sim poderemos executar esse arquivo de alguma forma.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ok, entendi de onde vêm as linguagens, mas como eu posso criar uma implementação?
&lt;/h2&gt;

&lt;p&gt;Eu diria que o caminho mais prático pra quem está começando é criar um interpretador, que utiliza a técnica de tree walk para interpretar o código. Esse estilo de implementação é quebrada em 3 componentes principais: scanner, parser e o interpretador tree walk.&lt;/p&gt;

&lt;p&gt;O seu código passará por esses 3 componentes nessa ordem mesmo, onde a cada etapa, o interpretador transforma o seu código em estruturas cada vez mais fáceis de serem interpretadas pelo computador.&lt;/p&gt;

&lt;p&gt;Esse fluxograma simples mostra o caminho do código fonte da sua linguagem até a fase da interpretação.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FzTVJcKLR%2Fimage.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FzTVJcKLR%2Fimage.png" alt="diagonal" width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vou explicar (com códigos de exemplo) cada uma dessas etapas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scanner
&lt;/h3&gt;

&lt;p&gt;Nessa fase o seu código fonte é lido como uma string (sequência de caracteres) e quebrado em vários tokens. Esse token é uma unidade da sua linguagem de programação, como por exemplo as palavras reservadas &lt;code&gt;while&lt;/code&gt; e &lt;code&gt;if&lt;/code&gt;, ou então os literais como &lt;code&gt;"isso é uma string"&lt;/code&gt; ou &lt;code&gt;10&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Então, isso:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl011jh1q45ajho2j1frf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl011jh1q45ajho2j1frf.png" alt="source code antes do scanner" width="800" height="123"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vira isso:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh8rab48e3u8m7qwcdb1j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh8rab48e3u8m7qwcdb1j.png" alt="source code antes do scanner" width="800" height="110"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Essa imagem é só pra exemplificar a quebra do código fonte em tokens, geralmente o "token" é um objeto/estrutura contendo algumas informações importantes como:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O seu tipo (ser é um &lt;code&gt;for&lt;/code&gt;, um número, operador &lt;code&gt;++&lt;/code&gt; e etc.).&lt;/li&gt;
&lt;li&gt;O seu lexema (a string que achamos na hora de escanear esse token).&lt;/li&gt;
&lt;li&gt;Em qual linha ele foi encontrado (ajuda bastante na hora de aportar erros de sintaxe).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Um exemplo de token seria:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Token&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;TokenType&lt;/span&gt; &lt;span class="nv"&gt;$tipo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;mixed&lt;/span&gt; &lt;span class="nv"&gt;$valor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Válido somente para valores literais como "strings" e números (10.5) explícitos no código fonte&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$lexema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$linha&lt;/span&gt;
    &lt;span class="p"&gt;){}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Parser
&lt;/h3&gt;

&lt;p&gt;Nessa fase já possuímos os tokens, mas esse monte de tokens ainda não possui significado algum, não possui &lt;strong&gt;semântica&lt;/strong&gt;. Então o parser vai transformar esse amontoado de tokens em algo mais palpável: uma árvore, representando as operações. Chamamos essa árvore de &lt;em&gt;"Parse Tree"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Uma parse tree é uma estrutura de capaz de representar fielmente a estrutura do seu programa, respeitando as regras de precedência (por exemplo, no código &lt;code&gt;const x = 5 * 5&lt;/code&gt;, precisamos executar o código &lt;code&gt;5 * 5&lt;/code&gt; &lt;em&gt;antes&lt;/em&gt; de executar o código de atribuição &lt;code&gt;const x = ...&lt;/code&gt; que irá receber o valor do resultado)&lt;/p&gt;

&lt;p&gt;Por exemplo, imagine a expressão &lt;code&gt;10 + 5 * 2&lt;/code&gt;. Ela pode ser representada assim na parse tree:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp45tyuytc6czy85x0q96.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp45tyuytc6czy85x0q96.png" alt="Uma parse tree representando a operação acima" width="563" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na parse tree, cada item (chamamos de nó da arvore) tende a representar uma operação feita no código. Onde cada nó por sua vez pode conter várias ramificações e se tornar uma árvore, com outros nós representando operações mais aninhadas na expressão.&lt;/p&gt;

&lt;p&gt;Também é bom lembrar que a imagem acima é um exemplo, e um nó de uma parse tree pode ser um objeto/estrutura com várias informações úteis, como por exemplo, assim pode ser um nó que guarda operações binárias (uma operação com dois operandos, como soma ou multiplicação):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BinaryExpr&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Expr&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;Expr&lt;/span&gt; &lt;span class="nv"&gt;$esquerda&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;Token&lt;/span&gt; &lt;span class="nv"&gt;$operador&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;Expr&lt;/span&gt; &lt;span class="nv"&gt;$direita&lt;/span&gt;
    &lt;span class="p"&gt;){}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse nó eu salvo a ramificação de expressões à esquerda e direita, que podem ser uma variável (&lt;code&gt;x + 4&lt;/code&gt;), uma chamada de função (&lt;code&gt;pegaNoBanco(x) + 4&lt;/code&gt;) ou um literal (&lt;code&gt;10  + 4&lt;/code&gt;). E também guardo o token que possui informações do operador dessa expressão (&lt;code&gt;+&lt;/code&gt;, &lt;code&gt;*&lt;/code&gt;, etc.).&lt;/p&gt;

&lt;h3&gt;
  
  
  Interpretação Tree Walk
&lt;/h3&gt;

&lt;p&gt;As duas primeiras fases são praticamente iguais pra &lt;em&gt;QUALQUER&lt;/em&gt; implementação de uma linguagem, mas a partir dessa fase, cada linguagem vai escolher suas técnicas para dar vida à parse tree. Existe uma infinidade de técnicas, e nessa artigo vamos abordar uma das mais diretas: A Tree Walk.&lt;/p&gt;

&lt;p&gt;Como o nome sugere, a ideia é percorrer a árvore de expressões e ir computando os nós mais profundos primeiro e indo subindo até a raiz da árvore.&lt;/p&gt;

&lt;p&gt;Na implementação do Phortugol, eu usei pattern matching pra ter uma função que conseguia interpretar cada tipo de nó da árvore e me retornar um resultado&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Expr&lt;/span&gt; &lt;span class="nv"&gt;$expr&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;mixed&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$expr&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;BinaryExpr&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;handleBinary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$expr&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nv"&gt;$expr&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;UnaryExpr&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;handleUnary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$expr&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nv"&gt;$expr&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;LiteralExpr&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;handleLiteral&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$expr&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nv"&gt;$expr&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;LambdaExpr&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;handleLambdaExpr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$expr&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="mf"&gt;...&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Então sempre que eu chamar a função &lt;code&gt;evaluate&lt;/code&gt; passando uma ramificação da árvore, ele vai saber exatamente qual função chamar pra interpretar o nó atual, e no fim das contas essa função continuará sendo chamada até o resultado de todas as operações chegar à raiz da arvore e obtermos o resultado final da expressão.&lt;/p&gt;

&lt;p&gt;Por exemplo, a parse tree anterior seria interpretada da seguinte forma:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpa1l4x1xjjuxu70zfwzh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpa1l4x1xjjuxu70zfwzh.png" alt="O processo de interpretação da parse tree anterior" width="800" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Um fato curioso, é que as primeiras versões de Ruby e PHP usavam essa técnica de tree walk. Então é totalmente possível construir uma linguagem funcional usando um tree walk interpreter.&lt;/p&gt;

&lt;h2&gt;
  
  
  conclusão
&lt;/h2&gt;

&lt;p&gt;Ufa finalmente chegamos ao fim. Eu expliquei a ponta do iceberg, tem várias técnicas que eu não cobri, e não falamos sobre coisas como compilação e nem otimização de código (essa parte é bem mindblowing). Mas eu espero que já seja possível ter um modelo mental mais acurado sobre o que acontece quando digitamos o código e mandamos o computador rodar.&lt;/p&gt;

&lt;p&gt;Caso você tenha se interessado pelo assunto, tenho algumas recomendações:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href=""&gt;O livro crafting interpreters&lt;/a&gt;. É absurdamente bom, eu gostaria que mais áreas da computação tivessem um livro com a mesma qualidade, pragmatismo e simplicidade sem perder profundidade.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=OIKL6wFjFOo&amp;amp;list=PLBlnK6fEyqRgPLTKYaRhcMt8pVKl4crr6" rel="noopener noreferrer"&gt;Essa playlist sobre parsers top down&lt;/a&gt;, os dois primeiros vídeos são a melhor explicação sobre o "Recursive Descent Parser" que eu já vi. Recomendo usar como material de apoio&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>computerscience</category>
      <category>braziliandevs</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Iniciando no Elasticsearch: Conceitos básicos</title>
      <dc:creator>Marcus Xavier</dc:creator>
      <pubDate>Thu, 18 Apr 2024 14:11:12 +0000</pubDate>
      <link>https://dev.to/marcusxavierr/iniciando-no-elasticsearch-conceitos-basicos-1152</link>
      <guid>https://dev.to/marcusxavierr/iniciando-no-elasticsearch-conceitos-basicos-1152</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Segundo o site oficial do Elasticsearch, ele é uma engine RESTFul distribuída de busca. Esse monte de palavras basicamente querem dizer que ele é um banco de dados que funciona de forma distribuída por natureza (pode usar várias máquinas em paralelo de forma super fácil) e que expõe uma API RESTFul para que o usuário interaja com o banco, seja escrevendo ou buscando dados, entre outras coisas.&lt;/p&gt;

&lt;p&gt;O Elasticsearch é uma ferramenta incrível quando o assunto é trabalhar com uma quantidade massiva de dados e fazer buscas em textos longos (diga adeus aos &lt;code&gt;select like %texto%&lt;/code&gt; lentos). Ele é a base do sistema de buscas de milhares de empresas, e muito provavelmente você tem contato diariamente com algum software que usa Elasticsearch por baixo dos panos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Antes de mais nada, um pouco de história
&lt;/h2&gt;

&lt;p&gt;Sempre que estou estudando uma tecnologia nova, gosto de entender &lt;strong&gt;porque essa ferramenta foi criada&lt;/strong&gt; e em qual contexto ela nasceu. O Elasticsearch foi criado em 2010, mas podemos dizer que sua história começa em 2004 quando Shay Banon iniciou um projeto chamado &lt;a href="https://web.archive.org/web/20080207094229/http://www.compass-project.org/"&gt;Compass&lt;/a&gt;, com o intuito de ser usado no sistema de buscas em um &lt;a href="https://devm.io/databases/elasticsearch-founder-interview-112677"&gt;app de receitas para sua esposa&lt;/a&gt;. O projeto nasceu de forma despretensiosa e só foi se tornar open source tempos depois.&lt;/p&gt;

&lt;p&gt;Um fato curioso: nesse mesmo ano (2004) nascia o projeto que atualmente é um dos principais concorrentes do elastic, o &lt;a href="https://solr.apache.org/"&gt;Apache Solr&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Todos esses projetos nasceram mais ou menos com o mesmo objetivo em mente: realizar buscas de texto de forma &lt;strong&gt;muito&lt;/strong&gt; eficiente usando por baixo dos panos o &lt;a href="https://lucene.apache.org/"&gt;Apache Lucene&lt;/a&gt;, projeto criado em 1999 usando Java. O Apache Lucene é a base de quase todos os softwares de busca atualmente, sendo por exemplo usado pelo twitter &lt;a href="https://lucidworks.com/post/how-twitter-uses-apache-lucene-for-real-time-search/"&gt;para buscar milhões de tweets diariamente&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Mas voltando ao assunto, o Shay Banon criou o Compass em 2004, e quando estava criando a versão 3.0 do projeto em 2010, reescreveu várias partes do projeto para que ele fosse distribuído por natureza e altamente escalável. E daí nasce o Elasticsearch.&lt;/p&gt;

&lt;p&gt;O Elasticsearch foi criado então, &lt;strong&gt;para ser uma forma fácil de usar todo o poder do Apache Lucene&lt;/strong&gt;, enquanto fornece uma forma extremamente simples de escalar seu projeto horizontalmente, &lt;strong&gt;usando e abusando de computação distribuída&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Termos comuns do Elasticsearch
&lt;/h2&gt;

&lt;p&gt;Ao iniciar os estudos sobre Elasticsearch é normal se deparar com vários termos novos, e achar a ferramenta complicada por causa disso. A ideia aqui é explicar os principais termos deste banco de dados, e mostrar quando esse termo tem algum paralelo no mundo dos bancos relacionais.&lt;/p&gt;

&lt;h3&gt;
  
  
  Documento
&lt;/h3&gt;

&lt;p&gt;É basicamente como uma row/linha no banco de dados relacional. A diferença está no fato de documentos serem salvos como objetos JSON.&lt;br&gt;
Quando você fizer buscas na API de &lt;code&gt;_search&lt;/code&gt; do elastic, vai encontrar documentos com essa estrutura.&lt;/p&gt;

&lt;p&gt;Os dados salvos pelo usuário estão dentro de &lt;code&gt;_source&lt;/code&gt;, os outros campos são metadados adicionados pelo banco de dados.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"_index"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"produtos"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"_doc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1234"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"_score"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"_source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"nome"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Notebook"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"descricao"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bla bla bla"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Essa&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;descrição&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;pode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ser&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;facilmente&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;buscável&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;no&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;elastic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;e&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;eu&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;eu&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;sei&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;que&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;JSON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;não&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;aceita&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;comentário&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"preco"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4000"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Índice
&lt;/h3&gt;

&lt;p&gt;É basicamente uma coleção de documentos do mesmo tipo. Ou seja, é como uma tabela de um banco de dados relacional.&lt;/p&gt;

&lt;h3&gt;
  
  
  Node
&lt;/h3&gt;

&lt;p&gt;Um &lt;code&gt;node&lt;/code&gt; é uma instância do Elasticsearch que salva dados. Para salvar terabytes de dados no elastic, você pode ter vários nodes, cada um guardando um pedaço dos dados.&lt;br&gt;
Assim você pode escalar em várias máquinas diferentes, mesmo que cada uma tenha só alguns gigabytes de armazenamento, cada uma rodando os &lt;code&gt;nodes&lt;/code&gt; que pode.&lt;br&gt;
Teoricamente falando, é como se cada &lt;code&gt;node&lt;/code&gt; fosse um arquivo.&lt;/p&gt;
&lt;h3&gt;
  
  
  Cluster
&lt;/h3&gt;

&lt;p&gt;Se &lt;code&gt;nodes&lt;/code&gt; são arquivos, &lt;code&gt;clusters&lt;/code&gt; são pastas. Eles basicamente agrupam os &lt;code&gt;nodes&lt;/code&gt; e te permitem buscar em todos esses nodes em busca dos dados que você quer.&lt;br&gt;
Geralmente um &lt;code&gt;cluster&lt;/code&gt; serve a um propósito. Então é possível ter um cluster para ter a busca de produtos no seu e-commerce, e outro &lt;code&gt;cluster&lt;/code&gt; guardando os seus logs, por exemplo.&lt;/p&gt;
&lt;h3&gt;
  
  
  Outros termos do Elastic
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Field&lt;/code&gt; é como se fosse uma coluna da tabela do banco relacional. No Json do documento, "nome" é um field e "preco" é outro.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Mapping&lt;/code&gt; é como o schema de um banco de dados relacional. Por exemplo, é o mapping que guarda o tipo de cada Field&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Shard&lt;/code&gt; é um pedaço do seu índice. O elastic por padrão quebra seu índice em vários pedaços e distribui entre os nodes do cluster, daí vem a computação distribuída que mencionei anteriormente.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Arquitetura "básica" da API Restful do elastic
&lt;/h2&gt;

&lt;p&gt;Enquanto outros bancos de dados usam conexão TCP para se comunicar com o cliente, e exigem um driver específico para cada linguagem, o Elastic usa &lt;em&gt;simplesmente&lt;/em&gt; uma API RESTful HTTP. Isso significa que qualquer linguagem com uma lib de requisições HTTP consegue se comunicar facilmente com o elastic (embora existam clients específicos para facilitar esse trabalho também).&lt;/p&gt;

&lt;p&gt;As estruturas básicas de um endpoint do elastic são as seguintes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{url_cluster}/&amp;lt;seu_indice&amp;gt;/&amp;lt;_operação&amp;gt;
// ou
{url_cluster}/&amp;lt;_ação_no_cluster_inteiro&amp;gt;/&amp;lt;_operação&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Geralmente, as operações começam com underscore (&lt;code&gt;_&lt;/code&gt;), tipo &lt;code&gt;_search&lt;/code&gt;, &lt;code&gt;_update&lt;/code&gt;, &lt;code&gt;_delete&lt;/code&gt;, &lt;code&gt;_bulk&lt;/code&gt;, etc. E na maioria dos casos, se você colocar a url do cluster e em seguida um nome sem underscore, como no primeiro exemplo, ele vai inferir que é um índice seu.&lt;/p&gt;

&lt;p&gt;Como a API é RESTful, cada operação tem um verbo HTTP associado.&lt;br&gt;
Para buscar dados, seja buscar documentos ou dados sobre o cluster, você usa o verbo &lt;code&gt;GET&lt;/code&gt;, para criar um novo documento você usa o verbo &lt;code&gt;POST&lt;/code&gt; e assim por diante.&lt;/p&gt;

&lt;p&gt;Alguns exemplos de requisições para essa API são:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Buscar dados de saúde do cluster&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET &lt;span class="s2"&gt;"localhost:9200/_cluster/health"&lt;/span&gt;

&lt;span class="c"&gt;# Atualizar o mapping de um índice&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; PUT &lt;span class="s2"&gt;"localhost:9200/meu_indice/_mapping"&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="s1"&gt;'
{
  "properties": {
    "nome_produto": {
      "type": "text"
    }
  }
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Como o Elastic consegue buscar texto de forma tão rápida?
&lt;/h2&gt;

&lt;p&gt;Como dito anteriormente, o elastic é baseado no Apache Lucene, e o Lucene usa uma técnica chamada &lt;strong&gt;&lt;a href="https://j.blaszyk.me/tech-blog/exploring-apache-lucene-index/#inverted-index"&gt;inverted index&lt;/a&gt;&lt;/strong&gt; para buscar texto de forma eficiente. Um índice invertido é basicamente uma lista de palavras que apontam para os documentos que contém essa palavra. Por exemplo, se você tem o documento de id 1 com o texto "O rato roeu a roupa do rei de Roma", e o outro de id 2 com "O gato comeu a roupa do rato", o índice invertido seria algo como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rato"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"roeu"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"roupa"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rei"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"roma"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"gato"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"comeu"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E quando você busca por "roupa", o elastic vai buscar no índice invertido a palavra "roupa" e vai te retornar os documentos 1 e 2.&lt;/p&gt;

&lt;p&gt;Então, buscando a frase "O rato comeu queijo", ele vai perceber que o documento 2 tem duas palavras da busca ("rato", "comeu"), e vai te retornar o documento 2 com um score maior que o documento 1, pois o documento 1 só tem uma palavra da busca ("rato").&lt;/p&gt;

&lt;p&gt;Por isso o nome é índice &lt;strong&gt;invertido&lt;/strong&gt;, pois ele inverte a lógica de busca. Em vez de buscar palavras em documentos, ele busca documentos em palavras. Isso é simples, mas extremamente eficaz.&lt;/p&gt;

&lt;p&gt;Claro, existem outras otimizações, como usar um &lt;a href="https://www.elastic.co/pt/blog/found-similarity-in-elasticsearch"&gt;Vector Space Model para calcular similiridade entre documentos e o texto buscado&lt;/a&gt;, mas a ideia básica é essa.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Bom, esse foi um resumo básico do que é o Elasticsearch, porque ele foi criado e como ele consegue buscar texto de forma tão eficiente, além de ser um overview de como funciona a API RESTful.&lt;br&gt;
Nos próximos artigos aprenderemos a fazer queries e usaremos o docker para subir um cluster do elastic e uma instância do Kibana, uma ferramenta muito útil para visualizar e interagir com clusters do elastic. Até lá!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>database</category>
      <category>elasticsearch</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Entendendo A Função Reduce - Parte 2</title>
      <dc:creator>Marcus Xavier</dc:creator>
      <pubDate>Tue, 29 Nov 2022 14:48:10 +0000</pubDate>
      <link>https://dev.to/marcusxavierr/entendendo-a-funcao-reduce-parte-2-5608</link>
      <guid>https://dev.to/marcusxavierr/entendendo-a-funcao-reduce-parte-2-5608</guid>
      <description>&lt;p&gt;Eu dei uma relida no artigo sobre reduce que tinha publicado anteriormente, e percebi algumas coisas que eu gostaria de adicionar, vamos lá. Se você não leu o artigo anterior, eu recomendo ler.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tipos de retorno no reduce
&lt;/h2&gt;

&lt;p&gt;O reduce recebe uma lista do tipo &lt;code&gt;X&lt;/code&gt; (onde &lt;code&gt;X&lt;/code&gt; pode ser um objeto, um número, qualquer coisa) e geralmente te retorna um único valor do tipo &lt;code&gt;X&lt;/code&gt;, vamos dizer que isso é do tipo &lt;code&gt;[X] -&amp;gt; X&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Mas isso não é obrigatório. É bem possível que o reduce te retorne um outro tipo (nesse caso seria &lt;code&gt;[X] -&amp;gt; Y&lt;/code&gt;), ou seja, pode receber uma lista de inteiros e retornar uma string ou um objeto, por exemplo.&lt;/p&gt;

&lt;p&gt;Vou exemplificar com código logo abaixo. Aqui eu tenho duas funções. Na primeira eu recebo uma lista de números, e retorno um único numero (que é a soma de todos os valores dessa lista). Isso seria &lt;code&gt;[X] -&amp;gt; X&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Mas na segunda função, eu recebo uma lista de strings e retorno uma lista de objetos, isso seria &lt;code&gt;[X] -&amp;gt; Y&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//Tipo [X] -&amp;gt; X&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;//retorna 10&lt;/span&gt;

&lt;span class="c1"&gt;//Tipo [X] -&amp;gt; Y&lt;/span&gt;
&lt;span class="c1"&gt;//Aqui eu recebo uma lista de pessoas,&lt;/span&gt;
&lt;span class="c1"&gt;//e quero criar uma lista de objetos&lt;/span&gt;
&lt;span class="c1"&gt;//Onde cada pessoa está com o score zerado&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aleatorio&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="c1"&gt;//retorna [ { name: 'nome', score: 0 }, { name: 'aleatorio', score: 0 } ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No Javascript, &lt;strong&gt;geralmente&lt;/strong&gt;, se você chama seu reduce &lt;strong&gt;sem&lt;/strong&gt; passar um valor inicial, ele será do tipo &lt;code&gt;[X] -&amp;gt; X&lt;/code&gt;. Já se você quiser fazer algo do tipo &lt;code&gt;[X] -&amp;gt; Y&lt;/code&gt;, &lt;strong&gt;geralmente&lt;/strong&gt;, terá que passar um valor inicial, que é o segundo parametro da função reduce, logo após a sua função anônima. No exemplo acima eu coloquei um array vazio.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debuggando o reduce
&lt;/h2&gt;

&lt;p&gt;Bom, a ideia aqui é criar um reduce, e ir passo a passo pra ver o que ele está fazendo. Primeiro vou reimplementar a função somador e ver como os valores vão mudando a cada passo, como aconteceria num debugger mesmo. Depois explicarei um exemplo um pouco mais complexo (e útil).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;//isso aqui, na verdade é&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos lá. Se você não passar um valor inicial (como eu não passei), o JS irá pegar o primeiro item do array pra ir pro &lt;code&gt;acc&lt;/code&gt;, e vai começar a rodar a partir do segundo, ou seja, vai colocar o segundo item no &lt;code&gt;value&lt;/code&gt;. Então dando um passo e nosso estado seria isso aqui&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//              1     2        1   +  2 = 3&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O resultado dessa soma irá sobrescrever o valor de acc, que passará a ser 3. Vamos dar mais um passo. Atualmente o nosso &lt;code&gt;acc&lt;/code&gt; é um 3, e o nosso &lt;code&gt;value&lt;/code&gt; irá pegar o valor do próximo item do array. Que por coincidência é um 3 também&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//            3    3         3   +  3 = 6&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;//Agora vamos rodar até a lista esvaziar&lt;/span&gt;

&lt;span class="c1"&gt;//          6    4         6   + 4 = 10&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;//          10   5        10  + 5 = 15&lt;/span&gt;
&lt;span class="p"&gt;[].&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Certo, agora o nosso &lt;code&gt;acc&lt;/code&gt; vale 15, e a nossa lista está vazia, o que acontece agora? Bom, quando a lista está vazia, o reduce simplesmente pega o que está no &lt;code&gt;acc&lt;/code&gt; e retorna para o usuário. É por isso que o exemplo abaixo retorna o valor 1, e não o valor 500.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//Eu vou passar 1 como valor inicial para a minha função.&lt;/span&gt;
&lt;span class="c1"&gt;//ou seja, o acc começará valendo 1&lt;/span&gt;
&lt;span class="c1"&gt;//Mas como a minha lista está vazia, o código return 500 nem rodará,&lt;/span&gt;
&lt;span class="c1"&gt;//o reduce vai retornar 1 logo&lt;/span&gt;
&lt;span class="p"&gt;[].&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;//retorna 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Resolvendo um problema possivelmente real
&lt;/h2&gt;

&lt;p&gt;Bom, agora vem o "debugging" mais complexo que citei anteriormente. Imaginemos que você recebe uma lista de objetos que representam a pontuação dos usuários, e você quer definir qual usuário ganhou. Existem várias formas de resolver esse problema, e uma delas é o reduce.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scores&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Huguinho&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Zezinho&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Luizinho&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora que nós temos a lista de pontuações, é só rodar no nosso reduce&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;previousValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;actualValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;actualValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;previousValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;actualValue&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;previousValue&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como eu não quero "acumular" um valor nesse caso, eu preferi chamar o meu primeiro parâmetro como "previousValue" (valorAnterior) e o segundo como "actualValue" (valoarAtual).&lt;/p&gt;

&lt;p&gt;A ideia aqui é basicamente olhar se o meu &lt;code&gt;actualValue&lt;/code&gt; tem um score maior que o &lt;code&gt;previousValue&lt;/code&gt;, se ele tiver, eu retorno o &lt;code&gt;actualValue&lt;/code&gt;, sobrescrevendo o que tem no &lt;code&gt;previousValue&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Agora, caso o score do meu &lt;code&gt;previousValue&lt;/code&gt; seja maior ou igual ao do meu &lt;code&gt;actualValue&lt;/code&gt; eu retorno o &lt;code&gt;previousValue&lt;/code&gt;, ou seja, eu basicamente estou deixando o mesmo valor que tinha no &lt;code&gt;previousValue&lt;/code&gt;. Não estou tratando o caso de empate aqui.&lt;/p&gt;

&lt;p&gt;Coloquei esse else pra deixar claro que retorna um ou outro, nesse caso ele é opcional.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//Vamos dar o primeiro passo então&lt;/span&gt;
&lt;span class="c1"&gt;//como não passei valor inicial o reduce faz o mesmo esquema de antes&lt;/span&gt;
&lt;span class="c1"&gt;//que é pegar o primeiro item e colocar no acumulador (valor anterior),&lt;/span&gt;
&lt;span class="c1"&gt;//e botar o segundo item no valor atual&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scores&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Huguinho&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Zezinho&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Luizinho&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;

&lt;span class="c1"&gt;//                              {name: 'Huguinho'...} {name: 'Zezinho'...}&lt;/span&gt;
&lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Luizinho&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;}].&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;previousValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;actualValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;//                 25     &amp;gt;              20 é true&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;actualValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;previousValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;actualValue&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;previousValue&lt;/span&gt;
    &lt;span class="c1"&gt;//retorno o meu actualValue (pontuação do zezinho)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como o score do meu valor atual é &lt;strong&gt;maior&lt;/strong&gt; do que o do valor anterior, eu retorno o meu valor atual, sobrescrevendo o &lt;code&gt;previousValue&lt;/code&gt; com ele. Agora o nosso próximo passo está assim.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//   {name: 'Zezinho'...} {name: 'Luizinho'...}&lt;/span&gt;
&lt;span class="p"&gt;[].&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;previousValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;actualValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;//                 15     &amp;gt;              25 é false&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;actualValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;previousValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;actualValue&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;previousValue&lt;/span&gt;
    &lt;span class="c1"&gt;//retorno o previousValue (pontuação do zezinho)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E como o meu valor atual não tem um score maior do que o anterior, vamos retornar o valor anterior para ser salvo no nosso acumulador (ou &lt;code&gt;previousValue&lt;/code&gt; nesse caso), basicamente deixando do mesmo jeito que estava.&lt;/p&gt;

&lt;p&gt;O reduce irá rodar novamente e verá que a lista está vazia, aí ele simplesmente retornará o que tiver no meu acumulador. E nesse caso isso é a pontuação do zezinho. &lt;code&gt;{ name: 'Zezinho', score: 25}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Se você quiser tirar a prova, abra o node ou o console do navegador e rode o código completo abaixo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scores&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;huguinho&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zezinho&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;luizinho&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;

&lt;span class="nx"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;previousValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;actualValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;actualValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;previousValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;actualValue&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;previousValue&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Bom, esse artigo serviu mais para explicar melhor como o reduce computa os valores da lista e reduz um &lt;code&gt;[X]&lt;/code&gt; em outra coisa como um &lt;code&gt;X&lt;/code&gt; ou um &lt;code&gt;Y&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ainda existem muitas coisas para serem abordadas, por exemplo: como map e filter são derivados do reduce, como é uma recursão por trás do reduce, como usar os outros dois parâmetros da função interna do reduce que nós ainda não usamos.&lt;/p&gt;

&lt;p&gt;Mas por hoje ficamos por aqui. Eu posso abordar esses temas em artigos futuros.&lt;/p&gt;

</description>
      <category>showdev</category>
    </item>
    <item>
      <title>Clean Code: Classes</title>
      <dc:creator>Marcus Xavier</dc:creator>
      <pubDate>Mon, 28 Nov 2022 12:51:44 +0000</pubDate>
      <link>https://dev.to/marcusxavierr/clean-code-classes-4ea3</link>
      <guid>https://dev.to/marcusxavierr/clean-code-classes-4ea3</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Classes deveriam ser pequenas, deveriam fazer somente uma coisa e deveriam ter somente um motivo para mudar&lt;/p&gt;

&lt;h2&gt;
  
  
  Classes deveriam ser pequenas
&lt;/h2&gt;

&lt;p&gt;Existe um milhão de motivos para odiar classes grandes: o código fica com aspecto de bagunçado, existem literalmente dezenas de métodos que podem fuçar em todos os atributos da classe, o que aumenta a chance de algum erro passar despercebido, e também é uma porcaria se "mover" na classe, você pula pra um método privado da classe, e vai pra 1000 linhas abaixo de onde você estava.&lt;/p&gt;

&lt;p&gt;Já as "classes pequenas", por outro lado, são mais simples de manter, pois elas não fazem muitas coisas então a preocupação de causar um efeito colateral ao mudando algo é menor. Em geral, quando você bate o olho no nome de um "Classe pequena" já é possível ter uma ideia do que ela faz (se o nome for bom, obviamente).&lt;/p&gt;

&lt;p&gt;"Classes pequenas", também são mais fáceis de testar, pois elas costumam a ser menos acopladas com coisas externas, isso significa menos mocks no teste, o que é sempre bom 😀.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mas o que raios é uma "Classe Pequena"?
&lt;/h2&gt;

&lt;p&gt;Acho que isso foi o suficiente pra mostrar que classes gigantes são uma merda geralmente. E agora vem a próxima pergunta: como eu defino o que é uma classe pequena?&lt;br&gt;
Muitas pessoas vão lembrar do capitulo sobre funções e pensar que também é possível definir se a classe é pequena ou não, se baseando na sua quantidade de linhas (seu tamanho), mas isso não poderia estar mais incorreto.&lt;/p&gt;

&lt;p&gt;Usar a quantidade de linhas para classificar uma classe seria muito vago, e por isso o uncle bob nos recomenda pensar no bom e velho S do SOLID (Principio da Responsabilidade Única).&lt;/p&gt;

&lt;p&gt;A ideia aqui é, ao invés de contar a quantidade de linhas para ver se a classe é pequena, nós iremos contar a quantidade de "responsabilidades" que a classe possui. Se tiver mais do que uma responsabilidade, geralmente é hora de dividir essa classe em classes menores.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ok, e como eu sei se a minha classe tem mais de uma responsabilidade?
&lt;/h2&gt;

&lt;p&gt;Bom, o uncle bob também apresenta algumas formas bem interessantes de verificar isso.&lt;/p&gt;

&lt;p&gt;A primeira forma é, na hora de criar o nome da classe, tentar dar um nome descritivo para ela. Se você tentar e não conseguir criar um nome descritivo, e ao mesmo conciso, &lt;strong&gt;pode&lt;/strong&gt; ser que a classe tenha mais de uma responsabilidade.&lt;/p&gt;

&lt;p&gt;Outra forma de ver isso é tentar escrever uma pequena descrição de uma 25 palavras explicando por cima o que a classe faz. Se você usar palavras como &lt;em&gt;"mas"&lt;/em&gt;, &lt;em&gt;"se"&lt;/em&gt;, &lt;em&gt;"e"&lt;/em&gt;, &lt;em&gt;"ou"&lt;/em&gt;, também &lt;strong&gt;pode&lt;/strong&gt; ser que a sua classe tenha mais de uma responsabilidade. Aqui vai um exemplo do livro:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"A &lt;code&gt;SuperDashBoard&lt;/code&gt; provê acesso ao último componente utilizado &lt;strong&gt;e&lt;/strong&gt; também nos permite acompanhas [metadados como] o número da versão e build."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;E por fim você pode pensar "motivos para mudar", ao invés de "responsabilidades". Pense, &lt;em&gt;"em quais situações, ou por quais motivos, eu teria de mudar o código dessa classe?"&lt;/em&gt;. Se existir mais de um motivo para mudar, está bem claro que a sua classe tem mais de uma "responsabilidade" ou "razão para existir".&lt;/p&gt;

&lt;h2&gt;
  
  
  O que você prefere?
&lt;/h2&gt;

&lt;p&gt;Eu já vi pessoas reclamando de que dividir seu sistema classes pequenas acaba gerando PRs maiores do que simplesmente fazer do modo "quick and dirty", tudo dentro de uma classe. &lt;/p&gt;

&lt;p&gt;Outras pessoas também podem argumentar que ter uma sistema repleto de arquivos de classes é mais complexo de gerenciar. Mas o autor do livro argumenta que a complexidade do sistema não tende a mudar muito por causa disso, e deixa a seguinte reflexão.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Você prefere as suas ferramentas organizadas em armários repletos de pequenas gavetas, cada uma contendo componentes bem definidos e bem nomeados? Ou prefere umas poucas gavetas onde você joga tudo lá?"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Clean Code: Testes</title>
      <dc:creator>Marcus Xavier</dc:creator>
      <pubDate>Wed, 16 Nov 2022 13:52:21 +0000</pubDate>
      <link>https://dev.to/marcusxavierr/clean-code-testes-4545</link>
      <guid>https://dev.to/marcusxavierr/clean-code-testes-4545</guid>
      <description>&lt;p&gt;Falar que testes são importantes pra mantenabilidade do código é chover no molhado, mas é sempre bom ter em mente que nem todo teste trás tanto benefício assim. &lt;/p&gt;

&lt;p&gt;Testes que quebram o tempo todo, são difíceis de estender e complicados de entender, são mais prejudiciais do que benéficos para a sua codebase, e o autor explica o porquê nesse trecho.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Ter testes 'sujos' é o equivalente ou até mesmo pior do que não ter testes. O problema é que testes precisam ser modificados enquanto o código de produção evolui e quanto mais os seus testes forem 'sujos', mas difícil será mudar eles."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  O que faz um teste ser "limpo"? Legibilidade, Legibilidade, Legibilidade
&lt;/h2&gt;

&lt;p&gt;Segundo o autor, a legibilidade talvez seja até mesmo mais importante no código dos testes do que o código de produção. Testes legíveis têm &lt;strong&gt;clareza&lt;/strong&gt;, &lt;strong&gt;simplicidade&lt;/strong&gt; e &lt;strong&gt;densidade de expressão&lt;/strong&gt;. O dois primeiro pontos são meio óbvios, e o terceiro significa que os seus testes precisam expressar o máximo de informação usando o mínimo de linhas possíveis. O que nos leva pra segunda dica.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pode ser boa ideia tentar minimizar a quantidade de assertions nos seus testes
&lt;/h2&gt;

&lt;p&gt;E isso não quer dizer que você precise deixar de testar algum caso, simplesmente significa que é sempre bom tentar abstrair as suas assertions. Se você der um nome descritivo para a função que está abstraindo as suas assertions, isso pode até mesmo ajudar o leitor a entender a intenção do seu código.&lt;/p&gt;

&lt;p&gt;Vou mostrar um exemplo abaixo de um código Go que eu fiz para testar quando o usuário fazia uma requisição http para pegar a definição de uma palavra. &lt;/p&gt;

&lt;p&gt;É bom lembrar que em Go, nós fazemos "assertions" usando um &lt;code&gt;if&lt;/code&gt; mesmo, e não chamando um &lt;code&gt;assertEquals&lt;/code&gt; da vida. Então considere cada &lt;code&gt;if&lt;/code&gt; como uma asserção no código.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestGetDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"User retrieve word definition successfully"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;makeFakeServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wordDefinition&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;GetDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;createResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"To shrink, cower, tense or recoil, as in fear, disgust or embarrassment."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"He cringed as the bird collided with the window."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"cringe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;reflect&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DeepEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"got %v want %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Normalize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Word&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"normalized word from response %v shouldn't be empty"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"word dont exists"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;makeFakeServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I dont know"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;GetDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotFoundError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"got %q want %q"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotFoundError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eu não considero esse código de teste como o ideal, por que ele não tem muita &lt;strong&gt;densidade de expressão&lt;/strong&gt;, ou seja, ele não passa a sua ideia de forma enxuta e isso obriga o leitor a ler bem mais coisa do que ele deveria. Nós podemos refatorar o teste para ficar dessa forma.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestGetDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"User retrieve word definition successfully"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;makeFakeServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wordDefinition&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;GetDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;createResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"To shrink, cower, tense or recoil, as in fear, disgust or embarrassment."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"He cringed as the bird collided with the window."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"cringe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;checkSuccessResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"word dont exists"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;makeFakeServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I dont know"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;GetDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;checkFailResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotFoundError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;//Meus testes acabaram, daqui pra baixo só temos funções auxiliares&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;checkSuccessResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;want&lt;/span&gt; &lt;span class="n"&gt;DictionaryApiResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Helper&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;reflect&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DeepEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;want&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"got %v want %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;want&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Normalize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Word&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"normalized word from response %v shouldn't be empty"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;checkFailResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;want&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Helper&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;want&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"got %q want %q"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;want&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse exemplo acima, eu "diminuí" a quantidade de assertions por teste simplesmente abstraindo a checagem das responses. Os testes ainda têm a mesma cobertura, mas o código dos testes ficou mais simples e enxuto. O número de linhas desse arquivo pode ter aumentado, mas a parte mais importante (o código que testa) está menor.&lt;/p&gt;

&lt;p&gt;Claro, é sempre bom lembrar de ter bom senso, eu não acho uma boa ideia criar um milhão de funções auxiliares só para que seus testes tenham uma única assertion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cada teste deveria testar um único conceito
&lt;/h2&gt;

&lt;p&gt;Nós não queremos um teste enorme que testa vários cenários, esses tipos de testes podem ser mais práticos de escrever, mas costumam ser bem chatas de manter, por que se esse teste quebrar, você pode precisar ter de debuggar o teste inteiro, o que irá te dar muito mais trabalho do que debuggar um código menor que testa somente um conceito.&lt;/p&gt;

&lt;p&gt;Pegue como exemplo o código acima, se nós misturássemos todos os testes em um único teste, a própria Legibilidade desse teste ficaria comprometida, mesmo que os dois testes mostrados acima sejam bem simples.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Bons testes tem uma boa legibilidade. Testes ruins mais atrapalham do que ajudam, pois eles tendem a ser bem mais difíceis de modificar à medida que o sistema evolui.&lt;/p&gt;

&lt;p&gt;Abstrair as assertions dos seus testes &lt;strong&gt;pode&lt;/strong&gt; ser uma boa ideia, mas é importante ter bom senso. Não misture conceitos diferentes no mesmo teste, se você está testando o caso de sucesso em um teste, é melhor criar um novo teste para testar o caso de exceção do que testar tudo no mesmo teste.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Clean Code: Formatação</title>
      <dc:creator>Marcus Xavier</dc:creator>
      <pubDate>Sat, 12 Nov 2022 16:33:55 +0000</pubDate>
      <link>https://dev.to/marcusxavierr/clean-code-formatacao-26hd</link>
      <guid>https://dev.to/marcusxavierr/clean-code-formatacao-26hd</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;A primeira impressão que tive sobre o capítulo sobre formatação é que ele só teria obviedades, afinal, formatar código não tem muito segredo, mas eu vi algumas provocações interessantes que gostaria de compartilhar.&lt;/p&gt;

&lt;p&gt;Por exemplo, se eu perguntasse que código funcionando é a coisa mais importante no trabalho de um Programador, a grande maioria das pessoas diria que sim. E o uncle bob no começo do capítulo lança uma provocação e diz que isso não é verdade.&lt;/p&gt;

&lt;p&gt;Segundo o autor, comunicação eficiente (o que engloba uma formatação de código eficiente) é o principal trabalho de um desenvolvedor. E com "comunicação" eu entendo que ele também engloba código legível e fácil de manter. O Uncle bob expressa muito bem esse ideia nesse parágrafo abaixo.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"as funcionalidades que você cria hoje têm uma boa chance de serem alteradas na próxima release, mas a legibilidade do seu código vai ter um profundo efeito em todas as mudanças que estarão por vir. &lt;strong&gt;Estilo de código&lt;/strong&gt; e &lt;strong&gt;Legibilidade&lt;/strong&gt; setam precedentes que continuarão a afetar a mantenabilidade e extensibilidade do código muito depois do código original ser modificado a ponto de ser tornar irreconhecível. &lt;strong&gt;Seu estilo e disciplina sobrevivem, mesmo que seu código não&lt;/strong&gt;"&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Antes de mais nada, a melhor formatação tende a ser aquela que a equipe inteira segue
&lt;/h2&gt;

&lt;p&gt;Uma das primeiras coisas que o autor menciona nesse capítulo é que você deveria escolher algumas regras simples em conjunto com a sua equipe e todos seguirem essas regras. Parece bobo, mas padronizar esse tipo de coisa deixa o código mais uniforme e constante.&lt;/p&gt;

&lt;p&gt;E em pleno 2022 você não precisa nem se preocupar em formatar seu código, existem inúmeras ferramentas (como o prettier por exemplo) que formatam seu código com base em algumas regras pré definidas.&lt;/p&gt;

&lt;p&gt;Por isso também, é sempre bom procurar seguir convenções das linguagens e frameworks. Se todo mundo usa snake_case em python, por que você usaria camelCase?&lt;/p&gt;

&lt;h2&gt;
  
  
  Cada "bloco" de código deveria funcionar da mesma forma que um parágrafo
&lt;/h2&gt;

&lt;p&gt;Em um texto bem escrito, geralmente o ideal é que cada parágrafo represente uma ideia. Ou seja, ideias diferentes, ao longo do texto você vai desenvolvendo suas ideias, e vai separando elas em parágrafos, pois assim você terá um texto bem formatado naturalmente, ao invés de ter um bloco enorme de palavras que é péssimo de ler.&lt;/p&gt;

&lt;p&gt;A mesma ideia se aplica à código. Eu sei que algumas pessoas não gostam de colocar espaços em branco no código, mas eu tenho uma opinião forte (e o autor corrobora com a minha opinião) de que "blocos" de código deveriam representar alguma "coisa", e "coisas" diferentes deveriam estar em blocos separados.&lt;/p&gt;

&lt;p&gt;Por exemplo:&lt;/p&gt;

&lt;h3&gt;
  
  
  Versão com tudo junto
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;ignoreUserThreads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;threads&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getThreads&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;threads&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;needIgnoreThisUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getAuthorName&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;display: none;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getAuthorName&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data-author&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;muteBlacklist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;threads&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getThreads&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;threads&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;thread&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;threadTitleIsBlacklisted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;display: none;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getThreads&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.js-threadList&amp;gt;.structItem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.structItem-title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Versão com código separado
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;ignoreUserThreads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;threads&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getThreads&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="nx"&gt;threads&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;needIgnoreThisUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getAuthorName&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;display: none;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getAuthorName&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data-author&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;muteBlacklist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;threads&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getThreads&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="nx"&gt;threads&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;threadTitleIsBlacklisted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;display: none;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getThreads&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.js-threadList&amp;gt;.structItem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.structItem-title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O que você prefere? Eu particularmente prefiro a segunda opção&lt;/p&gt;

&lt;h2&gt;
  
  
  Seja gente fina com o leitor do código, tente colocar coisas relacionadas o mais perto possível
&lt;/h2&gt;

&lt;p&gt;Uma das coisas que eu mais detesto é ter que ficar indo pra cima e pra baixo no código pra entender o que está acontecendo nele. E uma das formas de mitigar isso é deixando códigos que se relacionam, o mais próximo um do outro.&lt;/p&gt;

&lt;p&gt;Eu particularmente gosto de ler código de cima pra baixo, como se fosse um texto mesmo, então se a função &lt;em&gt;A&lt;/em&gt; chama a função &lt;em&gt;B&lt;/em&gt;, eu sempre tento deixar a função &lt;em&gt;A&lt;/em&gt; em algum lugar por cima da função &lt;em&gt;B&lt;/em&gt;, e nunca o contrário. Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;#do something
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claro que nem sempre isso é possível por N questões, mas é sempre bom tentar fazer isso pra facilitar a vida do leitor 😁.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Geralmente é melhor seguir um estilo de código já definido do que inventar moda. Baixe um formatador de código automático (como o prettier ou phpcbf, por exemplo).&lt;/p&gt;

&lt;p&gt;Separe os os seus blocos de código com espaços, a leitura desse artigo ficaria péssima se não tivesse espaços separando os blocos de texto, por que você acha que seria diferente com o seu código?&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Clean Code: Fazendo bom uso das funções | Parte 2</title>
      <dc:creator>Marcus Xavier</dc:creator>
      <pubDate>Sat, 12 Nov 2022 14:41:25 +0000</pubDate>
      <link>https://dev.to/marcusxavierr/clean-code-fazendo-bom-uso-das-funcoes-parte-2-4ok7</link>
      <guid>https://dev.to/marcusxavierr/clean-code-fazendo-bom-uso-das-funcoes-parte-2-4ok7</guid>
      <description>&lt;p&gt;Esse artigo é a continuação do tema "funções", por favor leia a parte 1 primeiro.&lt;/p&gt;

&lt;h2&gt;
  
  
  Um nível de abstração por função
&lt;/h2&gt;

&lt;p&gt;Para garantir que a nossa função faz somente &lt;strong&gt;uma&lt;/strong&gt; coisa, nós precisamos ter certeza que os pedaços de código dentro da função estão no mesmo nível de abstração. &lt;/p&gt;

&lt;p&gt;O que eu quero dizer com isso é que se uma parte da sua função está cuidando de coisas bem abstratas, não faz muito sentido misturar isso com detalhes de implementação logo abaixo. Vou mostrar um trecho de código para clarificar isso.&lt;/p&gt;

&lt;p&gt;Esse método abaixo faz parte de uma classe que tem como responsabilidade buscar dados do usuário. Essa função em específico precisa pegar a primeira venda do usuário.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;getFirstOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;cachedOrder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                   &lt;span class="s2"&gt;`orders.userId`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;reply&lt;/span&gt;
                  &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;cachedOrder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cachedOrder&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getFirstOrderInDB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No código acima eu tento pegar o pedido no cache, se não tiver no cache eu pego o valor do banco de dados. No começo eu fiz algo como um nível muito baixo de abstração que no caso foi chamar o &lt;code&gt;client.get&lt;/code&gt; e logo no fim da função eu chamei a função &lt;code&gt;getFirstOrderInDB&lt;/code&gt; que é algo muito mais abstraído. &lt;/p&gt;

&lt;p&gt;Um código assim não fica muito bom, na minha opinião, porque estamos fazendo algo com pouca abstração num cenário onde poderia ter muito mais abstração.&lt;br&gt;
Olhe agora o exemplo abaixo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;getFirstOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;cachedOrder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getOrderFromCache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;cachedOrder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cachedOrder&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getFirstOrderInDB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Não mudou praticamente nada, só a busca no cache que foi abstraída. Essa simples mudança deixou o código mais limpo e simples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Escreva código para ser lido de cima pra baixo
&lt;/h2&gt;

&lt;p&gt;Eu gosto bastante dessa dica e tento sempre seguir ela. Me surpreende isso ser uma coisa tão pouco debatida. A ideia é você escrever o seu código com muita abstração no começo do arquivo, e a parte do código menos abstraída (ou seja, as funções que foram chamadas pelas funções no topo do arquivo) devem ficar mais abaixo no arquivo.&lt;/p&gt;

&lt;p&gt;Por exemplo, no trecho de código anterior a função &lt;code&gt;getFirstOrder&lt;/code&gt; é mais abstraída, logo deveria ficar mais acima. Já as funções &lt;code&gt;getOrderFromCache&lt;/code&gt; e&lt;code&gt;getFirstOrderInDB&lt;/code&gt; devem ficar no final do arquivo por que estão em um nível mais baixo de abstração (talvez essas duas últimas funções podem até mesmo ser métodos privados).&lt;/p&gt;

&lt;h2&gt;
  
  
  Use nomes descritivos
&lt;/h2&gt;

&lt;p&gt;O seus nomes precisam descrever o que a função faz, por isso é bom ter funções pequenas e que fazem somente uma coisa. Bons nomes são tão importantes que esse foi assunto do primeiro artigo dessa série de posts, você pode conferir lá ótimas dicas para escolher bons nomes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cuidado ao passar booleanos como parâmetro da sua função
&lt;/h2&gt;

&lt;p&gt;Nessa parte o autor diz que passar booleanos como parâmetro para a sua função pode ser um sinal de que a sua função faz mais de uma coisa, pois ela pode fazer uma coisa se o parâmetro for &lt;code&gt;true&lt;/code&gt; e outra coisa caso seja &lt;code&gt;false&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Claro, nem sempre é possível evitar isso, mas caso você tenha uma situação com a citada acima, pode ser interessante fazer uma função para caso determinado valor seja &lt;code&gt;true&lt;/code&gt; e outra para caso seja &lt;code&gt;false&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Você deve evitar códigos como o abaixo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CompanyRepository&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateOrUpdate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Company&lt;/span&gt; &lt;span class="n"&gt;company&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="p"&gt;...&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="p"&gt;...&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E preferir fazer códigos como esse aqui&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CompanyRepository&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Company&lt;/span&gt; &lt;span class="n"&gt;company&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Company&lt;/span&gt; &lt;span class="n"&gt;company&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Error Handling é uma coisa
&lt;/h2&gt;

&lt;p&gt;Lembra que no mundo ideal cada função faria somente uma coisa? então, error Handling é uma coisa. Segundo o autor, se a sua função tem um bloco de try catch ou algo do tipo, não deveria haver nada além disso. Ao invés de abrir o bloco try e colocar um monte de código nele, você deveria pegar todo o código dentro do try e colocá-lo em uma nova função.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Ufa, finalmente terminamos de cobrir o capítulo sobre funções. Esse capítulo nem é tão grande, mas como ele é cheio de pérolas interessantes sobre como escrever funções "melhores", eu não quis deixar ele muito resumido.&lt;/p&gt;

&lt;p&gt;É sempre bom lembrar que nem mesmo o autor do livro escreve funções boas logo de cara (ele fala sobre isso no final do capítulo), a ideia é primeiramente fazer algo que funciona, depois se preocupar em fazer o seu código seguir as boas práticas citadas acima.&lt;/p&gt;

&lt;p&gt;E pra finalizar esse artigo, deixo um insight do uncle bob que achei bem interessante.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"&lt;strong&gt;Programadores experientes veem os sistemas como histórias a serem contadas&lt;/strong&gt; em vez de programas a serem escritos.[...]Mas jamais se esqueça de que &lt;strong&gt;seu objetivo verdadeiro é contar a história do sistema&lt;/strong&gt;, e que as funções que você escrever precisam estar em perfeita sincronia e formar uma linguagem clara e precisa para lhe ajudar nessa narração"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>braziliandevs</category>
      <category>programming</category>
    </item>
    <item>
      <title>Clean Code: Fazendo bom uso das funções | Parte 1</title>
      <dc:creator>Marcus Xavier</dc:creator>
      <pubDate>Sun, 25 Sep 2022 15:25:54 +0000</pubDate>
      <link>https://dev.to/marcusxavierr/clean-code-fazendo-bom-uso-das-funcoes-parte-1-375j</link>
      <guid>https://dev.to/marcusxavierr/clean-code-fazendo-bom-uso-das-funcoes-parte-1-375j</guid>
      <description>&lt;p&gt;Parafraseando o próprio uncle bob, funções são a primeira linha de organização de qualquer programa. Ou seja, na maioria das linguagens, uma função (ou método) é a "menor" forma de organizar seu código.&lt;/p&gt;

&lt;p&gt;Você pode ter classes, interfaces e tudo mais, mas dentro disso tudo estarão funções mantendo sua codebase organizada. Ou bagunçada, depende de como você as usa. Eu diria que essa é uma das partes mais importantes dessa série de artigos justamente por isso.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pequenas!
&lt;/h2&gt;

&lt;p&gt;Aqui o autor diz que funções deveriam ser pequenas, e eu concordo totalmente com isso. Raramente existe um motivo plausível para que as suas funções tenham mais do que vinte e cinco linhas. Nessa seção do livro, o uncle bob é mais extremista e diz que uma função pequena tem por volta de &lt;strong&gt;quatro&lt;/strong&gt; linhas.&lt;/p&gt;

&lt;p&gt;Você pode pensar que ele enlouqueceu, mas em algumas linguagens como haskell é até comum ver uma codebase inteira composta em sua maioria por minúsculas funções de quatro ou cinco linhas.&lt;/p&gt;

&lt;p&gt;O código fica muito mais organizado e bonito dessa forma, na minha opinião. O problema é que muitas vezes acabamos o código de forma apressada e damos muitas responsabilidades pra mesma função. Não tem problema fazer isso, contanto que limpe o seu código depois. &lt;/p&gt;

&lt;p&gt;Praticamente todo editor hoje em dia fornece a opção de selecionar um bloco de código e extrair uma função (ou seja, pegar esse bloco e automaticamente jogar numa nova função). Trate de configurar essa opção no seu editor pra ontem, é &lt;strong&gt;muito&lt;/strong&gt; útil pra refatorar o código.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nada de Hadouken, por favor
&lt;/h2&gt;

&lt;p&gt;O autor sugere que as suas funções tenham somente um ou dois níveis de identação no máximo, ou seja, você deveria ao máximo evitar aninhados. Sério, se tem um if aninhado no seu código, ele muito provavelmente poderia ser abstraído em uma nova função.&lt;/p&gt;

&lt;p&gt;Outra dica polêmica do uncle bob, da qual eu gosto bastante, é que deveria ter somente &lt;strong&gt;uma&lt;/strong&gt; linha de código em blocos como &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;else&lt;/code&gt;, &lt;code&gt;while&lt;/code&gt;, etc. Eu acho essa dica um pouco extrema em algumas situações, mas se estiver um monte de coisa acontecendo dentro do seu &lt;code&gt;if&lt;/code&gt;, isso provavelmente deveria ser abstraído dentro de um novo método (lembra que as suas funções deveriam ser pequenas? 🙃).&lt;/p&gt;

&lt;h2&gt;
  
  
  Faça somente uma coisa, e faça direito
&lt;/h2&gt;

&lt;p&gt;Fazer uma função que faz mais de uma coisa fere tantas "boas práticas" que é até difícil de listar todas, mas os principais problemas de ter uma função "multitarefa" são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fere o princípio de responsabilidade única do SOLID&lt;/li&gt;
&lt;li&gt;Como a função faz várias coisas, fica muito mais difícil dar um nome descritivo pra ela&lt;/li&gt;
&lt;li&gt;Muito provavelmente não será uma função pequena&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Essa dica de criar funções que fazem somente uma coisa já é algo extremamente antiga, desenvolvedores muito inteligentes já aplicavam isso nos anos 70. No desenvolvimento do Unix o programadores fizeram ferramentas que &lt;strong&gt;faziam somente uma coisa, mas faziam direito&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Por exemplo, o comando &lt;code&gt;history&lt;/code&gt; serve para mostrar o seu histórico de comandos rodados no terminal. O comando &lt;code&gt;grep&lt;/code&gt; pode ser usado para filtrar texto.&lt;br&gt;
E pronto, caso eu queira ver todos os comandos do git que eu rodei no terminal, basta rodar o comando &lt;code&gt;history&lt;/code&gt; combinado com o &lt;code&gt;grep&lt;/code&gt; pra filtrar o resultado e me mostrar somente os comandos que contenham a palavra &lt;code&gt;git&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Mas nós temos um problema, escrever funções que fazem somente uma coisa (e fazem isso direito), não costuma ser uma tarefa trivial. Pode ser complicado dizer se a sua função é multitarefa ou não.&lt;/p&gt;

&lt;p&gt;O exemplo abaixo é uma função de um CLI meu que salva palavras em inglês que o usuário não conhece (para poder adicioná-las no anki depois), e dá ao usuário a opção de printar a definição dessa palavras desconhecida no terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;cobra&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Flags&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetBool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"definition"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;sentence&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;getSentenceFromArgs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"https://api.dictionaryapi.dev/api/v2/entries/en/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;sentence&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;dictionary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotFoundError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrintRed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stdout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"word not found on dictionary api&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;PrettyPrintDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Normalize&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;saveSentence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sentence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse função é multitarefa? Parece ser, não é? E se nós abstrairmos o código dentro desse &lt;code&gt;if&lt;/code&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;cobra&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Flags&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetBool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"definition"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;sentence&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;getSentenceFromArgs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sentence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;saveSentence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sentence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;printDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sentence&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"https://api.dictionaryapi.dev/api/v2/entries/en/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;sentence&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;dictionary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotFoundError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrintRed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stdout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"word not found on dictionary api&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;PrettyPrintDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Normalize&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Será que agora a função faz somente uma coisa? Bom, vamos listar o que a nossa função está fazendo.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pegando os dados que o usuário passa, e ver se o usuário passou a flag &lt;code&gt;definition&lt;/code&gt; no comando, para ver no terminal a definição da palavra que ele está adicionando&lt;/li&gt;
&lt;li&gt;verificar se o usuário quer ver a definição da palavra, caso ele queira, printar isso na tela.&lt;/li&gt;
&lt;li&gt;salvar a sentença que o usuário está adicionando para estudar no anki mais tarde.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Bom, como podemos ver, o nosso código ainda está "fazendo" três, será que nós conseguimos abstrair esse código ainda mais pra que ele faça somente &lt;strong&gt;uma&lt;/strong&gt; coisa? Vamos ver&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;cobra&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// finalmente a minha função faz SOMENTE uma coisa&lt;/span&gt;
    &lt;span class="n"&gt;saveSentenceAndPrintDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Mas espera, agora eu gerei uma função com assinatura igual à anterior&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;saveSentenceAndPrintDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;cobra&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Esse código está exatamente igual antes, agora somente mudou de lugar&lt;/span&gt;
    &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Flags&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetBool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"definition"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;sentence&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;getSentenceFromArgs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sentence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;saveSentence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sentence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;printDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sentence&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"https://api.dictionaryapi.dev/api/v2/entries/en/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;sentence&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;dictionary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotFoundError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrintRed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stdout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"word not found on dictionary api&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;PrettyPrintDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Normalize&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Viram? Existe um ponto onde &lt;strong&gt;não&lt;/strong&gt; vale mais a pena ficar extraindo métodos da sua função principal para que ela fique "menos multitarefa". Depois de certo ponto você está simplesmente jogando o código para outro canto, sem melhorar em nada a sua legibilidade e mantenabilidade.&lt;/p&gt;

&lt;p&gt;Ou seja, uma boa forma de saber se seu código chegou no "ponto certo" e está seguindo a regra do &lt;em&gt;"Faça somente uma coisa"&lt;/em&gt; é ver se mais uma extração de função irá melhorar seu código ou se irá simplesmente pegar o seu código atual e jogá-lo em outro canto, como aconteceu no nosso último exemplo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Eu pretendia fazer somente um artigo para abordar o bom uso da função, mas as funções são tão importante para a programação, que existem inúmeras boas práticas e dicas para se fazer um excelente código com elas. Colocar tudo em um único artigo deixaria ele enorme.&lt;/p&gt;

&lt;p&gt;Por isso pretendo fazer mais um ou dois artigos abordando mais dicas para escrever boas funções, como por exemplo, evitar efeitos colaterais e evitar receber um milhão de parâmetros.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Entendendo A Função Reduce - Parte 1</title>
      <dc:creator>Marcus Xavier</dc:creator>
      <pubDate>Sun, 18 Sep 2022 20:24:16 +0000</pubDate>
      <link>https://dev.to/marcusxavierr/brincando-com-a-funcao-reduce-4kjl</link>
      <guid>https://dev.to/marcusxavierr/brincando-com-a-funcao-reduce-4kjl</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Faz um tempo que eu não escrevo nenhum blogpost. Nesse período eu andei estudando haskell e achei uma função que bem interessante chamada &lt;strong&gt;fold&lt;/strong&gt;, mas essa função é mais conhecida como &lt;strong&gt;reduce&lt;/strong&gt;. O que faz essa função ser bem interessante é o fato de que ela contém bastante informação em pouquíssimas linhas de código.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementando um simples problema
&lt;/h2&gt;

&lt;p&gt;Só pra mostrar um pouco do que o reduce é capaz de fazer, vamos imaginar um problema hipotético: &lt;em&gt;Você recebe uma lista de compras que um cliente fez, e precisa somar todos os valores dessa lista.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Aviso
&lt;/h3&gt;

&lt;p&gt;Muitas linguagens fornecem funções pra somar os valores de uma lista, mas vamos implementar a nossa própria função só por questões didáticas.&lt;/p&gt;

&lt;p&gt;Primeiro eu vou implementar essa função no bom e velho PHP escrevendo sem usar reduce, só com um foreach mesmo.&lt;/p&gt;

&lt;p&gt;Depois vou implementar usando Javascript e reduce, e por fim vou mostrar como seria essa função em haskell&lt;/p&gt;

&lt;h4&gt;
  
  
  Versão no PHP
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Crio uma lista simples só pra poder testar depois&lt;/span&gt;
&lt;span class="nv"&gt;$array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;//Aqui vou fazer um foreach simples e somar os valores do meu array&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;sumArrayValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$array&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$value&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nv"&gt;$item&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;sumArrayValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$lista&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;//Output: 55&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Versão JS com reduce
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//Crio a lista&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;lista&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;//Sim, a função só tem uma linha&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;somador&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acumulador&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acumulador&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt;
&lt;span class="nx"&gt;lista&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;somador&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// Output: 55&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Versão em haskell
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;lista&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;-- Cria uma lista de 1 até 10&lt;/span&gt;
&lt;span class="n"&gt;foldl&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;acumulador&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;acumulador&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;lista&lt;/span&gt;
&lt;span class="c1"&gt;-- Output: 55&lt;/span&gt;
&lt;span class="c1"&gt;-- Ou então nós poderíamos ter feito isso aqui que daria o mesmo resultado&lt;/span&gt;
&lt;span class="n"&gt;foldl&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;lista&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como você pode ver, o reduce torna seu código muito menos verboso, e na minha opinião, esse jeito minimalista e declarativo é bem elegante, mas creio que seja justamente por isso que a função &lt;strong&gt;fold&lt;/strong&gt; (mais conhecida como &lt;strong&gt;reduce&lt;/strong&gt;) seja tão incompreendida.&lt;/p&gt;

&lt;p&gt;Tendo isso em vista, vamos então entender com calma o que a função reduce está fazendo por baixo dos panos.&lt;br&gt;
Pra entender como o reduce funciona, nós vamos implementar a nossa própria versão dele, da forma mais explicita possível.&lt;/p&gt;
&lt;h2&gt;
  
  
  Implementando nosso próprio reduce
&lt;/h2&gt;

&lt;p&gt;Vou usar javascript, mas funcionaria com praticamente qualquer linguagem.&lt;br&gt;
Aqui está a definição original do array.reduce&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;initialValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mas como os parâmetros &lt;code&gt;currentIndex&lt;/code&gt; e &lt;code&gt;arr&lt;/code&gt; são opcionais, vou fazer uma definição mais simples para explicar de forma mais didática.&lt;/p&gt;

&lt;p&gt;Obs: O parâmetro initialValue também é opcional, mas eu considero ele importante demais para omitirmos na nossa implementação&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acumulador&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentValue&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;initialValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;//mas vamos criar uma função que recebe o array como ultimo parâmetro&lt;/span&gt;
&lt;span class="nx"&gt;meuReduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acumulador&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;valorAtual&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;valorInicial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lista&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos implementar logo a nossa versão simplificada do reduce&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;meuReduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;funcaoAnonima&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;acumulador&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lista&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// No reduce eu basicamente vou percorrer a minha lista e ir salvando no meu acumulador&lt;/span&gt;
    &lt;span class="c1"&gt;// o resultado da minha função anônima&lt;/span&gt;
    &lt;span class="c1"&gt;// Eu usei um for, mas poderia ser feito usando recursão também.&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;lista&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//Aqui o meu acumulador vai receber o resultado da computação da minha função anônima&lt;/span&gt;
        &lt;span class="c1"&gt;// Veja que eu estou usando "=" e não "+=".&lt;/span&gt;
        &lt;span class="c1"&gt;// Por isso estou passando o meu acumulador pra minha função&lt;/span&gt;
        &lt;span class="c1"&gt;// A ideia é como se ele estivesse sendo incrementado&lt;/span&gt;
        &lt;span class="nx"&gt;acumulador&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;funcaoAnonima&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acumulador&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lista&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;//Por fim eu simplesmente retorno o meu acumulador&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;acumulador&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E se eu chamar a minha nova função, tudo deve funcionar&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//Se você quiser, pode copiar o codigo acima e esse aqui e colar no console do navegador pra ver o resultado também&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;somador&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acumulador&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acumulador&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;multiplicador&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acumulador&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acumulador&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dobra_array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acumulador&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;acumulador&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//Aqui o meu valor inicial precisa ser um array vazio&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;acumulador&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;lista&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nx"&gt;meuReduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;somador&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lista&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// Output: 55&lt;/span&gt;

&lt;span class="nx"&gt;meuReduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;multiplicador&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lista&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//o valor inicial precisa ser 1, pois se for 0 vai zerar a multiplição&lt;/span&gt;
&lt;span class="c1"&gt;// Output: 3628800&lt;/span&gt;

&lt;span class="nx"&gt;meuReduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dobra_array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nx"&gt;lista&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// Output: [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]&lt;/span&gt;

&lt;span class="c1"&gt;//Se você fizer lista.reduce(dobra_array, []) o resultado será o mesmo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sim, eu diria que uma das principais funções do reduce é pegar uma lista de itens e retornar um único item. Como nas duas primeiras funções onde nós pegávamos umas lista de inteiros e &lt;strong&gt;REDUZÍAMOS&lt;/strong&gt; a lista a somente um inteiro.&lt;/p&gt;

&lt;p&gt;Mas também é possível que nosso reduce receba uma lista e retorne outra lista. Basta que o valor inicial seja um array vazio, para que o acumulador consiga usar a função push para colocar itens dentro de si.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recapitulando
&lt;/h2&gt;

&lt;p&gt;Bom, esse artigo já está ficando grande demais, então vamos somente recapitular o que aprendemos antes de finalizar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O reduce (mais conhecido como fold em algumas linguagens) é uma função que pode fazer muitas coisas com poucas linhas de código&lt;/li&gt;
&lt;li&gt;A função reduce é bastante usada para pegar uma lista de valores e &lt;strong&gt;reduzir&lt;/strong&gt; essa lista a somente um item.&lt;/li&gt;
&lt;li&gt;O reduce recebe uma função anônima que será aplicada ao acumulador e a cada item da sua lista, recebe um valor inicial para o acumulador, e recebe a própria lista&lt;/li&gt;
&lt;li&gt;A função anônima deve receber como parâmetro, no mínimo o seu acumulador e o item atual da sua lista (lembre-se que a função vai ser chamada dentro de um loop que vai varrer toda a sua lista). Além desses dois itens obrigatórios algumas linguagens te permitem colocar mais parâmetros na sua função anônima, mas esses são opcionais.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E é isso pessoal. Foi bom escrever um pouco sobre essa função que é bem confusa de se entender quando vemos ela pela primeira vez.&lt;/p&gt;

</description>
      <category>functional</category>
      <category>javascript</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Clean Code: Escolhendo bons nomes</title>
      <dc:creator>Marcus Xavier</dc:creator>
      <pubDate>Sun, 18 Sep 2022 01:17:49 +0000</pubDate>
      <link>https://dev.to/marcusxavierr/clean-code-escolhendo-bons-nomes-feb</link>
      <guid>https://dev.to/marcusxavierr/clean-code-escolhendo-bons-nomes-feb</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Clean code é provavelmente um dos livros mais famosos do desenvolvimento de software, provavelmente todo desenvolvedor já ouviu o nome desse livro.&lt;/p&gt;

&lt;p&gt;A ideia dessa série de artigos é servir como um pequeno resumo pessoal sobre o que vi no livro. Eu achei vários insights interessantes enquanto lia e anotei eles para que eu pudesse revisar, mas senti que anotações soltas com zero contexto não são muito boas pra revisar.&lt;/p&gt;

&lt;p&gt;Por isso pretendo não só compartilhar esses insights, mas também divagar sobre cada uma das dicas apresentadas e colocar um pouco de código pra contextualizar o que está sendo dito.&lt;/p&gt;

&lt;p&gt;É sempre bom deixar claro que o livro Clean Code não é nenhum magnum opus da computação e nem tem pretensão de ser. O próprio autor do livro deixa bem claro que não se deve levar a ferro e fogo 100% do que é dito no livro. Então não vamos desapontar o uncle bob, ok 😉?&lt;/p&gt;

&lt;h2&gt;
  
  
  Use nomes que revelam a intenção do código
&lt;/h2&gt;

&lt;p&gt;Segundo o autor do livro, excelentes nomes são capazes de responder perguntas como essas aqui abaixo.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Por que a classe "X" existe?&lt;/li&gt;
&lt;li&gt;Qual é a finalidade da função "Y"?&lt;/li&gt;
&lt;li&gt;O teste "A" testa o que exatamente?&lt;/li&gt;
&lt;li&gt;Eu consigo imaginar com um pouco de precisão a aparência do componente "Z" só com base no nome dele?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E eu concordo bastante com essa visão. Excelentes nomes te dão um certo contexto geral do que está acontecendo no código e isso pode poupar bastante tempo de leitura.&lt;/p&gt;

&lt;p&gt;O problema é que criar excelentes nomes é uma tarefa bem difícil, raramente me vem à mente o nome perfeito quando estou codificando, principalmente se eu não tiver uma visão clara do que o código deve fazer.&lt;/p&gt;

&lt;p&gt;Felizmente, hoje em dia quase todo editor te dá a possibilidade de renomear coisas no código de forma extremamente simples e rápida. Então, se você ainda não usa isso no seu editor, trate de configurar essa funcionalidade pra ontem. E se você tiver uma boa cobertura de testes, mudar o nome de algo é mais seguro ainda.&lt;/p&gt;

&lt;p&gt;Pra mostrar outro exemplo real disso, vou pegar um trecho de código em Go de um projeto pessoal meu.&lt;br&gt;
Eu troquei os nomes das funções e parâmetros que estou usando num trecho de código. Você consegue entender com facilidade o que está se passando no código abaixo?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;sentence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;testItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Red&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"sentence '%s' already exists on file %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;testItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, vamos para o código original. Leia novamente o trecho de código.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;CheckIfSentenceExists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sentence&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filePathList&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;filePathList&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;hasSentence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sentence&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Red&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"sentence '%s' already exists on file %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sentence&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;hasSentence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sentence&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filePath&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ReadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;verifyIsSentenceExists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sentence&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Os nomes mais descritivos ajudam mesmo a entender o funcionamento do código com o mínimo de contexto possível, não é?&lt;/p&gt;

&lt;p&gt;Confesso que não acho esse trecho de código o mais legível que eu já escrevi, mas com uma boa nomenclatura de métodos (e claro, &lt;strong&gt;testes&lt;/strong&gt;) eu consigo entender facilmente o que o código deveria fazer, mesmo depois de um tempo sem tocar no projeto.&lt;/p&gt;

&lt;p&gt;Enfim, sempre que possível veja se seus nomes estão respondendo perguntas como as mencionadas mais acima.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use e abuse de enums, constantes e afins
&lt;/h2&gt;

&lt;p&gt;Muitas vezes nos vemos na situação em que precisamos usar um valor hardcoded no nosso código, tipo, o nosso valor não vai mudar e só vamos usá-lo em algum lugar, logo bate a vontade de simplesmente colocar o valor que você quer e pronto.&lt;br&gt;
Quando surgir uma situação parecida, coloque esse valor dentro de uma constante ou variável, ou então se você estiver mexendo com números crus que representam algo além de um simples número, use um Enum ou algo parecido que é fornecido na sua linguagem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;IgnoreVideos&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;videos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selector&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

   &lt;span class="nx"&gt;videos&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelectoAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selector&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Duas coisas podem ser feitas para melhorar &lt;strong&gt;muito&lt;/strong&gt; a clareza do código. Nós poderíamos jogar aquele valor do parseInt numa variável que indica o que é o valor sendo guardado, e podemos usar um const para guardar aquele número 1000 hardcoded.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;IgnoreVideos&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;videos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selector&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

   &lt;span class="nx"&gt;videos&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MINIMUM_VIEWS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;numberOfViews&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelectoAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selector&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;numberOfViews&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;MINIMUM_VIEWS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa mudança não foi nada de extraordinário e sendo sincero eu nem achei que o nome da constante seja bom, mas o simples fato de adicionar nome a coisas que antes eram só um monte de código já trouxe muito mais clareza pra esse trecho de código.&lt;/p&gt;

&lt;p&gt;Outra melhoria seria jogar esse código que pega o número de views em uma função, pois além de tirar esse &lt;code&gt;innerText.replace&lt;/code&gt; feio da nossa frente, também tornaria o código reaproveitável e nós poderíamos escolher um bom nome pra essa função, deixando ainda mais claro o que o nosso código faz.&lt;/p&gt;

&lt;h2&gt;
  
  
  Procure nomear variáveis com nomes que indicam o que está sendo mensurado e a sua unidade
&lt;/h2&gt;

&lt;p&gt;Imagine que eu preciso criar uma variável para guardar o número de dias que a minha entrega demorou pra chegar dos correios. Eu poderia usar uma variável chamada &lt;code&gt;days&lt;/code&gt;, é um nome OK, mas podemos achar um nome melhor ainda.&lt;br&gt;
Para descobrir qual nome usar, vamos responder as duas perguntas abaixo.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;O que essa variável está guardando?&lt;/p&gt;

&lt;p&gt;R: O número de dias decorridos desde que eu fiz o meu pedido.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Qual é a "unidade" dessa variável, ou seja, que tipo de valor eu estou guardando e qual é a sua ordem de grandeza?&lt;/p&gt;

&lt;p&gt;R: Aqui quando eu digo "tipo" não estou me referindo se o valor é uma string ou um int, mas sim qual a ordem de grandeza do meu valor salvo, ou seja, esse tempo decorrido está sendo mensurado em dias, segundos ou milissegundos? Informar isso é importante para evitar confusões futuras (usar um valor em milissegundos achando que eram dias, por exemplo). Enfim, eu quero guardar o tempo decorrido em &lt;strong&gt;dias&lt;/strong&gt;, então a unidade da minha variável é um dia.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Pronto, com essas duas informações fica mais simples decidir um nome para nossa variável: Por que ao invés de usar o nome &lt;code&gt;days&lt;/code&gt;, nós não usamos o nome &lt;code&gt;elapsedTimeInDays&lt;/code&gt;? É um nome que descreve o que nós guardamos (&lt;code&gt;elapsedTime&lt;/code&gt; (Tempo decorrido)) e salva a unidade desse tempo que são dias.&lt;/p&gt;

&lt;p&gt;Caso eu precisasse fazer uma variável para guardar quanto tempo eu consegui ficar sem respirar, uma boa opção de nome seria &lt;code&gt;elapsedTimeInSeconds&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Se possível, use nomes que são "buscáveis"
&lt;/h2&gt;

&lt;p&gt;Não sei quanto a você, mas eu busco nomes no meu código o tempo inteiro, seja porque eu tenho uma rota e quero descobrir qual Controller é usado por ela, ou então pra achar onde uma função é usada. &lt;/p&gt;

&lt;p&gt;O problema é que quando o nome é genérico demais, fica péssimo de fazer buscas assim no código porque você vai receber vários resultados inúteis para sua busca, simplesmente porque existem várias coisas no código com um nome parecido com o nome buscado.&lt;/p&gt;

&lt;p&gt;Uma boa forma de resolver isso é evitar ao máximo usar nomes genéricos no código. Um exemplo de nome genérico seria a variável &lt;code&gt;days&lt;/code&gt; do trecho acima. &lt;/p&gt;

&lt;p&gt;Evite também usar variáveis de uma só letra porque buscar por essa variável depois será como procurar agulha no palheiro. A única situação onde que acho plausível usar uma variável com esse tipo de nome é dentro de um for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Bom, esse artigo já está ficando um pouco grande então vamos parar por aqui. O tema de nomes é algo extremamente importante para o desenvolvimento de software, não é atoa que esse tema é abordado logo no segundo capitulo do livro, e por isso eu acho importante que praticar dar bons nomes às coisas no seu código, e ter sempre à mão alguma ferramenta para refatorar código e trocar o nome de algo sem muita dor de cabeça (testes pra garantir que nada foi quebrado são sempre bem vindos).&lt;/p&gt;

&lt;p&gt;No próximo artigo eu pretendo abordar o assunto de funções. Em minha humilde opinião a função é a unidade de código mais importante em um software. Fazendo o bom uso das funções seu código tende a ser organizado e fácil de manter, não importando qual paradigma você está usando.&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>Guia fundamental da programação orientada a objetos - Final</title>
      <dc:creator>Marcus Xavier</dc:creator>
      <pubDate>Sat, 16 Apr 2022 18:57:54 +0000</pubDate>
      <link>https://dev.to/marcusxavierr/guia-fundamental-da-programacao-orientada-a-objetos-final-1h18</link>
      <guid>https://dev.to/marcusxavierr/guia-fundamental-da-programacao-orientada-a-objetos-final-1h18</guid>
      <description>&lt;p&gt;Agora que nós já vimos os pilares da POO e a sua importância, está na hora de abordar mais alguns aspectos importantes de orientação a objetos neste último artigo. Vamos falar um pouco sobre classes abstratas, interfaces e classes finais (conhecida como classe selada em algumas linguagens).&lt;/p&gt;

&lt;h2&gt;
  
  
  O que são classes abstratas?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tL60ARai--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/59l8s16n32mccql3g3q7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tL60ARai--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/59l8s16n32mccql3g3q7.png" alt="Image description" width="359" height="276"&gt;&lt;/a&gt;&lt;br&gt;
Elas são classes que não podem ser instanciadas. Ou seja, você não pode criar objetos a partir de uma classe abstrata. Aí você pode pensar: “Mas pra que serve uma classe que não pode virar objeto?”. Bom, você ainda pode fazer herança com uma classe abstrata, e é aí que vem a grande utilidade delas. Imaginemos que eu queira implementar algumas classes de Pagamento. Uma pra pagamento via cartão de crédito, outra para pagamento com boleto, e por fim uma para pagamento via pix. &lt;/p&gt;

&lt;p&gt;Muitas coisas nessas três formas de pagamento são bem parecidas, não? Sempre existe uma pessoa que paga, um horário em que o pagamento e também o seu valor. Essas informações podem, e devem ser &lt;strong&gt;abstraídas&lt;/strong&gt;, não faz o menor sentido ficar repetindo coisas atoa. &lt;/p&gt;

&lt;p&gt;E é aí que nós podemos criar uma classe &lt;strong&gt;PagamentoBase&lt;/strong&gt; que não vai ser capaz de realizar um pagamento, mas terá a responsabilidade de guardar essas partes comuns a todos os tipos de pagamento.&lt;/p&gt;

&lt;p&gt;E não faz o menor sentido criar uma instância de &lt;strong&gt;PagamentoBase&lt;/strong&gt;, já que ele não é uma classe responsável por fazer o pagamento em si, mas para abstrair ao máximo coisas para as outras classes usarem. Então nesse caso, nós podemos marcar essa classe como sendo abstrata, então será &lt;strong&gt;impossível&lt;/strong&gt; de criar um objeto a partir de PagamentoBase. &lt;/p&gt;

&lt;p&gt;Claro, classes abstratas também podem ter outras responsabilidades dependendo de como você as implementa, mas na minha visão, a principal função delas é abstrair coisas para que outras classes “normais” consigam usar e se beneficiar, aumentando a reusabilidade do código. &lt;/p&gt;

&lt;p&gt;Além disso, lembre-se que também é possível sobrescrever os métodos da nossa classe abstrata, então, por exemplo, eu posso sobrescrever o método de notificar o usuário quando o pagamento é feito com sucesso.&lt;/p&gt;

&lt;p&gt;Abaixo implemento o exemplo citado nos parágrafos anteriores.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PagamentoBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="nv"&gt;$valor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;DateTime&lt;/span&gt; &lt;span class="nv"&gt;$dataPagamento&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;//etc...&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;notificarUsuarioSobrePagamento&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//imagine uma implementação&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;//Temos mais metodos abaixo que estão invisiveis...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PagamentoViaCartao&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;PagamentoBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$numeroCartao&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;//etc...&lt;/span&gt;

    &lt;span class="c1"&gt;//imagine que tem alguns métodos aqui&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PagamentoViaBoleto&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;PagamentoBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//Imagine que eu implementei alguns metodos aqui também&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PagamentoViaPix&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;PagamentoBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;notificarUsuarioSobrePagamento&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//A implementação é diferente pois como o pix é instantaneo&lt;/span&gt;
        &lt;span class="c1"&gt;//eu preciso enviar essa notificação o mais rápido possivel.&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;//temos mais metodos e atributos nessa classe...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  O que são interfaces?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pJ980nBb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kbj6h0bhawkudys94dgo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pJ980nBb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kbj6h0bhawkudys94dgo.png" alt="Image description" width="505" height="379"&gt;&lt;/a&gt;&lt;br&gt;
A primeira coisa que você precisa ter em mente é que interface &lt;strong&gt;NÃO&lt;/strong&gt; são classes, logo é &lt;strong&gt;impossível&lt;/strong&gt; instanciar objetos a partir da interface. Mas você pode pensar, “se eu não consigo criar objetos a partir de interfaces, como que eu vou usar elas no meu código?”, e eu vou te responder que interfaces são usadas como se fossem &lt;strong&gt;”contratos”&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Quando você assina um contrato, você é &lt;strong&gt;obrigado&lt;/strong&gt; pela lei a cumprir o que está escrito no contrato. Ou seja, o contrato é uma forma de &lt;strong&gt;garantir&lt;/strong&gt; que tu cumpra o que prometeu cumprir. Interfaces funcionam de forma parecida. &lt;/p&gt;

&lt;p&gt;Digamos que eu tenha uma classe &lt;strong&gt;Carro&lt;/strong&gt;, e uma classe &lt;strong&gt;Moto&lt;/strong&gt;, e você concorda comigo que todo veículo precisa andar para ser útil, não é mesmo? Então, nessa situação, se essas classes não tiverem um método andar(), elas serão inúteis pra mim, pois um veículo que não anda é inútil.&lt;/p&gt;

&lt;p&gt;E é justamente nesse cenário que as interfaces aparecem pra salvar o dia, eu posso criar uma interface chamada &lt;strong&gt;“ContratoVeiculo”&lt;/strong&gt; e lá colocar o método andar(). Logo após isso eu faço a minha classe implementar essa interface. Isso vai fazer com que essa classe seja &lt;strong&gt;obrigada&lt;/strong&gt; a implementar os métodos definidos na interface. &lt;/p&gt;

&lt;p&gt;A interface não tem a obrigação de dizer como um método deve funcionar (e nem pode fazer isso), por isso em interfaces nós não implementamos o método, apenas escrevemos a assinatura do método, ou seja, escrevemos o seu nome, quais parâmetros ele recebe, e qual o tipo do retorno desse método. &lt;/p&gt;

&lt;p&gt;É &lt;strong&gt;obrigação&lt;/strong&gt; da classe que implementa esse interface dizer como vai ser toda a lógica do meu método, mas esse método precisa respeitar a assinatura da interface, então ele precisa receber os mesmos tipos de parâmetros e retornar o tipo de valor definido na interface.&lt;/p&gt;

&lt;p&gt;A vantagem em ter essa abordagem (interfaces serem proibidas de ditar o funcionamento dos métodos) é que eu vou poder usar a mesma interface para classes diferentes, que terão lógicas de funcionamento diferentes. Como você já deve saber, carros e motos andam de formas diferentes, mas como a minha interface &lt;strong&gt;ContratoVeiculo&lt;/strong&gt; é “agnóstica”, eu consigo usar ela tanto na classe &lt;strong&gt;Carro&lt;/strong&gt; quanto na classe &lt;strong&gt;Moto&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Abaixo eu mostro um trecho de código PHP que implementa essas classes e interface citados acima.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ContratoVeiculo&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;andar&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="c1"&gt;//Aqui eu digo que quero uma função chamada andar&lt;/span&gt;
   &lt;span class="c1"&gt;//que não recebe nenhum parametro e retorna void&lt;/span&gt;
   &lt;span class="c1"&gt;//Ou seja, não retorna nada&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Carro&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ContratoVeiculo&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;//Imagine que temos varios atributos&lt;/span&gt;
   &lt;span class="c1"&gt;//e varios metodos aqui&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;andar&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"O carro está andando&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Moto&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ContratoVeiculo&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;//Imagine que temos varios atributos&lt;/span&gt;
   &lt;span class="c1"&gt;//e varios metodos aqui&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;andar&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Andando como uma moto&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  E o que são classes seladas?
&lt;/h2&gt;

&lt;p&gt;E por fim, vamos falar um pouco sobre as classes finais, ou classes seladas, o nome varia de acordo com a linguagem de programação que você estiver usando (em PHP e Java é classe final e no C# é classe selada).&lt;br&gt;
Lembra que as classes abstratas não podem ser instanciadas, mas podiam ser herdadas? Com as classes finais acontece o oposto, elas podem ser instanciadas, mas não podem ser herdadas.&lt;/p&gt;

&lt;p&gt;A razão para se usar uma classe desse tipo é que a herança também tem o seu ônus, e pode ser que em algum caso especifico você quer evitar que algum outro programador extenda a sua classe. Deixo abaixo a &lt;a href="https://pt.stackoverflow.com/a/227216"&gt;opinião de um usuário do stackoverflow&lt;/a&gt; sobre o assunto.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“É uma forma de dizer que esta classe não pode ser herdada, o que costuma ser uma boa ideia. Desenvolver classes preparadas para serem herdadas é muito mais difícil, a manutenção seguinte se torna um fardo. Acho até que o padrão deveria ser a classe não herdável.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Abaixo deixo um exemplo de classe final no PHP.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CarroGenerico&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$quilometragem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;ligar&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="c1"&gt;//logica para ligar o carro&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ToyotaCorolla&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;CarroGenerico&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;//implementa coisas especificas de um Corolla&lt;/span&gt;
   &lt;span class="c1"&gt;//A ideia aqui, é que chegamos na nossa classe final&lt;/span&gt;
   &lt;span class="c1"&gt;//Não faz muito sentido extender um Corolla&lt;/span&gt;
   &lt;span class="c1"&gt;//pois ele já é o produto FINAL&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Bom, com esse artigo nós cobrimos todas as partes que eu considero fundamentais para que você comece a usar a orientação a objetos. Existem muitas coisas que não foram cobertas nessa série e que estão relacionadas com POO, como por exemplo funções amigas e generics. Mas falar disso fugiria um pouco da finalidade dessa série, que é cobrir os fundamentos. Vejo vocês em próximos artigos! :)&lt;/p&gt;

</description>
      <category>oop</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Guia fundamental da programação orientada a objetos - Parte 2 | Os pilares</title>
      <dc:creator>Marcus Xavier</dc:creator>
      <pubDate>Thu, 10 Feb 2022 19:05:56 +0000</pubDate>
      <link>https://dev.to/marcusxavierr/guia-fundamental-da-programacao-orientada-a-objetos-parte-2-os-pilares-1b5i</link>
      <guid>https://dev.to/marcusxavierr/guia-fundamental-da-programacao-orientada-a-objetos-parte-2-os-pilares-1b5i</guid>
      <description>&lt;p&gt;É impossível falar de programação orientada a objetos sem citar seus famosos quatro pilares. Seguir esses pilares é muito importante para que você possa conseguir todos os maravilhosos benefícios da POO. No artigo de hoje eu vou falar exclusivamente sobre esses pilares, e sempre que pertinente vou exemplificar com código e imagens. &lt;br&gt;
Seria ótimo que você deixasse seu feedback nos comentários.&lt;/p&gt;
&lt;h2&gt;
  
  
  Quais são os pilares da POO?
&lt;/h2&gt;

&lt;p&gt;A POO possui alguns pilares que devem ser seguidos para que possamos começar a obter os benefícios oferecidos por esse paradigma da maneira mais correta possível.&lt;/p&gt;
&lt;h3&gt;
  
  
  Encapsulamento
&lt;/h3&gt;

&lt;p&gt;Basicamente é o pilar que te permite deixar seu código mais isolado do resto, então quando você baixa uma lib no seu projeto e usa um objeto dessa lib com vários métodos úteis você não preciso fuçar na classe dela, já vem tudo encapsulado certinho pra você usar, só precisa chamar as funções desse objeto e deixar a mágica acontecer sem se preocupar se o seu código vai bugar o código da lib, porque se ela estiver encapsulada isso não vai acontecer.&lt;/p&gt;

&lt;p&gt;Vou usar uma pilha como exemplo. Dentro da pilha tem vários elementos químicos, que poderiam danificar sua pele, por esse motivo nós colocamos eles dentro de uma &lt;strong&gt;cápsula&lt;/strong&gt;, que tem dois terminais. &lt;br&gt;
Então essa &lt;strong&gt;cápsula&lt;/strong&gt; tem o único objetivo de te proteger da pilha, e ao mesmo tempo proteger a pilha de você, pois você poderia danificar a pilha caso ficasse tocando no catodo dela. &lt;br&gt;
Essa &lt;strong&gt;cápsula&lt;/strong&gt; da pilha só expõe o necessário dela (que são os terminais negativo e positivo) e esconde todo o resto. &lt;strong&gt;Encapsulamento&lt;/strong&gt; na POO é exatamente isso.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzbdo67wdtqj5c3lghe32.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzbdo67wdtqj5c3lghe32.jpg" alt="Desenho de pilha partida ao meio"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Herança
&lt;/h3&gt;

&lt;p&gt;É o pilar que te permite reutilizar o seu código, fazendo uma classe reaproveitar o código de outra classe, como um filho que herda os genes dos pais, então a classe que herda é a &lt;strong&gt;classe filha (child class)&lt;/strong&gt;, e a classe que serve como base na herança é a &lt;strong&gt;classe mãe (parent class)&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Vamos imaginar que você está escrevendo um programa para realizar cobranças de um e-commerce. E nesse caso você vai aceitar pagamento por cartão de crédito, boleto e pix. É possível perceber que parte dos pagamentos vão ser iguais (todos tem um valor, informações do usuário, etc), e têm partes que são diferentes (boleto tem data de vencimento e pagamento por cartão não tem). &lt;/p&gt;

&lt;p&gt;Então ao invés de escrever o código do zero pros três tipos de pagamento, ou escrever tudo junto, de forma bagunçada, nós podemos criar uma classe mais genérica, chamada pagamento, e classes para os pagamentos com cartão de crédito, boleto e pix, fazendo essas classes herdarem a genérica, reaproveitando código.&lt;/p&gt;

&lt;p&gt;Abaixo vou deixar uma imagem como exemplo e um trecho de código.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frgyn49pqpctmd63mhjzh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frgyn49pqpctmd63mhjzh.png" alt="Herança exemplo"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pagamento&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;NomeDoPagador&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;FoiPago&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="c1"&gt;//… mais várias propriedades aqui&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PagamentoCartaoCredito&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Pagamento&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;//Eu ainda tenho as propriedades do Pagamento aqui&lt;/span&gt;
   &lt;span class="c1"&gt;// ou seja, posso acessar o Id, e o nome do pagador&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;NumeroCartao&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;VerificarCartao&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="c1"&gt;//verificando o cartão&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PagamentoBoleto&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Pagamento&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;//Eu ainda tenho as propriedades do Pagamento aqui&lt;/span&gt;
   &lt;span class="c1"&gt;// ou seja, posso acessar o Id, e o nome do pagador&lt;/span&gt;

   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;vencimento&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;VerificarSeVenceu&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="c1"&gt;//verificando se o boleto não venceu&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Abstração
&lt;/h3&gt;

&lt;p&gt;O pilar da abstração vai deixar seu código o mais simples possível. Vamos imaginar que você precisa escrever o código de cadastro de alunos em uma escola, logo você irá precisar criar uma classe do tipo pessoa, mas uma pessoa tem milhares de características e pode realizar milhões de ações diferentes. &lt;/p&gt;

&lt;p&gt;Então, pra evitar que a sua classe fique com 10000 linhas usamos o conceito de abstração, que é focar somente nas características e ações importantes no contexto do programa.&lt;/p&gt;

&lt;p&gt;Para uma escola, a altura, peso ou cor da pele de um aluno não faz a menor diferença, mas é importante saber as notas desse aluno e o seu nome, então focaremos somente nas últimas características. A mesma ideia se aplica na hora de escolher quais ações representar usando os métodos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Aluno&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;//Aqui vou focar somente no essenssial&lt;/span&gt;
   &lt;span class="c1"&gt;//Um aluno é uma pessoa, logo tem centenas&lt;/span&gt;
   &lt;span class="c1"&gt;//de caracteristicas, mas vou focar em somente três&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Idade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;Notas&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="c1"&gt;//Isso acima é um vetor de notas&lt;/span&gt;
   &lt;span class="c1"&gt;//Ou seja, varias notas juntas na mesma estrutura&lt;/span&gt;

   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Aprovar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Reprovar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Polimorfismo
&lt;/h3&gt;

&lt;p&gt;Polimorfismo quer dizer &lt;strong&gt;“muitas formas”&lt;/strong&gt;, e é exatamente isso que você entendeu, os métodos das classes podem ter muitas formas. Eu vou explicar de forma mais detalhada logo logo, mas preciso falar primeiro que existe mais de um tipo de polimorfismo. Nesse artigo vou focar nos dois principais, a &lt;strong&gt;sobrescrita&lt;/strong&gt; e &lt;strong&gt;sobrecarga&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  &amp;gt;Sobrescrita
&lt;/h4&gt;

&lt;p&gt;Como o próprio nome já diz, sobrescrita é uma forma de escrever por cima de algo que já existe, e no nosso contexto, é a habilidade de uma classe filha para &lt;strong&gt;modificar o comportamento&lt;/strong&gt; de um método (função) da classe mãe. A vantagem disso é poder reutilizar toda parte útil da nossa classe mãe, mas ao mesmo tempo ter a capacidade de alterar as partes que nós desejamos alterar por qualquer motivo que seja. &lt;/p&gt;

&lt;p&gt;Isso é literalmente o melhor dos dois mundos, pois economizamos código escrito e também temos total flexibilidade para deixar nossas classes filhas do jeito que queremos. Abaixo vou mostrar um trecho de código onde faz sentido esse tipo de polimorfismo. &lt;/p&gt;

&lt;p&gt;Eu tenho uma classe &lt;strong&gt;Mamífero&lt;/strong&gt;, e você vai concordar comigo que todos (ou quase todos) os mamíferos emitem som, não é mesmo? Então, por isso criamos um método &lt;strong&gt;Falar()&lt;/strong&gt; nessa nossa classe. Mas, caso eu crie um &lt;strong&gt;Cachorro&lt;/strong&gt; e um &lt;strong&gt;Gato&lt;/strong&gt; a partir dessa classe &lt;strong&gt;Mamífero&lt;/strong&gt;, eu vou precisar modificar esse método &lt;strong&gt;Falar()&lt;/strong&gt;, pois como todos sabemos, cachorros e gatos “falam” de formas diferentes, um late e outro mia.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Mamifero&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;

   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Especie&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Idade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Falar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Fala genérica de um animal"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
       &lt;span class="c1"&gt;// printa Fala genérica de um animal na tela&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Gato&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Mamifero&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Falar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Miau"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
       &lt;span class="c1"&gt;// printa Miau na tela&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cachorro&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Mamifero&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Falar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Au au"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
       &lt;span class="c1"&gt;//printa au au na tela&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &amp;gt;Sobrecarga de métodos
&lt;/h4&gt;

&lt;p&gt;Esse é um conceito que te permite criar variações de um mesmo método, ou seja, você pode ter vários métodos com nomes iguais dentro de uma mesma classe, realizando ações diferentes. Pode ter ficado confuso, mas eu vou mostrar agora uma situação onde a sobrecarga pode ser útil, é um exemplo bem bobo, mas vai tornar esse conceito mais claro pra você.&lt;/p&gt;

&lt;p&gt;Imagina que vamos criar uma classe &lt;strong&gt;Calculadora&lt;/strong&gt;, e ela tem um método de &lt;strong&gt;Somar()&lt;/strong&gt;. O que esse método faz é basicamente pegar dois inteiros e retornar a soma deles&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Calculadora&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;Somar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mas se eu quiser somar 3 números, como eu faço? Caso eu modifique esse método acima, todos os meus trechos de código que usavam essa função vão quebrar, pois eles só estavam somando dois números, e a função passou a querer somar três números.&lt;/p&gt;

&lt;p&gt;E é nesse momento que a sobrecarga vem salvar o dia. Eu tenho a opção de simplesmente criar outro método chamado &lt;strong&gt;Somar&lt;/strong&gt;, que recebe três números, e o C# é inteligente o suficiente pra saber quando ele chama o método que recebe dois parâmetros, e quando chamar o método que recebe três.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Calculadora&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;Somar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="c1"&gt;// Novo método&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;Somar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você vai ver isso bastante em métodos “nativos” do .NET Core (uma plataforma de desenvolvimento que usa o C#), a sobrecarga de métodos (mais conhecida como &lt;strong&gt;overload&lt;/strong&gt;) é algo extremamente comum nessa plataforma.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;No artigo de hoje nós vimos o coração da orientação a objetos: os seus famosos pilares. Entender bem esses conceitos é fundamental para aplicar bem a POO em problemas reais do dia a dia, por isso recomendo salvar esse texto para ler futuramente de novo depois que você tiver mais experiência programando nesse paradigma. &lt;/p&gt;

&lt;p&gt;No próximo artigo veremos mais conceitos importantes da POO, como classes abstratas, interfaces, classes “seladas” e se sobrar tempo vou mostrar como os métodos GET e SET do C# podem ser escritos de forma elegante e enxuta.&lt;/p&gt;

</description>
      <category>oop</category>
      <category>braziliandevs</category>
      <category>csharp</category>
    </item>
  </channel>
</rss>
