<?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: Terminal Coffee</title>
    <description>The latest articles on DEV Community by Terminal Coffee (@terminalcoffee).</description>
    <link>https://dev.to/terminalcoffee</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%2F1031236%2Fc67a4968-9e95-4228-884e-9d070d5b319b.jpeg</url>
      <title>DEV Community: Terminal Coffee</title>
      <link>https://dev.to/terminalcoffee</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/terminalcoffee"/>
    <language>en</language>
    <item>
      <title>HTML é uma linguagem de programação - ou pelo menos está mais perto disso do que você imagina</title>
      <dc:creator>Terminal Coffee</dc:creator>
      <pubDate>Tue, 01 Apr 2025 20:53:55 +0000</pubDate>
      <link>https://dev.to/terminalcoffee/html-e-uma-linguagem-de-programacao-ou-pelo-menos-esta-mais-perto-disso-do-que-voce-imagina-1387</link>
      <guid>https://dev.to/terminalcoffee/html-e-uma-linguagem-de-programacao-ou-pelo-menos-esta-mais-perto-disso-do-que-voce-imagina-1387</guid>
      <description>&lt;p&gt;O HTML é alvo de muita chacota on-line, quem nunca riu do famoso "programador de HTML" ou, pelo menos, pensou que era óbvio que ele estava errado, que atire a primeira pedra.&lt;/p&gt;

&lt;p&gt;Não é exatamente incomum nos depararmos com a afirmação de que "HTML é uma linguagem de programação" e ver diversos comentários dizendo o contrário (afinal é verdade), apesar disso, muitos desses comentários tem como intenção zombar como se a pessoa fosse estúpida por pensar daquela forma, como se essa fosse uma discussão rasa e banal.&lt;/p&gt;

&lt;p&gt;O problema é que geralmente os argumentos demonstrando que ele não é uma linguagem de programação, não são bem os mais inteligentes do mundo também, o que gera uma situação do sujo falando do mal lavado, ou seja, a famosa hipocrisia.&lt;/p&gt;

&lt;p&gt;Entretanto esse &lt;em&gt;rabbit role&lt;/em&gt; pode ser bem mais profundo e interessante do que se imagina, existe de fato uma área cinza considerável quanto à o que seria uma linguagem de programação.&lt;/p&gt;

&lt;p&gt;Por isso hoje vamos estudar como aquele seu amigo iniciante que "programa" em HTML talvez possa ter mais razão do que você imagina. &lt;/p&gt;

&lt;h2&gt;
  
  
  Caso 1: é uma linguagem de marcação
&lt;/h2&gt;

&lt;p&gt;Para muitos, o fato de HTML ser uma sigla para &lt;em&gt;hypertext &lt;strong&gt;markup language&lt;/strong&gt;&lt;/em&gt; é o suficiente para desconsiderar ele como linguagem de programação, afinal ele não seria uma linguagem de programação, mas sim uma de marcação, porém não tem nada que impede uma linguagem de marcação de ser uma linguagem de programação também, alguns exemplos disso seriam:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;XSLT (Extensible Stylesheet Language Transformation);&lt;/li&gt;
&lt;li&gt;SGML (Standart Generalized Markup Language);&lt;/li&gt;
&lt;li&gt;LaTeX.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;XSLT por exemplo é uma linguagem Turing Complete (o que como vamos ver mais para frente também não é requisito, apesar de ser um bom indicativo), além de possuir construtos como condicionais, e estruturas de repetição, sendo possível até escrever algoritmos nele, como por exemplo a sequência de fibonacci:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;xsl:stylesheet&lt;/span&gt; &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;"1.0"&lt;/span&gt; &lt;span class="na"&gt;xmlns:xsl=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/1999/XSL/Transform"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;xsl:template&lt;/span&gt; &lt;span class="na"&gt;match=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;result&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;xsl:call-template&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"fibonacci"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;xsl:with-param&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"n"&lt;/span&gt; &lt;span class="na"&gt;select=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;xsl:with-param&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt; &lt;span class="na"&gt;select=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;xsl:with-param&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"b"&lt;/span&gt; &lt;span class="na"&gt;select=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/xsl:call-template&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/result&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/xsl:template&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;xsl:template&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"fibonacci"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;xsl:param&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"n"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;xsl:param&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;xsl:param&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"b"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

        &lt;span class="c"&gt;&amp;lt;!-- Output current Fibonacci number --&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;fib&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;xsl:value-of&lt;/span&gt; &lt;span class="na"&gt;select=&lt;/span&gt;&lt;span class="s"&gt;"$a"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/fib&amp;gt;&lt;/span&gt;

        &lt;span class="c"&gt;&amp;lt;!-- Continue recursion if n &amp;gt; 1 --&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;xsl:if&lt;/span&gt; &lt;span class="na"&gt;test=&lt;/span&gt;&lt;span class="s"&gt;"$n &amp;gt; 1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;xsl:call-template&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"fibonacci"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;xsl:with-param&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"n"&lt;/span&gt; &lt;span class="na"&gt;select=&lt;/span&gt;&lt;span class="s"&gt;"$n - 1"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;xsl:with-param&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt; &lt;span class="na"&gt;select=&lt;/span&gt;&lt;span class="s"&gt;"$b"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;xsl:with-param&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"b"&lt;/span&gt; &lt;span class="na"&gt;select=&lt;/span&gt;&lt;span class="s"&gt;"$a + $b"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/xsl:call-template&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/xsl:if&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/xsl:template&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/xsl:stylesheet&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Caso 02: não está no nome
&lt;/h2&gt;

&lt;p&gt;Continuando num outro argumento que vem acompanhado quando se faz o anterior é a ideia de que como o HTML tem &lt;em&gt;markup language&lt;/em&gt; no nome, ele claramente é uma linguagem de marcação e como não tem programação escrito no nome, não poderia ser uma linguagem de programação, o que é um argumento no mínimo pedante.&lt;/p&gt;

&lt;p&gt;Várias outras linguagens de programação bem populares também carregam nomes ambíguos como por exemplo JavaScript, que indica que ele seria uma linguagem script e não uma de programação de verdade, ou PHP (PHP Hypertext Processor) que inclusive possui o hypertext no nome, o que demonstra que o nome pode até ser um indicativo, mas ele não deveria ser um critério decisivo para decidir isso.&lt;/p&gt;

&lt;p&gt;Outro grande exemplo seria o próprio XSLT que vimos anteriormente que mesmo sendo uma linguagem de marcação, com &lt;em&gt;markup language&lt;/em&gt; no nome, ainda assim é uma linguagem de programação.&lt;/p&gt;

&lt;h2&gt;
  
  
  Caso 03: HTML é estrutura, CSS é estilização, e JS é interatividade
&lt;/h2&gt;

&lt;p&gt;Uma variação do ponto anterior é que se argumenta que como o HTML tem uma responsabilidade muito clara de definir a estrutura semântica de uma página web, enquanto CSS serve para estiliza-lá, e o JS para adicionar interatividade.&lt;/p&gt;

&lt;p&gt;Dessa forma, apenas o JS poderia ser considerado uma linguagem de programação afinal ele que adiciona o elemento do dinamismo e da interatividade nos documentos.&lt;/p&gt;

&lt;p&gt;O problema disso é que tanto o HTML quanto CSS possuem capacidades de tornar coisas dinâmicas atualmente, mesmo que de forma limitada.&lt;/p&gt;

&lt;p&gt;O HTML, por exemplo, possui a Popover API, os novos atributos command e commandfor (que possibilitam habilitar uma tag dialog sem JS, e muito mais), ou tags interativas como as summary e details.&lt;/p&gt;

&lt;h2&gt;
  
  
  Caso 04: Falta de controle de fluxo
&lt;/h2&gt;

&lt;p&gt;Para muitos, uma linguagem só pode ser de programação se incluir coisas como variáveis, estruturas condicionais como if ou switch, e estruturas de repetição como for loops por exemplo.&lt;/p&gt;

&lt;p&gt;Sendo um dos argumentos mais hipócritas de todos, visto que demonstra que elas entendem tanto do tema quanto o iniciante ao qual elas estão fazendo chacota.&lt;/p&gt;

&lt;p&gt;Afinal você não precisa de variáveis, ifs ou loops para programar, programação funcional nos mostra que é possível programar de forma imutável (sem variáveis), podemos simplesmente usar recursão ao invés de loops, e ifs não precisam ser estruturas que controlam o fluxo do código, uma vez que booleans podem ser expressos como objetos ou funções, resultando em branching ou pelo type system ou simplesmente pela invocação de funções.&lt;/p&gt;

&lt;p&gt;Considerar apenas essas estruturas mais comuns deixa de fora inumeras linguagens como as que compõe o paradigma lógico e funcional, e até mesmo algumas puramente orientadas a objeto como Smalltalk (não existem estruturas de controle de fluxo aqui, apenas objetos).&lt;/p&gt;

&lt;h2&gt;
  
  
  Caso 05: Não é Turing Complete
&lt;/h2&gt;

&lt;p&gt;Este talvez seja o melhor ponto para se ressaltar se algo é uma linguagem de programação ou não, visto que é uma métrica bem confiável para maioria dos casos, afinal se passa pelo teste de Turing, possui uma sintaxe formal com semântica definida, e pode ser usado para escrever programas de computador, então é uma linguagem de programação.&lt;/p&gt;

&lt;p&gt;O problema aqui é que só ser Turing Complete não garante que é uma linguagem de programação visto que existem coisas que são Turing Complete, mas não são linguagens de programação por exemplo o &lt;a href="https://gaming.stackexchange.com/questions/20219/is-minecraft-turing-complete" rel="noopener noreferrer"&gt;a redstone do jogo Minecraft&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Por outro lado, não ser Turing Complete também não desqualifica automaticamente uma linguagem, afinal existem alguns domínios que exigem que as linguagens proibam certas coisas como loops infinitos de acontecerem, por exemplo em linguagens usadas para projetar chips de computador (como os produzidos pela Intel ou AMD), como essas linguagens produzem especificações que refletem as limitações que o hardware vai ter na vida real, elas acabam tendo limitações que as impedem de ser consideradas Turing Complete.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mas então o que caracterizaria uma linguagem de programação?
&lt;/h2&gt;

&lt;p&gt;Isso é uma questão complexa, visto que mesmo critérios já estabelecidos como a completude de Turing não parecem ser suficiente para isso, mas se formos para uma linha abstrata demais, quase que filosófica, e dizer que seria qualquer coisa que possibilite a criação de instruções que façam um computador fazer alguma coisa, talvez até mesmo prompt numa IA possa ser considerado programação, o que também não é muito útil como critério.&lt;/p&gt;

&lt;p&gt;O que fez mais sentido para mim até hoje seria a ideia de que precisa ser uma linguagem com sintaxe e semântica formais, um grau de expressividade suficiente para computação geral (Turing completa ou próximo disso) e que permite o raciocínio sobre seus programas.&lt;/p&gt;

&lt;p&gt;Expressividade significa o grau de liberdade que uma linguagem oferece, por exemplo numa linguagem de tipagem estática, a liberdade é menor, pois o sistema de tipos te impede de usar um valor de um tipo quando outro é requerido.&lt;/p&gt;

&lt;p&gt;O raciocínio se refere a capacidade de programas poderem ser análisados por humanos ou computadores baseado na sua sintaxe e semânticas formais, por exemplo poder olhar que x = 1 + 1, e dizer que x é 2 se baseando no modelo formal da matemática.&lt;/p&gt;

&lt;p&gt;Essa definição se baseia na descrição de Peter Van Roy sobre o que seria programação:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;First, a computation model, which is a formal system that defines a language and how sentences of the language (e.g., expressions and statements) are executed by an abstract machine.For this book, we are interested in computation models that are useful and intuitive for programmers.This will become clearer when we define the first one later in this chapter.&lt;/li&gt;
&lt;li&gt;Second, a set of programming techniques and design principles used to write programs in the language of the computation model.We will sometimes call this a programming model.A programming model is always built on top of a computation model.&lt;/li&gt;
&lt;li&gt;Third, a set of reasoning techniques to let you reason about programs, to increase confidence that they behave correctly, and to calculate their efficiency.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;~ Peter Van Roy, Concepts, Techiniques, and Models of Computer Programming, p. 29&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Já que ela nos dá os critérios necessários para entender os casos "fora da curva" que eu citei nas seções anteriores, ao mesmo tempo que oferece uma justificativa para o HTML chegar perto, mas não ser uma linguagem de programação.&lt;/p&gt;

&lt;p&gt;No caso, ele possui sintaxe e semântica muito bem definidas, você consegue raciocinar sobre o resultado de um "programa" HTML, tem um certo grau de expressividade (inclusive ele ganhou mais expressividade nos últimos anos), mas ainda não chega a ser suficiente para ser algo próximo de uma máquina de Turing, ele ainda é uma linguagem cujo a expressividade é limitada à apenas declarar estruturas de dados e nada mais.&lt;/p&gt;

&lt;p&gt;Dito isso, ele é compatível com várias das coisas que caracterizam uma linguagem de programação, e é por isso que num critério menos rigoroso, ele poderia sim ser considerado uma linguagem de programação, mesmo que técnicamente isso fosse errado, o que explica o motivo de muitos iniciantes, ou pessoas em geral falando de forma informal, se referirem a ele assim.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explorando as áreas cinzas
&lt;/h2&gt;

&lt;p&gt;Apesar disso tudo que nós abordamos, se a gente considerar a existência de web components, e fizermos algumas concessões, o HTML poderia sim ser considerado uma linguagem de programação dentro das regras que nós decidimos na seção anterior.&lt;/p&gt;

&lt;p&gt;Tudo o que falta para o HTML é uma expressividade maior, de modo que ele possa realizar computações além de simplesmente declarar estruturas de dados.&lt;/p&gt;

&lt;p&gt;Tanto que isso se verifica na prática pois template engines, ou frameworks JS que adicionam DSLs por cima do HTML (tipo o Vue ou Svelte) basicamente tornam possível a escrita de programas com ele.&lt;/p&gt;

&lt;p&gt;O problema é que template engines não contam pois são uma nova linguagem implementada por cima do HTML, então ele em si continua não contando.&lt;/p&gt;

&lt;p&gt;E no caso dos frameworks de JS, apesar deles melhorarem o HTML, essencialmente o código que você escreve é o em JS, a parte HTML continua sendo só puramente declarativa mesmo.&lt;/p&gt;

&lt;p&gt;O interessante seria se o HTML em si ganhasse novas tags que permitissem expressar computações mesmo que de forma declarativa (semelhante ao XLST citado anteriormente), e é ai que entram os web components.&lt;/p&gt;

&lt;p&gt;Eles são uma spec oficial da web cujo o propósito é justamente estender o HTML permitindo que você registre novos elementos válidos ao DOM da página. Sendo assim, poderíamos definir um conjunto de web components que simbolizam computações formais, virando HTML válido dentro da página que registrar eles.&lt;/p&gt;

&lt;p&gt;O único problema dessa abordagem seria que web components dependem de JS para funcionar, então para esse ponto funcionar deveríamos fazer a concessão de considerar o JS apenas como o runtime do HTML, tal como o bytecode é para o Java.&lt;/p&gt;

&lt;p&gt;Essa concessão faz sentido aqui e não para os frameworks de JS, pois os web components não adicionam nada na sintaxe formal do HTML, então essencialmente um novo web component seria uma nova tag do HTML, e o JS não é exposto em nenhum ponto aqui, ele age apenas como um detalhe de implementação, se a gente escrevesse um interpretador de HTML em python e que entendesse esses web components também, e projetasse uma saída num console, a parte de raciocínio do programa continuaria igual, ao passo que num interpretador de Vue por exemplo, seria necessário adicionar toda a semântica e raciocínio para um programa JS também.&lt;/p&gt;

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

&lt;p&gt;No artigo de hoje vimos que a ideia de HTML ser uma linguagem de programação vai bem além de só uma piada, e que a definição de o que seria uma é um assunto bem mais profundo do que parece, por isso se você achou o conteúdo interessante, comenta aqui para gente o que você achou da nossa proposta de interpretação com web components, o HTML deveria ser considerado uma linguagem de programação nesse caso ou não?&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>braziliandevs</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Se preferimos composição, então por que os frameworks usam herança?</title>
      <dc:creator>Terminal Coffee</dc:creator>
      <pubDate>Tue, 31 Dec 2024 23:48:49 +0000</pubDate>
      <link>https://dev.to/terminalcoffee/se-preferimos-composicao-entao-por-que-os-frameworks-usam-heranca-1ce5</link>
      <guid>https://dev.to/terminalcoffee/se-preferimos-composicao-entao-por-que-os-frameworks-usam-heranca-1ce5</guid>
      <description>&lt;p&gt;Todos já ouvimos aquele famoso ditado do GoF (Gang of Four) sobre preferir composição ao invés de herança, entretanto, na prática, isso acaba mais virando um: herança é ruim, nunca use herança, sempre utilize exclusivamente composição para tudo.&lt;/p&gt;

&lt;p&gt;Apesar disso, ela está mais presente em nossos códigos do que parece quando pensamos sobre o assunto, afinal, embora nós nunca a escolhemos para projetar os nossos códigos, e temos até certa aversão ao seu uso dependendo de quão fundo você foi neste tópico, ela se faz presente em diversos códigos essenciais para que a nossas aplicações existam, afinal diversos frameworks de utilizam dela para que eles funcionem, então não é incomum precisarmos herdar uma classe de um framework por exemplo.&lt;/p&gt;

&lt;p&gt;Ao refletir neste tópico, isso me fez chegar a questão do nosso título: se preferimos composição, então por que os frameworks usam herança? Será que podemos estar subestimando a sua utilidade? Ou será que podemos ser criativos e projetar algo interessante através dela? Sendo isso que iremos investigar no artigo de hoje.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;Eu conheço os diversos problemas da herança tal como o alto acoplamento, problema do diamante, problema da classe base frágil, e etc, entretanto este não é um artigo para discutir os seus problemas num geral, e sim as suas utilidades, por isso se quiserem um artigo sobre isso também não deixem de pedir nos comentários o nosso take sobre &lt;em&gt;"why inheritance is evil"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Também não é a intenção deste artigo dizermos que você sempre deve utilizar herança ao invés de composição, ou até que discordamos do ditado, na verdade, é por concordar demais com ele, que resolvi realizar esta investigação atrás de um cenário onde o "prefira" se aplica de fato ao invés de ser um "sempre", afinal se é "prefira" então significa que deve ter algum caso onde herança pode ser mais útil ou pelo menos equivalente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Por que preferimos composição ao invés de herança?
&lt;/h2&gt;

&lt;p&gt;Em resumo, é porque, geralmente, o trade-off é melhor quando usamos composição, utilizamos herança por dois motivos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reúso de código;&lt;/li&gt;
&lt;li&gt;Programação incremental;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reúso é bem auto-explicativo, se temos uma classe A com os métodos &lt;code&gt;foo&lt;/code&gt; e &lt;code&gt;bar&lt;/code&gt;, podemos usar ela de base para criar a classe B com os métodos &lt;code&gt;foo&lt;/code&gt;, &lt;code&gt;bar&lt;/code&gt;, e &lt;code&gt;bazz&lt;/code&gt;, ex:&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;A&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;foo&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;echo&lt;/span&gt; &lt;span class="s2"&gt;"Foo"&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;function&lt;/span&gt; &lt;span class="n"&gt;bar&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;echo&lt;/span&gt; &lt;span class="s2"&gt;"Bar"&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;B&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;A&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;bazz&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;echo&lt;/span&gt; &lt;span class="s2"&gt;"Bazz"&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;Assim não precisamos ficar copiando e colando todo o código comum da nossa aplicação toda vez que tivermos uma classe parecida com outra, podemos simplesmente herdar da original.&lt;/p&gt;

&lt;p&gt;Essa habilidade de reúsar o código é bem útil para aplicar uma abordagem que chamamos de programação incremental, onde ao invés de começar com uma classe gigante que faz tudo, nós começamos com uma pequena, e se precisarmos criar variações dela, nós podemos implementa-las como classes filhas dessa original, incrementando de pouco em pouco a cada nova iteração. Assim como fizemos com a classe A que tinha dois métodos, onde incrementamos ela com mais um método lá na classe B.&lt;/p&gt;

&lt;p&gt;Herança também permite a gente modificar o código de um método da classe mãe na filha caso seja necessário, mas como sabemos que boa parte do tempo, se quisermos respeitar o LSP (Liskov Substitution Principle), não devemos fazer isso, ou perderemos a capacidade de trocar classes dentro de uma mesma hierarquia (que é uma das maiores vantagens de se colocar os adicionais em classes separadas ao invés de tudo na principal), então normalmente só temos uma situação onde se adiciona coisas a mãe na filha, e não modificamos nada que veio da mãe, assim a filha é só a mãe com coisas extras, ao invés de ser a mãe só que diferente em alguns pontos.&lt;/p&gt;

&lt;p&gt;Dado que vamos respeitar o LSP, poderíamos ter uma hierarquia assim:&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;class&lt;/span&gt; &lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Stringable&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;private&lt;/span&gt; &lt;span class="kt"&gt;string&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="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__toString&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="k"&gt;return&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="n"&gt;value&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;AllCapsText&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Text&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;__toString&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="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;strtoupper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;__toString&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;TrimmedText&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Text&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;__toString&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="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;__toString&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;echo&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'    Hello World'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//     Hello World&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AllCapsText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'    Hello World'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//     HELLO WORLD&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TrimmedText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'    Hello World'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Hello World&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Dessa forma, qualquer código que aceita Text vai aceitar suas filhas também, entretanto, observe esse código feito com composiçã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="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Stringable&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;private&lt;/span&gt; &lt;span class="kt"&gt;string&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="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__toString&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="k"&gt;return&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="n"&gt;value&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;AllCapsText&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Stringable&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;private&lt;/span&gt; &lt;span class="kt"&gt;Stringable&lt;/span&gt; &lt;span class="nv"&gt;$text&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;function&lt;/span&gt; &lt;span class="n"&gt;__toString&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="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;strtoupper&lt;/span&gt;&lt;span class="p"&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="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;__toString&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;TrimmedText&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Stringable&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;private&lt;/span&gt; &lt;span class="kt"&gt;Stringable&lt;/span&gt; &lt;span class="nv"&gt;$text&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;function&lt;/span&gt; &lt;span class="n"&gt;__toString&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="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;trim&lt;/span&gt;&lt;span class="p"&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="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;__toString&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="nv"&gt;$text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'    Hello World'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$allCaps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AllCapsText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$trimmed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TrimmedText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$text&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//     Hello World&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$allCaps&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//     HELLO WORLD&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$trimmed&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Hello World&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Obtivemos exatamente o mesmo resultado com praticamente o mesmo esforço, apesar disso, a abordagem com composição possui duas vantagens:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tem menor acoplamento;&lt;/li&gt;
&lt;li&gt;Você pode compor cada uma das classes;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Então, como cada classe é uma classe independente sem acoplamento direto com a original, podemos nos beneficiar do baixo acoplamento e evoluir cada uma de forma independente sem ter medo de quebrar ninguém de forma não planejada, além disso, apesar do efeito ser o mesmo para quando só queremos usar versões diferentes da classe base, a vantagem aqui é que se a gente quiser combinar as mutações, podemos só fazer isso:&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;echo&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TrimmedText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AllCapsText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'   Hello World'&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="c1"&gt;// HELLO WORLD&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E usando herança, não temos como combinar as filhas, nós temos que criar uma nova filha que tem a capacidade de duas, por exemplo uma classe &lt;code&gt;AllCapsTrimmedText&lt;/code&gt;, o que limita a flexibilidade da habilidade de se incrementar, mantendo o reúso de código, só que tendo que escrever bem mais código de boilerplate em troca.&lt;/p&gt;

&lt;p&gt;Em resumo, podemos visualizar melhor os trade-offs de cada abordagem na seguinte tabela:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspecto&lt;/th&gt;
&lt;th&gt;Peso&lt;/th&gt;
&lt;th&gt;Herança&lt;/th&gt;
&lt;th&gt;Composição&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Acoplamento&lt;/td&gt;
&lt;td&gt;Muito Importante (3)&lt;/td&gt;
&lt;td&gt;Alto (1)&lt;/td&gt;
&lt;td&gt;Baixo (3)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flexibilidade&lt;/td&gt;
&lt;td&gt;Muito Importante (3)&lt;/td&gt;
&lt;td&gt;Médio (2)&lt;/td&gt;
&lt;td&gt;Alto (3)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reúso&lt;/td&gt;
&lt;td&gt;Importante (2)&lt;/td&gt;
&lt;td&gt;Alto (3)&lt;/td&gt;
&lt;td&gt;Alto (3)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extensibilidade&lt;/td&gt;
&lt;td&gt;Importante (2)&lt;/td&gt;
&lt;td&gt;Alto (3)&lt;/td&gt;
&lt;td&gt;Médio (2)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Boilerplate&lt;/td&gt;
&lt;td&gt;Pouco Importante (1)&lt;/td&gt;
&lt;td&gt;Baixo (3)&lt;/td&gt;
&lt;td&gt;Alto (1)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Média Ponderada&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;4.8&lt;/td&gt;
&lt;td&gt;5.8&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Acoplamento
&lt;/h3&gt;

&lt;p&gt;Esse é um aspecto que é muito importante na prática (por isso seu peso é 3), pois tem um impacto enorme na capacidade de se dar manutenção e evoluir qualquer sistema.&lt;/p&gt;

&lt;p&gt;A composição possui baixo acoplamento devido a poder evitar uma relação direta com outras classes através de interfaces, sendo assim, mudanças ficam encapsuladas num objeto, e não se propagam para os outros objetos que dependem dele tão facilmente.&lt;/p&gt;

&lt;p&gt;A herança, pelo contrário, cria uma relação direta entre mãe e filha, sendo uma das relações com maior grau de acoplamento entre objetos. O que se reflete pelo próprio objetivo da herança que seria o reúso de código, ou seja, quando você utiliza herança é justamente quando você quer que mudanças na classe base se propagem nas filhas, então, por natureza, ela exige um cenário de alto acoplamento.&lt;/p&gt;

&lt;h3&gt;
  
  
  Flexibilidade
&lt;/h3&gt;

&lt;p&gt;Esse também é outro aspecto que damos muita importancia na prática, afinal é o aspecto mais útil de quando digitamos código, pois mais útil do que não precisar copiar as mesmas linhas de código de um módulo para criar variações dele, é conseguir juntar vários módulos diferentes num módulo só, assim economizando as linhas de todos esses módulos ao mesmo tempo.&lt;/p&gt;

&lt;p&gt;Até porque as variações de uma classe podem ir surgindo com o tempo, mas elas vão crescendo de forma linear, entretanto as combinações entre vários módulos podem ir crescendo exponencialmente a cada nova variação introduzida.&lt;/p&gt;

&lt;p&gt;Nesse aspecto, a composição, similar a herança no último tópico, tem como objetivo principal ser o ato de combinar vários módulos em um (afinal você &lt;strong&gt;compõe&lt;/strong&gt; eles), então por natureza esse é o aspecto mais forte dessa abordagem.&lt;/p&gt;

&lt;p&gt;No caso da herança, enquanto ela oferece certo grau de flexibilidade ao permitir que nós adicionemos variações de uma mesma classe ao herdar ela, não conseguimos misturar essas variações umas com as outras, sendo um grau menos flexível que a composição.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reúso
&lt;/h3&gt;

&lt;p&gt;Esse é um aspecto importante, afinal seguir o DRY tem se provado como uma decisão sábia ao longo de toda a história do desenvolvimento de software, entretanto, ele não é um aspecto que deve ser buscado a custa de outros, inclusive reusar código em situações onde a coesão entre os módulos for baixa acaba sendo mais um problema do que uma solução, visto que pela falta de coesão entre eles, cada módulo vai acabar evoluindo de forma independente ao longo do tempo, sendo assim, depois de um periodo de tempo, a tendência é que eles já não vão compartilhar mais nada entre si, tornando o ato de criar uma abstração para compartilhar o código um empecilho em evoluir cada um deles de forma independente.&lt;/p&gt;

&lt;p&gt;Aqui, ambos herança e acoplamento são ferramentas ótimas para lidar com esse aspecto, não a toa que existe toda essa discussão em torno de quando se usar cada um, sendo a herança melhor em reduzir o boilerplatena hora de reusar código e extender o mesmo, e a composição melhor em criar combinações a partir de códigos já existentes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Extensibilidade
&lt;/h3&gt;

&lt;p&gt;Esse é um aspecto bem importante, afinal, como apontado no aspecto de flexibilidade, é bem importante que os módulos do sistema possam ser reutilizamos na criação de novos módulos que sejam derivações dos originais, apesar disso, a extensibilidade por si é só um pedaço da flexibilidade, por isso sua importância não chega a ser a mesma da flexibilidade.&lt;/p&gt;

&lt;p&gt;Aqui encontramos o primeiro trade-off onde herança começa a ganhar mais relevância, pois dependendo do cenário em que vamos acabar precisando estender os comportamentos na nova classe, alguns deles são impossíveis para a composição sem que nós violemos o encapsulamento, enquanto na herança temos um mecanismo específico desenhado para resolver esse problema na forma do modificador de visibilidade protected.&lt;/p&gt;

&lt;p&gt;Esses cenários podem ser resumidos na seguinte tabela:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Cenário&lt;/th&gt;
&lt;th&gt;Herança&lt;/th&gt;
&lt;th&gt;Composição&lt;/th&gt;
&lt;th&gt;Observações&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Adicionar/Modificar + Sem Dependências&lt;/td&gt;
&lt;td&gt;✅ Fácil&lt;/td&gt;
&lt;td&gt;✅ Fácil&lt;/td&gt;
&lt;td&gt;Sem dependências, ambas as abordagens são viáveis.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Adicionar/Modificar + Depende do Filho&lt;/td&gt;
&lt;td&gt;✅ Fácil&lt;/td&gt;
&lt;td&gt;✅ Fácil&lt;/td&gt;
&lt;td&gt;Ambas as abordagens lidam bem com dependências específicas do filho.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Adicionar/Modificar + Depende do Comportamento do Pai (Público)&lt;/td&gt;
&lt;td&gt;✅ Fácil&lt;/td&gt;
&lt;td&gt;✅ Fácil&lt;/td&gt;
&lt;td&gt;Métodos públicos funcionam igualmente em herança e composição.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Adicionar/Modificar + Depende do Comportamento do Pai (Protegido)&lt;/td&gt;
&lt;td&gt;✅ Fácil&lt;/td&gt;
&lt;td&gt;⚠️ Comprometido&lt;/td&gt;
&lt;td&gt;A composição exigiria tornar métodos protegidos públicos.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Adicionar/Modificar + Depende dos Dados do Pai&lt;/td&gt;
&lt;td&gt;✅ Fácil&lt;/td&gt;
&lt;td&gt;❌ Quebra o Encapsulamento&lt;/td&gt;
&lt;td&gt;A composição força o uso de getters, quebrando o encapsulamento.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Boilerplate
&lt;/h3&gt;

&lt;p&gt;Aqui é o aspecto menos importante daquela tabela, pois enquanto é algo que torna a experiência de escrever código muito mais prazerosa, visto que não vamos perder tempo escrevendo código que não está contribuindo para a resolução do problema, ou seja, evitando de escrever código "por obrigação", sendo o mais prático de se escrever a curto prazo, é um benefício que a gente trocaria facilmente sempre que a troca nos der outros benefícios mais relevantes tais como os outros mais bem rankeados nesta comparação.&lt;/p&gt;

&lt;p&gt;Essa troca entre praticidade e benefícios de longo prazo é a decisão que a gente toma constantemente quando decidimos desacoplar nosso código por exemplo.&lt;/p&gt;

&lt;p&gt;Apesar disso é aqui que se encontra o trade-off mais favorável para a herança, pois a composição exige um monte de boilerplate em troca de todos os benefícios que ela oferece.&lt;/p&gt;

&lt;p&gt;Em uma situação onde a classe base só tem um método, e queremos estender um único método, como vimos anteriormente, o código requerido por cada abordagem é mais ou menos o mesmo, entretanto quanto mais métodos nós adicionamos na classe base, mais a composição sofre, pois ela necessita que cada método não incrementado da classe base seja copiado no novo objeto só para chamar internamente o método do objeto original. Ex:&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;Foo&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;methodA&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;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;methodB&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="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bar&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;private&lt;/span&gt; &lt;span class="kt"&gt;Foo&lt;/span&gt; &lt;span class="nv"&gt;$foo&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;function&lt;/span&gt; &lt;span class="n"&gt;methodA&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;return&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="n"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;methodA&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;function&lt;/span&gt; &lt;span class="n"&gt;methodB&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="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;methodC&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;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;methodB&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;function&lt;/span&gt; &lt;span class="n"&gt;methodC&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enquanto a herança elimina completamente o boilerplate do código, mantendo só as partes que interessa para gente, ou seja, as que contém código novo:&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;Foo&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;methodA&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;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;methodB&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="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bar&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Foo&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;methodB&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="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;methodC&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;methodB&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;function&lt;/span&gt; &lt;span class="n"&gt;methodC&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Resultado
&lt;/h3&gt;

&lt;p&gt;Sendo assim, o ditado se prova pois, apesar de ambos terem uma média final similar, os cenários onde a composição tem vantagem sobre a herança são os cenários que preferimos ter quando escrevemos os nossos códigos, por isso, via de regra, vamos acabar preferindo por composição mesmo.&lt;/p&gt;

&lt;p&gt;Infelizmente, o alto acoplamento é algo que segura demais a herança quando vamos fazer essas comparações, tanto é que se removermos a importância do acoplamento, reduzindo ela a 0, a média ponderada vai mudar para um cenário que mostra a herança como mais favorável (por uma diferença de 0.2 mais ou menos).&lt;/p&gt;

&lt;h2&gt;
  
  
  O que os frameworks tem a ver com isso?
&lt;/h2&gt;

&lt;p&gt;Ao analisar a nossa tabela, podemos concluir que o cenário ideal para herança seria quando nossas prioridades estão invertidas, por isso que ele é tão raro, sendo algo praticamente teórico, ou seja, nós precisamos desenhar um cenário onde desejamos um acoplamento alto ou ele não faz diferença para a situação, e que reúso de código seja o aspecto que damos mais importância ao invés de ser só algo secundário que seria bom ter. E adivinha qual cenário da vida real seria esse?&lt;/p&gt;

&lt;p&gt;Exatamente meu caro leitor, os frameworks são o exemplo perfeito que atinge todos esses requisitos extremamente específicos onde a herança é algo favorável. Pelo menos é esse o caso quando falamos de frameworks opinativos tal como o Laravel ou Ruby on Rails.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reúso
&lt;/h3&gt;

&lt;p&gt;Frameworks existem para facilitar a nossa vida na hora de desenvolver uma aplicação, sendo assim, o seu princípal objetivo é prover abstrações já prontas de modo que esse código que vai ser comum a todos os projetos que necessitem dos processos que o framework busca automatizar ou facilitar possa ser reutilizado diretamente dele pelos desenvolvedores desse projeto.&lt;/p&gt;

&lt;p&gt;Podemos notar isso através dessas duas definições obtidas da Wikipedia:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Uma estrutura é um termo genérico que geralmente se refere a uma estrutura de suporte essencial sobre a qual outras coisas são construídas em cima.&lt;br&gt;
~ &lt;a href="https://en.wikipedia.org/wiki/Framework" rel="noopener noreferrer"&gt;Wikipedia - Definição genérica&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Um &lt;em&gt;framework&lt;/em&gt; em desenvolvimento de software, é uma abstração que une códigos comuns entre vários projetos de software provendo uma funcionalidade genérica.&lt;br&gt;
~ &lt;a href="https://pt.wikipedia.org/wiki/Framework" rel="noopener noreferrer"&gt;Wikipedia - Definição em desenvolvimento de software&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Resumindo, exatamente a nossa definição, sendo uma dependência externa que reúne várias abstrações diferentes comuns a diversos projetos de software com domínios semelhantes, de modo a prover uma base genérica para se escrever uma aplicação daquele tipo em cima.&lt;/p&gt;

&lt;p&gt;Sendo assim, a princípal prioridade de um framework é escrever código que possa ser compartilhado e reúsado, que como vimos é uma área onde herança tende a ter mais vantagens, mesmo que composição possa ser situacionalmente melhor.&lt;/p&gt;

&lt;p&gt;Além disso, permitir que os usuários de um framework possam estender suas capacidades, visto que cada usuário terá necessidades diferentes para ele, e, portanto, potencialmente, poderia necessitar de modificações em como ele funciona, a capacidade de sobrescrever certas funções e fornecer pontos de estensão, são coisas essenciais para bons frameworks.&lt;/p&gt;

&lt;p&gt;Herança trás seus maiores benefícios justamente nesses dois casos, sobrescrever comportamentos como é comum usando polimorfismo de subtipo (que é o que você ganha ao usar herança), e criação de pontos de estenção por meio de &lt;a href="https://refactoring.guru/design-patterns/template-method" rel="noopener noreferrer"&gt;template method&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Acoplamento
&lt;/h3&gt;

&lt;p&gt;Apesar de mostrarmos que por sua própria natureza frameworks serem o tipo de código que mais se aproveita dos benefícios da herança, ainda assim temos frameworks inteiros baseados em composição, o que poderia fazer o argumento do alto acoplamento causado pela herança ganhar força novamente, para ela, no melhor dos casos, ser só uma alternativa escrita com uma funcionalidade pior.&lt;/p&gt;

&lt;p&gt;Entretanto, mesmo que frameworks disponibilizem interfaces, módulos isolados baseados em composição, e etc, que façam parecer que o código é menos intrusivo, e mais desacoplado. A verdade é que acoplamento não importa muito num cenário onde você decide usar um framework, pelo menos não para quem escreve o código do framework pensando num benefício para quem usa.&lt;/p&gt;

&lt;p&gt;Tão importante quanto a força do acoplamento é a direção em que ele acontece, estar desacoplado não significa que magicamente os dois módulos sempre vão estar isolados um do outro, na verdade, significa que o código que depende de membros abstratos está se defendendo de quem usa ele.&lt;/p&gt;

&lt;p&gt;Essa noção é muito importante, pois isso significa que mesmo que os frameworks usem composição, e interfaces, expondo elas para manter tudo desacoplado e etc, na verdade, o que está acontecendo é que o código do framework está se protegendo do seu código, quando o que queremos ao ter um baixo acoplamento no código é justamente o contrário, proteger o nosso código do resto.&lt;/p&gt;

&lt;p&gt;Se os desenvolvedores de framework fazem isso, interessante para eles que estão se previnindo de mudanças nos códigos dos seus usuários, mas isso adiciona pouquíssima vantagem para o objetivo de um framework que é facilitar a vida de seus usuários. Uma vez que eles que tem que se defender do framework, e não o contrário.&lt;/p&gt;

&lt;p&gt;Outro motivo pelo qual o acoplamento importa pouco ou as vezes não importa quando estamos falando de frameworks é que, por definição, eles forçam os seus usuários a jogarem nas suas regras, então por definição usar um framework é decidir se acoplar a ele, e reagir as suas mudanças, afinal se você não usa uma arquitetura como a clean architecture ou similares, a estrutura do seu código é a própria estrutura do framework.&lt;/p&gt;

&lt;p&gt;Logo, é uma premissa que para usar, você está aceitando estar acoplado a ele em menor ou maior grau, até porque a única maneira de não se acoplar é escrevendo seu código explicitamente para evitar o framework, o que é uma abordagem mais trabalhosa e faz você não colher todos os benefícios de usar um em primeiro lugar, ou simplesmente não utilizar ele, afinal a ideia é usar código pronto que não é você que controla.&lt;/p&gt;

&lt;p&gt;Dessa forma, como o framework em si não tem como tornar o seu código desacoplado dele, visto que própria premissa dele é ser uma dependência do seu projeto, o acoplamento realmente tem pouquíssimo valor nessa situação em específico, o que nos trás uma situação exatamente como descrevemos anteriormente, onde temos alto acoplamento, e reúso é uma prioridade.&lt;/p&gt;

&lt;h3&gt;
  
  
  Coesão
&lt;/h3&gt;

&lt;p&gt;Curiosamente, um ponto que continua o raciocínio por trás do acoplamento não ser tão relevante, é que, dependendo do caso, o fato de ter menos acoplamento pode até ser pior.&lt;/p&gt;

&lt;p&gt;Uma vez que a maior flexibilidade trazida por ele, é uma vantagem quando você que é o dono desse código, mas pode ser uma desvantagem para um código já estável e coeso como é o caso dos frameworks.&lt;/p&gt;

&lt;p&gt;Isso porque a ideia de um framework é forçar a estrutura dele nos seus usuários em maior ou menor grau, além disso, seus módulos tendem a ser altamente coesos, e já terem sido escritos para funcionarem bem entre si dentro dos casos esperados pelos seus autores.&lt;/p&gt;

&lt;p&gt;Sendo assim, uma abordagem que oferece mais flexibilidade tal como a composição poderia fazer com que seja possível a criação de uma combinação inválida dentro das premissas do framework.&lt;/p&gt;

&lt;p&gt;Outro "problema" é que reforçar uma consistência na forma de fazer as coisas, sendo uma noção vinda até pela própria definição de framework de ser uma base para se construir em cima, é um atributo bem relevante para um framework, e uma abordagem cujo os benefícios são menos controle por parte do framework (mais flexível), e menos dependência direta dele (menos acoplado) iria diretamente contra a promoção deste aspecto.&lt;/p&gt;

&lt;p&gt;Uma maior flexibilidade pode ser uma vantagem para frameworks baseados em configuração (Spring, Synfony, etc), mas particularmente um problema para frameworks baseados em convenções, visto que vai tornar o código menos consistente o que pode ser um desafio para os autores na hora de forçarem certas convenções a se repetirem ao longo do código.&lt;/p&gt;

&lt;p&gt;Fechando esse ponto da consistência, herança pode ser uma vantagem aqui, pois ela oferece uma forma de inversão de controle na forma do padrão template method que é mais rígido que a versão de composição que seria o strategy, com o benefício de ser mais conveniente de implementar os pontos de extensão (o que é um pró no caso de frameworks), e dar mais controle para o framework nesse caso, enquanto retém benefícios semelhantes a versão baseada em composição da aplicação desse conceito.&lt;/p&gt;

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

&lt;p&gt;Sinceramente, quando eu comecei a pesquisa para este artigo, pensei que seria bem simples, iria falar mal do conceito, mostrar que template method era pelo menos algo que dava para ser utilizado e que era legal, e fechar por ali, no entanto, quanto mais eu lia sobre o assunto, mais ideias eu tinha sobre como talvez herança não fosse tão inútil quanto o senso comum faz parecer, o que resultou no texto de hoje sendo um dos que eu mais me diverti escrevendo.&lt;/p&gt;

&lt;p&gt;E você? Se surpreendeu com o quanto a discussão poderia ser mais interessante do que simplesmente dizer que composição é melhor e ponto? Já havia pensando tão profundamente sobre a utilidade da herança? Mudou algo em como você encara esse princípio? Conta para gente aqui nos comentários.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links que podem te interessar
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://refactoring.guru/design-patterns/template-method" rel="noopener noreferrer"&gt;Refactoring Guru sobre Template Method&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/riccardo_cardin/template-method-pattern-revised-3od3"&gt;Template Method Pattern Revised&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.thoughtworks.com/insights/blog/composition-vs-inheritance-how-choose" rel="noopener noreferrer"&gt;Composition vs Inheritance: How to Choose?&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.infoworld.com/article/2160788/why-extends-is-evil.html" rel="noopener noreferrer"&gt;Why extends is evil&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.tonymarston.net/php-mysql/inheritance-is-not-evil.html#how.i.use.inheritance" rel="noopener noreferrer"&gt;Inheritance is NOT evil&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.sicpers.info/2018/03/why-inheritance-never-made-any-sense/" rel="noopener noreferrer"&gt;Why inheritance never made any sense&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://buttondown.com/hillelwayne/archive/when-to-prefer-inheritance-to-composition/" rel="noopener noreferrer"&gt;When to prefer inheritance to composition&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://buttondown.com/hillelwayne/archive/if-inheritance-is-so-bad-why-does-everyone-use-it/" rel="noopener noreferrer"&gt;If Inheritance is so bad, why does everyone use it?&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://thevaluable.dev/guide-inheritance-oop/" rel="noopener noreferrer"&gt;Is Inheritance That Evil?&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.sebaslab.com/wp-content/uploads/2022/04/TemplateAndStrategy.pdf" rel="noopener noreferrer"&gt;TEMPLATE METHOD &amp;amp; STRATEGY: Inheritance vs. Delegation&lt;/a&gt;;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ass. Suporte Cansado&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>learning</category>
      <category>programming</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Tell Don't Ask: a arte da comunicação entre objetos.</title>
      <dc:creator>Terminal Coffee</dc:creator>
      <pubDate>Sat, 19 Oct 2024 04:23:31 +0000</pubDate>
      <link>https://dev.to/terminalcoffee/tell-dont-ask-a-arte-da-comunicacao-entre-objetos-587m</link>
      <guid>https://dev.to/terminalcoffee/tell-dont-ask-a-arte-da-comunicacao-entre-objetos-587m</guid>
      <description>&lt;p&gt;Um tópico que me manteve muito interessado recentemente foi o princípio Tell Don't Ask, citado originalmente no livro Smalltalk By Example (Alec Sharp), o autor destaca que um aspecto que difere muito o código orientado a objetos do código procedural é que usando objetos se &lt;strong&gt;diz&lt;/strong&gt; para eles agirem, enquanto usando funções se &lt;strong&gt;pergunta&lt;/strong&gt; pelos dados primeiro para depois decidir como se agir.&lt;/p&gt;

&lt;p&gt;O princípio se tornou conhecido graças a &lt;a href="https://media.pragprog.com/articles/jan_03_enbug.pdf" rel="noopener noreferrer"&gt;Andy Hut e Dave Thomas&lt;/a&gt;, autores do livro The Pragimatic Programmer, onde, novamente, o conceito é destacado como algo fundamental para a aplicação das ideias orientadas a objeto no código.&lt;/p&gt;

&lt;p&gt;Por fim, minha terceira fonte de inspiração para mergulhar de cabeça nesse assunto foram dois artigos incríveis abordando o tema para além de uma variação do &lt;a href="https://martinfowler.com/bliki/TellDontAsk.html" rel="noopener noreferrer"&gt;artigo escrito pelo Fowler&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://kevinsmith.io/a-better-way-to-handle-validation-errors/" rel="noopener noreferrer"&gt;A Better Way to Handle Validation Errors&lt;/a&gt;: que mostra o potencial desse estilo no tratamento de erros, o que nos dá uma dica sobre como objetos se informam das coisas sem a necessidade de retornar valores ou uso de ifs;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://talesfrom.dev/blog/map-dont-ask" rel="noopener noreferrer"&gt;Map, don't ask&lt;/a&gt;: que traça uma comparação muito interessante do estilo orientado a objetos de resolver problemas (tell don't ask), com o estilo funcional (monâdas representando efeitos colaterais);&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sendo assim, tenho pensado muito sobre como poderíamos escrever software apenas nos baseando nessa ideia, então hoje vou compartilhar com vocês, caros leitores, minhas reflexões sobre o assunto, na forma das várias interações que podemos observar entre objetos, e como lidamos com elas no &lt;em&gt;tell style&lt;/em&gt; ao invés do &lt;em&gt;ask style&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tell Don't Ask
&lt;/h2&gt;

&lt;p&gt;Antes de irmos de fato para o assunto de hoje, para manter todos na mesma página, vamos relembrar a definição do princípio:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Você envia comandos aos objetos dizendo para eles o que você quer feito. Nós explicitamente não queremos perguntar ao objeto sobre o seu estado, tomar uma decisão, e então dizer ao objeto o que fazer.&lt;/p&gt;

&lt;p&gt;~ Andy Hunt e Dave Thomas (adaptação livre)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Situação 01: Quando o objeto possui todos os dados necessários
&lt;/h2&gt;

&lt;p&gt;Aqui seria o exemplo mais simples do uso do Tell Don't Ask (TDA), vamos pensar em lidar com um objeto apenas, por exemplo num caso de uso de sacar dinheiro de uma conta bancária. Se nós seguirmos o &lt;em&gt;ask style&lt;/em&gt;, teríamos o seguinte resultado:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Account&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;balance&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="nf"&gt;getBalance&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="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;balance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;setBalance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;balance&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="k"&gt;void&lt;/span&gt; &lt;span class="p"&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;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;balance&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;type&lt;/span&gt; &lt;span class="nx"&gt;WithdrawCommand&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;amount&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useCase&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;WithdrawCommand&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&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;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Insufficient balance in the account&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="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setBalance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;useCase&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;12345-6&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Toda a lógica de negócio ficou acumulada no caso de uso, e pior de tudo, ela apenas usa dados presentes na classe &lt;code&gt;Account&lt;/code&gt;, o que significa que ela poderia ter dado conta de fazer isso ela mesma, mas quem fez foi o caso de uso, logo, o princípio do encapsulamento, onde nos benefíciamos dos dados viverem ao lado das computações realizadas neles, está sendo gravemente violado aqui.&lt;/p&gt;

&lt;p&gt;Podemos mudar isso ao reescrever no &lt;em&gt;tell style&lt;/em&gt;:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Account&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;balance&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="nf"&gt;withdraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&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="k"&gt;void&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Insufficient balance in the account&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="nx"&gt;amount&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;type&lt;/span&gt; &lt;span class="nx"&gt;WithdrawCommand&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;amount&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useCase&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;WithdrawCommand&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withdraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;useCase&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;12345-6&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Temos que o código foi drasticamente simplificado para apenas:&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="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withdraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Logo, lidando com um único objeto, caso você estiver se pegando usando muitas queries antes de decidir fazer alguma coisa, considere se a lógica que você está escrevendo não poderia ser um método do objeto que é dono desses dados, assim você pode dizer para ele realizar a tarefa ao invés de perguntar se ele tem os dados para realizar a tarefa.&lt;/p&gt;

&lt;h2&gt;
  
  
  Situação 02: Quando um objeto precisa de informações de outro para agir
&lt;/h2&gt;

&lt;p&gt;Se tudo pudesse ser modelado com os dados pertencendo a um objeto, e somente a ele, o mundo seria muito mais fácil, afinal, aplicaríamos sempre a regra que vimos anteriormente, e ai tudo sempre ia acabar se encaixando no método de um objeto, e o dono daquele método seria óbvio, entretanto existem situações onde uma operação exige a colaboração entre dois objetos, pois eles "operam no mesmo dado", ao mesmo tempo que precisam se manter independentes um do outro, pelo menos em termos de conhecimento de seus detalhes de implementação.&lt;/p&gt;

&lt;p&gt;Por exemplo, se tivermos um caso de uso onde um cliente compra um produto, o cliente precisa pagar um &lt;strong&gt;preço&lt;/strong&gt; que é uma propriedade de produto, sendo assim, ele precisa de um dado que não é dele para realizar suas operações.&lt;/p&gt;

&lt;p&gt;Caso nós estejamos pensando de forma procedural, uma solução simples seria perguntar ao produto qual o seu preço, e então modificar a quantidade de dinheiro no cliente, ex:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Customer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;money&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="nf"&gt;setMoney&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;money&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="k"&gt;void&lt;/span&gt; &lt;span class="p"&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;money&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;money&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;Product&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;price&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="nf"&gt;getPrice&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="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;price&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="nf"&gt;useCase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&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;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMoney&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPrice&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Customer cannot pay for the Product&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="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setMoney&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMoney&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPrice&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;A princípio, parece que temos uma situação semelhante a do nosso primeiro exemplo, entretanto note a linha que contém a condicional:&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMoney&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPrice&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;Ela não envolve só os dados de &lt;code&gt;customer&lt;/code&gt;, por isso não podemos simplesmente converter ela num método, como podemos lidar com esse dado que não pertence ao cliente? A resposta é bem simples, se é algo de fora do objeto, então tem que vir de fora, por isso o preço é convertido num parâmetro, ex:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Customer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;money&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="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&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="k"&gt;void&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;money&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Customer cannot pay for this amount&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;money&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="nx"&gt;amount&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;Product&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;price&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="nf"&gt;getPrice&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="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;price&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="nf"&gt;useCase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPrice&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;Com isso o TDA foi aplicado com sucesso no cliente, mas o nosso objeto produto continua sendo só um saco de dados, então será que existe alguma forma de aplicar o TDA nele também?&lt;/p&gt;

&lt;p&gt;A resposta é sim, pois ele tem uma ação relacionada com ele, que é a venda, da mesma forma que a gente tem uma ação faltando no cliente também, que é a compra, o que nos permite modelar a situação da seguinte maneira:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Customer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;money&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="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&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="k"&gt;void&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;money&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Customer cannot pay for this amount&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;money&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;buy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sellItselfTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&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;Product&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;price&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="nf"&gt;sellItselfTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&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;price&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="nf"&gt;useCase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;aProduct&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;buy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;aProduct&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;Parece meio confuso a primeira vista, mas o que está acontecendo nesse código é que ao aplicar o TDA em todas as operações que devem acontecer para que a compra de um produto seja realizada, nós acabamos numa situação onde para implementar uma ação, nós repetimos o processo de descrever as ações que ela precisa realizar para ser executada também, o que nos leva a aplicar o TDA nessas sub-tarefas também, entrando num ciclo de adiar a resolução do problema o máximo possível, sempre empurrando a batata para frente até alguém conseguir resolver o problema. Em certo sentido, é semelhante a como a gente treina para escrever algoritmos recursivos.&lt;/p&gt;

&lt;p&gt;Entrando mais em detalhes, o truque aqui é que a gente troca quem está no controle da execução do código entre ambos os objetos conforme a necessidade de um dado que não pertence ao objeto for surgindo. A lógica é a seguinte:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Para que o cliente possa comprar o produto, o produto precisa ser vendido para ele, então o cliente pede ao produto para que a ação de venda aconteça;&lt;/li&gt;
&lt;li&gt;Para que o Produto possa se vender, ele precisa saber a quem ele está sendo vendido, então ele requere isso via um parâmetro;&lt;/li&gt;
&lt;li&gt;Como Cliente sabe quem quer comprar o produto (&lt;strong&gt;ele mesmo&lt;/strong&gt;), ele informa ao produto quem é o comprador se passando como parâmetro;&lt;/li&gt;
&lt;li&gt;Sabendo para quem ele vai se vender, o Produto precisa que o Cliente pague por ele, então ele pede ao cliente para realizar o pagamento;&lt;/li&gt;
&lt;li&gt;Para que o cliente pague, ele exige saber o valor a ser pago, então ele requere isso via um parâmetro;&lt;/li&gt;
&lt;li&gt;O produto sabe qual valor deve ser pago (pois é o &lt;strong&gt;seu preço&lt;/strong&gt;), então ele passa o preço como parâmetro, e o cliente consegue executar a ação de pagar, encerrando o caso de uso;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Visualizando a coisa acontecendo, o fluxo de execução seria algo como:&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="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;buy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sellItselfTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O truque para fazer com que o controle da execução seja trocado conforme ela for acontecendo, é ceder o controle para o outro objeto chamando um de seus métodos, e se passando como parâmetro, assim quando o outro objeto terminar de fazer o que ele precisa, ele pode devolver o controle da execução para o original ao chamar um de seus métodos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Situação 03: Quando um objeto precisa reagir a eventos em outro
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Nothing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Credentials&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;SignInOutputBoundary&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;emailNotFound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Nothing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;invalidCredentials&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Credentials&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Nothing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;userAuthenticated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Nothing&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;SignIn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;encrypter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Encrypter&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;attemptFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Credentials&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;andReportTo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SignInOutputBoundary&lt;/span&gt;
  &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;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;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;andReportTo&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&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;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;userOfEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&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;user&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;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;emailNotFound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;matchPassword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&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;encrypter&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;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invalidCredentials&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&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;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;userAuthenticated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&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;SignInController&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;SignInOutputBoundary&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;signIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SignIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ResponseBuilder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;emailNotFound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Email: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; not found`&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;invalidCredentials&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Credentials&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Invalid Credentials`&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;userAuthenticated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User Authenticated&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&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;private&lt;/span&gt; &lt;span class="nf"&gt;validateCredentials&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;unknow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// lógica para validar o body...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validateCredentials&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&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;signIn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attemptFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&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;Neste exemplo não aplicamos o TDA em 100% do código para não deixa-lo tão complexo, feitas essas considerações, se você já entendeu a ideia de "trocar o controle da execução", então já deve ter matado a charada aqui também, basicamente quando precisamos notificar um objeto de coisas que aconteceram em outro objeto, podemos mandar uma mensagem para o objeto interessado avisando que o que ele queria saber aconteceu, e o que seriam mensagens senão métodos?&lt;/p&gt;

&lt;p&gt;Por isso, para mandar uma mensagem para o objeto interessado, ele precisa ser capaz de receber essas mensagens para início de conversa, ou seja, ele precisa ter os métodos que vão responder a cada uma dessas situações implementados dentro dele, sendo uma solução bem interessante para lidar com lógica condicional num geral usando apenas troca de mensagens.&lt;/p&gt;

&lt;p&gt;A aplicação do TDA aqui se dá pois ao invés de fazermos algo como o retornar um código de status ou, numa abordagem mais moderna, um objeto Result representando o resultado da execução do caso de uso, e depois decidindo o que fazer, ou seja, perguntando primeiro ao caso de uso qual foi o seu resultado, e depois decidindo o que fazer, sendo que o próprio caso de uso, que tem controle sobre essas informações, pode conversar com o controller, e dizer para ele o que fazer diretamente sem esse passo intermediário.&lt;/p&gt;

&lt;p&gt;Em resumo, o truque aqui é que o objeto interessado em saber de coisas de outro objeto, deve declarar métodos para cada coisa que ele quiser saber desse segundo objeto, dessa forma o segundo objeto pode depender do interessado e chamar os seus métodos quando as condições para eles serem chamados forem atingidas. E se essa explicação soou familiar para você, é porque se nós implementarmos essa ideia de forma ainda mais desacoplada, o que nós temos é basicamente o padrão de projetos Observer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Situação 04: Quando ações diferentes são necessárias para tipos diferentes de objetos
&lt;/h2&gt;

&lt;p&gt;Continuando na ideia de aprender com padrões de projeto, o padrão Visitor nos ensina que podemos realizar a comunicação entre objetos mesmo quando a informação que precisamos é uma meta informação, por exemplo de qual tipo é o objeto.&lt;/p&gt;

&lt;p&gt;No caso de se ter uma única operação ao longo de vários objetos, mas com implementações diferentes para cada um, podemos simplesmente usar polimorfismo simples para resolver o problema, mas e se nós precisarmos executar operações diferentes para tipos diferentes de objetos, quando essas operações podem ter implementações diferentes?&lt;/p&gt;

&lt;p&gt;Por exemplo, podemos escrever o exemplo anterior de uma forma diferente caso se prefira lançar erros e tratar eles separadamente num bloco catch, ao invés de acoplar o caso de uso no presenter:&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ExceptionVisitor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;productNotFound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ProductNotFoundException&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;outOfStock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;OutOfStockException&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;insufficentStock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;InsufficentStockException&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Exception&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;visitor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ExceptionVisitor&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DomainException&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;Exception&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="nf"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;visitor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ExceptionVisitor&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&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;UnknownException&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;Exception&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;visitor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ExceptionVisitor&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;visitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unknown&lt;/span&gt;&lt;span class="p"&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;value&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;ErrorException&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;Exception&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;visitor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ExceptionVisitor&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;visitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&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;error&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;ProductNotFoundException&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;DomainException&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Product not found&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="nf"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;visitor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ExceptionVisitor&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;visitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;productNotFound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&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;OutOfStockException&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;DomainException&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Product out of stock&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="nf"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;visitor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ExceptionVisitor&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;visitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;outOfStock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&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;InsufficentStockException&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;DomainException&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Insufficient Stock of Product&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="nf"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;visitor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ExceptionVisitor&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;visitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insufficentStock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&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="nf"&gt;exceptionFactory&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="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Exception&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;value&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;DomainException&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;value&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="nx"&gt;value&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;Error&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;new&lt;/span&gt; &lt;span class="nc"&gt;ErrorException&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="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;UnknownException&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="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;tryExecute&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;F&lt;/span&gt; &lt;span class="nf"&gt;extends &lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;orHandleWith&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ExceptionVisitor&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;ReturnType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;F&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;void&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="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;();&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;error&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="nf"&gt;exceptionFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;orHandleWith&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;OrderController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;placeOrder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PlaceOrder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;place&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;tryExecute&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;placeOrder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Unknown error&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="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="nf"&gt;insufficentStock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Cannot place an order due to insufficient stock&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="nf"&gt;outOfStock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Cannot place an order for an product that is out of stock&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="nf"&gt;productNotFound&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Cannot place an order for a product that doesn't exist&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="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 caso, com a ajuda de um pequeno helper para converter um valor unknow numa Exception que pode ser visitada, nós conseguimos implementar uma forma de lidar com todas as exceções lançadas pelo caso de uso PlaceOrder sem depender de um switch dentro do Controller.&lt;/p&gt;

&lt;p&gt;Dessa forma, ao invés de ter um instanceof para cada tipo de Erro, nós limitamos a abordagem de perguntar pelas coisas apenas ao que está fora de nosso controle (valores unknow, e erros fora de DomainException), de forma a adaptar esses valores para objetos dentro de nosso controle novamente, e então usar apenas da abordagem tell para lidar com o problema, visto que dizemos para a Exceção aceitar um Visitor, e cada erro pode decidir por si mesmo como usar o Visitor para lidar com si mesmo, o que seria o contrário da abordagem ask, onde o Visitor teria que perguntar a cada Erro quem ele é para depois decidir qual código executar.&lt;/p&gt;

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

&lt;p&gt;Tentar usar o Tell Don't Ask para tudo pode até não ser a abordagem mais pragmática possível, entretanto para que nós de fato consigamos aprender um paradigma, devemos tentar nos blindar o máximo possível de nossos vícios, enquanto tentamos abraçar ao máximo as premissas do paradigma, o que é uma experiência bem difícil, e que nos desafia a pensar fora da caixinha o máximo possível, mas os resultados são recompensadores, visto que depois de conquistar essa nova maneira de pensar, nosso cérebro fica cada vez mais flexível e aberto a novos tipos de soluções, o que melhora a nossa capacidade de resolver problemas.&lt;/p&gt;

&lt;p&gt;Você leitor já havia olhado para a Orientação a Objetos por este ângulo da conversa entre objetos? Achou interessante? Conta para a gente sua opinião sobre o assunto aqui nos comentários.&lt;/p&gt;

&lt;p&gt;Até a próxima!&lt;/p&gt;

&lt;p&gt;ASS: Suporte Cansado...&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Afinal de contas, qual a definição de Orientação a Objetos?</title>
      <dc:creator>Terminal Coffee</dc:creator>
      <pubDate>Thu, 05 Sep 2024 19:04:50 +0000</pubDate>
      <link>https://dev.to/terminalcoffee/afinal-de-contas-qual-a-definicao-de-orientacao-a-objetos-4kmc</link>
      <guid>https://dev.to/terminalcoffee/afinal-de-contas-qual-a-definicao-de-orientacao-a-objetos-4kmc</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;O paradigma da orientação a objetos certamente é um dos tópicos mais relevantes da programação, sendo encontrada em diversas das boas práticas da industria como SOLID, GoF Design Patterns, ou Object Calhistenics, e até mesmo em linguagens extremamente populares como Java, C#, Ruby, PHP, JavaScript, etc. E dada tamanha relevância, ela também é alvo de diversos debates tanto em discussões online ou até na própria acadêmia.&lt;/p&gt;

&lt;p&gt;Uma das principais polêmicas em torno do paradigma seria: o que de fato seria a orientação a objetos? Visto que &lt;a href="https://wiki.c2.com/?NobodyAgreesOnWhatOoIs" rel="noopener noreferrer"&gt;ninguém concorda com o que ela significa&lt;/a&gt;, sendo esse o cerne da questão em vários tipos de brigas de internet como por exemplo quando alguém clama que a sua linguagem é verdadeiramente orientada a objetos enquanto as outras não são, ou que determina linguagem não é realmente orientada a objetos, e etc.&lt;/p&gt;

&lt;p&gt;O que pode parecer bobo a primeira vista, mas existe um problema escondido atrás disso que é o fato de realmente &lt;a href="https://pt.stackoverflow.com/a/88685" rel="noopener noreferrer"&gt;não existir uma definição formal para o que seria a orientação a objetos&lt;/a&gt;. Logo, ao se criticar algo relacionado com o paradigma não podemos realmente ter certeza se ela é justa ou não devido ao fato de ninguém saber do que a verdade se trata de fato, já que isso só vai levar a um debate onde ambas as partes podem acusar a outra de atacar um espantalho visto que elas não concordam com a definição do que elas estão debatendo, o que as leva a falar sobre coisas diferentes enquanto pensam falar sobre a mesma coisa.&lt;/p&gt;

&lt;p&gt;Isso acontece pois ela não nasce de uma base formal que pode ser identificada como fonte primária das discussões tal como o paradigma estruturado/procedural - que nasce do  &lt;a href="https://cse.buffalo.edu/~rapaport/111F04/greatidea3.html" rel="noopener noreferrer"&gt;teorema Boehm-Jacopini&lt;/a&gt; e do artigo &lt;a href="https://www.cs.utexas.edu/~EWD/ewd02xx/EWD215.PDF" rel="noopener noreferrer"&gt;Go-to statement considered harmful&lt;/a&gt; - ou do funcional que nasce do &lt;a href="https://pt.wikipedia.org/wiki/C%C3%A1lculo_lambda" rel="noopener noreferrer"&gt;cálculo lambda&lt;/a&gt;, pelo contrário, tecnicamente, ela tem duas história de origens diferentes, o que dificulta muito as coisas, afinal é complicado até mesmo dizer quem foi a primeira linguagem orientada a objetos, se foi Simula ou o Smalltalk. &lt;/p&gt;

&lt;p&gt;Se você não tem contato prévio com o tema, pode estar achando tudo o que eu estou descrevendo aqui um tanto quanto estranho, afinal, todos aprendemos sobre orientação a objetos, usamos a palavra para nos comunicarmos diariamente, e tudo parece seguir normalmente, sem ruídos na comunicação, não é mesmo?&lt;/p&gt;

&lt;p&gt;Pode até estar pensando que é muito fácil visto que mesmo se olharmos em fontes diferentes como um &lt;a href="https://www.devmedia.com.br/os-4-pilares-da-programacao-orientada-a-objetos/9264#:~:text=A%20maior%20parte%20das%20linguagens,ligam%20a%20televis%C3%A3o%20est%C3%A3o%20encapsulados." rel="noopener noreferrer"&gt;tutorial genérico&lt;/a&gt; na internet, a &lt;a href="https://en.wikipedia.org/wiki/Object-oriented_programming" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;, ou até se passarmos pelo &lt;a href="https://edisciplinas.usp.br/mod/resource/view.php?id=28243" rel="noopener noreferrer"&gt;ensino formal&lt;/a&gt; (como um curso técnico ou faculdade), vamos encontrar definições bem semelhantes à algo que eu chamo de: os 4 pílares da orientação a objetos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Abstração;&lt;/li&gt;
&lt;li&gt;Encapsulamento;&lt;/li&gt;
&lt;li&gt;Herança;&lt;/li&gt;
&lt;li&gt;Polimorfismo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Só que isso na verdade só conta uma parte da história, pois como apontei anteriormente, na verdade, existem &lt;a href="https://stereobooster.github.io/two-big-schools-of-object-oriented-programming" rel="noopener noreferrer"&gt;duas escolas diferentes de pensamento orientado a objetos&lt;/a&gt;, uma que cresceu baseada na tradição criada no Simula, e desenvolvida e popularizada pelo C++, e outra que cresceu na tradição criada pelo Smalltalk.&lt;/p&gt;

&lt;p&gt;Mesmo que possamos aceitar o lado vencedor da história na tradição do C++ (visto que a grande maioria das linguagens consideradas OO atualmente seguem mais pelas suas ideias do que pelas de Smalltalk), ou seja, do legado de Simula que evoluiu nos 4 pílares, não se tem um consenso sobre se eles são exatamente esses 4 ou se realmente deveriam ser 4. Por exemplo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O próprio criador da linguagem C++ considera uma definição que só possui &lt;a href="https://www.stroustrup.com/oopsla.pdf" rel="noopener noreferrer"&gt;3 pílares&lt;/a&gt; (abstração, herança, e polimorfismo);&lt;/li&gt;
&lt;li&gt;A linguagem Eiffel considera outro conjunto de &lt;a href="https://www.eiffel.org/doc/glossary/Glossary#Object-oriented" rel="noopener noreferrer"&gt;6 princípios&lt;/a&gt; (classes, asserções, genericidade, herança, polimorfismo, e &lt;em&gt;dinamyc binding&lt;/em&gt;);&lt;/li&gt;
&lt;li&gt;O criador da linguagem Smalltalk diz que o que ele quis dizer ao cunhar o termo &lt;a href="https://lists.squeakfoundation.org/pipermail/squeak-dev/1998-October/017019.html" rel="noopener noreferrer"&gt;não é nada disso que usamos atualmente&lt;/a&gt;, e descreve que na verdade se resume a &lt;a href="https://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en" rel="noopener noreferrer"&gt;3 princípios&lt;/a&gt; (Troca de mensagens, encapsulamento, e Late-binding extremo de todas as coisas);&lt;/li&gt;
&lt;li&gt;A linguagem Ada define apenas &lt;a href="https://ada-lang.io/docs/style-guide/s9/" rel="noopener noreferrer"&gt;3 princípios&lt;/a&gt; (encapsulamento, herança, e polimorfismo);&lt;/li&gt;
&lt;li&gt;A linguagem Self se baseia em &lt;a href="https://dl.acm.org/doi/pdf/10.1145/38807.38828" rel="noopener noreferrer"&gt;3 ideias&lt;/a&gt;(protótipos, slots, e comportamentos) que apesar de terem outros nomes, são equivalentes a termos usados em outras definições (herança, campos, e troca de mensagens);&lt;/li&gt;
&lt;li&gt;A linguagem Java define &lt;a href="https://docs.oracle.com/javase/specs/jls/se6/jls3.pdf" rel="noopener noreferrer"&gt;5 conceitos&lt;/a&gt; (encapsulamento, campos, herança, métodos, e objetos);&lt;/li&gt;
&lt;li&gt;A linguagem C# segue os &lt;a href="https://learn.microsoft.com/pt-br/dotnet/csharp/fundamentals/tutorials/oop" rel="noopener noreferrer"&gt;4 pílares&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;O criador da linguagem Simula admite não existir uma definição concreta, mas cita alguns conceitos que acredita serem &lt;a href="https://www.mn.uio.no/ifi/english/about/ole-johan-dahl/bibliography/the-birth-of-object-orientation-the-simula-languages.pdf" rel="noopener noreferrer"&gt;comuns as linguagens consideradas orientadas a objeto&lt;/a&gt; (objetos, classes, herança, polimorfismo);&lt;/li&gt;
&lt;li&gt;A linguagem Python cita &lt;a href="https://docs.python.org/3/tutorial/classes.html" rel="noopener noreferrer"&gt;4 conceitos&lt;/a&gt; como orientados a objeto (classes, objetos, herança, e polimorfismo);&lt;/li&gt;
&lt;li&gt;A linguagem Ruby &lt;a href="https://ruby-doc.com/docs/ProgrammingRuby/" rel="noopener noreferrer"&gt;afirma seguir a definição de Smalltalk&lt;/a&gt;, com grande enfase nas ideias de que tudo deveria ser um objeto, e troca de mensagens;&lt;/li&gt;
&lt;li&gt;A linguagem PHP não possui uma definição oficial sobre orientação a objetos, mas podemos derivar que ela segue algo como os 4 pílares com base nas &lt;a href="https://www.php.net/oop" rel="noopener noreferrer"&gt;funcionalidades que ele apresenta como orientadas a objeto&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;A linguagem Objective-C não possui uma definição oficial sobre orientação a objetos, mas seu manual sugere a seguinte combinação de conceitos (tudo é um objeto, classes, troca de mensagens, encapsulamento, herança, e polimorfismo);&lt;/li&gt;
&lt;li&gt;O site MDN, em sua seção sobre a linguagem JavaScript considera &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object-oriented_programming" rel="noopener noreferrer"&gt;3 conceitos&lt;/a&gt; (classes e objetos, herança e encapsulamento);&lt;/li&gt;
&lt;li&gt;Grady Booch, autor do livro &lt;a href="https://zjnu2017.github.io/OOAD/reading/Object.Oriented.Analysis.and.Design.with.Applications.3rd.Edition.by.Booch.pdf" rel="noopener noreferrer"&gt;Object-Oriented Analysis and Design With Applications&lt;/a&gt;, define 7 princípios (abstração, encapsulamento, modularidade, hierarquia, tipagem, concorrência, e persistência);&lt;/li&gt;
&lt;li&gt;A GoF (Gang of Four: Erich Gamma, Richard Helm, Ralph Johnson, e John Vlissides), em seu livro &lt;a href="https://www.javier8a.com/itc/bd1/articulo.pdf" rel="noopener noreferrer"&gt;Design Patterns : Elements of Reusable Object-Oriented Software&lt;/a&gt; cita encapsulamento, herança e polimorfismo como "padrões de projeto" numa linguagem procedural;&lt;/li&gt;
&lt;li&gt;Peter Van Roy, em seu livro &lt;a href="https://ia902308.us.archive.org/15/items/c-15_20211009/C15.pdf" rel="noopener noreferrer"&gt;Concepts, Techiniques, and Models of Computer Programming&lt;/a&gt;, descreve OO em 4 items (objetos como mecanismo de abstração, estado explícito, polimorfismo, e herança);&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://www.iso.org/obp/ui/#iso:std:iso-iec:2382:ed-1:v2:en" rel="noopener noreferrer"&gt;ISO/IEC 2382 item 2122503&lt;/a&gt;, que é o mais próximo que a gente tem de uma definição formal, considera 6 princípios (abstração, encapsulamento, herança, polimorfismo, troca de mensagens, e &lt;em&gt;dynamic binding&lt;/em&gt;);&lt;/li&gt;
&lt;li&gt;Yegor Bugayenko, define por meio de um modelo formal criado por ele chamado de &lt;a href="https://arxiv.org/pdf/2111.13384" rel="noopener noreferrer"&gt;phi-calculus&lt;/a&gt;, implementado na sua linguagem EOLANG;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://wiki.c2.com/?ObjectOrientedProgramming" rel="noopener noreferrer"&gt;etc...&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Definindo uma perspectiva
&lt;/h2&gt;

&lt;p&gt;Dessa forma, assim como Bjarne Stroustrup (criador do C++) argumenta em sua definição de orientação a objetos: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Qualquer definição de "orientação a objetos" deveria ser históricamente aceitável. Palavras são apenas úteis para comunicação, elas apenas significiam alguma coisa, se concordarmos em um significado para elas.&lt;/p&gt;

&lt;p&gt;~ &lt;a href="https://www.stroustrup.com/oopsla.pdf" rel="noopener noreferrer"&gt;Bjarne Stroustrup&lt;/a&gt;, adaptado do inglês em tradução livre&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Por isso gostaria de adotar uma abordagem holística (analisando pelo todo ao invés de pela soam das partes) para analisar o que deve ser considerado para a minha definição. Nisso avaliarei de acordo com 4 critérios em ordem de importância:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Alinhamento conceitual com a perspectiva definida;&lt;/li&gt;
&lt;li&gt;Relevância histórica;&lt;/li&gt;
&lt;li&gt;Implementações na prática (que também será considerada a percepção no senso comum);&lt;/li&gt;
&lt;li&gt;Exclusividade para a OO (o quanto o conceito pode ser identificado como algo de orientação a objetos, ao invés de algo de paradigma X ou Y, ou um conceito mais geral);&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Vamos começar por definir o nosso ponto de partida pela história, primeiro vamos decidir qual dos lados vamos escolher como fonte primária, e então seguir com as intenções do que deveria significar orientação a objetos dos autores dela como base para nossa definição, além de usa-la como parâmetro de comparação para julgar qual conjunto de princípios faz sentido a ser enquadrado nela.&lt;/p&gt;

&lt;p&gt;Nessa questão, eu gosto da visão de que &lt;a href="https://www.hillelwayne.com/post/alan-kay/" rel="noopener noreferrer"&gt;Alan Kay inventou a "orientação a objetos", mas não os "objetos"&lt;/a&gt;, por isso nossa base vai ser a visão dele sobre o que deveria ser a orientação a objetos, que podemos resumir em algumas citações:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Apenas um gentil lembrete de que me esforcei no último OOPSLA para tentar lembrar a todos que Smalltalk não é apenas sua sintaxe ou biblioteca de classes, nem se trata de classes. Lamento ter cunhado há muito tempo o termo "objetos" para este tópico porque faz com que muitas pessoas se concentrem no ideia menor.&lt;/p&gt;

&lt;p&gt;A grande ideia é "mensagens" - é isso que o núcleo do Smalltalk/Squeak é tudo sobre...&lt;/p&gt;

&lt;p&gt;~ &lt;a href="https://lists.squeakfoundation.org/pipermail/squeak-dev/1998-October/017019.html" rel="noopener noreferrer"&gt;Alan Kay&lt;/a&gt;, adaptado do inglês em tradução livre&lt;/p&gt;

&lt;p&gt;Pensei em objetos como células biológicas e/ou individuais computadores em uma rede, capazes apenas de se comunicar por meio de mensagens (então mensagens vieram logo no início - demorou um pouco para ver como enviar mensagens em uma linguagem de programação com eficiência suficiente para ser útil).&lt;/p&gt;

&lt;p&gt;Eu queria me livrar dos dados. O B5000 quase fez isso através de seu arquitetura de HW quase inacreditável. Eu percebi que o A metáfora da célula/computador inteiro eliminaria os dados, e esse "&amp;lt;-" seria apenas mais um token de mensagem (demorei um pouco para pense nisso porque eu realmente pensei em todos esses símbolos como nomes para funções e procedimentos.&lt;/p&gt;

&lt;p&gt;Minha formação em matemática me fez perceber que cada objeto poderia ter várias álgebras associadas a ele, e poderia haver famílias de estes, e que estes seriam muito úteis. O termo o "polimorfismo" foi imposto muito mais tarde (acho que por Peter Wegner) e não é muito válido, pois na verdade vem da nomenclatura de funções, e eu queria um pouco mais do que funções. Eu inventei um termo "genericidade" para lidar com comportamentos genéricos em um forma quase algébrica.&lt;/p&gt;

&lt;p&gt;Não gostei da maneira como o Simula I ou o Simula 67 fizeram a herança (embora eu pensasse que Nygaard e Dahl eram apenas tremendos pensadores e designers). Então decidi deixar de fora a herança como uma funcionalidade built-in até que eu entendesse melhor.&lt;/p&gt;

&lt;p&gt;~ &lt;a href="https://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en" rel="noopener noreferrer"&gt;Alan Kay&lt;/a&gt;, adaptado do inglês em tradução livre&lt;/p&gt;

&lt;p&gt;POO para mim significa apenas troca de mensagens, retenção local dos dados e proteção e ocultamento do estado, e extremo &lt;em&gt;late binding&lt;/em&gt; de todas as coisas.&lt;/p&gt;

&lt;p&gt;~ &lt;a href="https://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en" rel="noopener noreferrer"&gt;Alan Kay&lt;/a&gt;, adaptado do inglês em tradução livre&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Com isso podemos concluir que a &lt;strong&gt;perspectiva&lt;/strong&gt; pelo qual vemos um programa orientado a objetos usando as definições de Kay, é a seguinte:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Um programa é visto como uma rede de objetos se comunicando por meio de troca de mensagens, no qual se busca programar evitando os dados, focando nas interações, de forma que uma mensagem possa carregar vários significados.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Falando em perspectiva, esse é a seção utilizado pelos criadores de Simula em seu livro &lt;a href="https://citeseerx.ist.psu.edu/document?repid=rep1&amp;amp;type=pdf&amp;amp;doi=8f1492ddefd8d9864d43f259761f90e6f0b27d36" rel="noopener noreferrer"&gt;Object-Oriented Programming in the BETA Programming Language&lt;/a&gt; para descrever o framework conceitual de um framework, ou seja, uma descrição de como enxergamos a estrutura de um programa escrito em determinado paradigma, por exemplo no caso da programação procedural, eles a descrevem como:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A execução de um programa é considerada uma sequência (parcialmente ordenada) de chamadas de procedimento que manipulam variáveis.&lt;/p&gt;

&lt;p&gt;~ &lt;a href="https://citeseerx.ist.psu.edu/document?repid=rep1&amp;amp;type=pdf&amp;amp;doi=8f1492ddefd8d9864d43f259761f90e6f0b27d36" rel="noopener noreferrer"&gt;Nygaard at all&lt;/a&gt;, adaptado do inglês em tradução livre&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No caso da funcional:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Um programa é considerado uma função matemática, que descreve uma relação entre entrada e saída.&lt;/p&gt;

&lt;p&gt;~ &lt;a href="https://citeseerx.ist.psu.edu/document?repid=rep1&amp;amp;type=pdf&amp;amp;doi=8f1492ddefd8d9864d43f259761f90e6f0b27d36" rel="noopener noreferrer"&gt;Nygaard at all&lt;/a&gt;, adaptado do inglês em tradução livre&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;E para a orientação a objetos:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A execução de um programa é considerada um modelo físico, simulando o comportamento de uma parte real ou imaginária do mundo.&lt;/p&gt;

&lt;p&gt;~ &lt;a href="https://citeseerx.ist.psu.edu/document?repid=rep1&amp;amp;type=pdf&amp;amp;doi=8f1492ddefd8d9864d43f259761f90e6f0b27d36" rel="noopener noreferrer"&gt;Nygaard at all&lt;/a&gt;, adaptado do inglês em tradução livre&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Assim, mesmo que nosso foco seja na definição de Alan Kay, dado as grandes contribuições de Krysten Nygaard e Ole-Johan Dahl (criadores do Simula) no que diz respeito as funcionalidades encontradas em linguagens orientadas a objeto, e em quão bem sua perspectiva envelheceu ao longo do tempo, visto que quase todo tutorial moderno ainda segue essa história que os objetos representam conceitos do mundo real, sendo até formalizado como parte da definição de abstração, eu diria que é adequado incorporar suas visões na nossa definição final.&lt;/p&gt;

&lt;p&gt;Dessa forma, onde puder ser feito um argumento em favor da conciliação das duas tradições numa definição unificada, assim respeitando nossa abordagem de uma análise holística, eu tentarei.&lt;/p&gt;

&lt;p&gt;Por isso, como ela não é necessariamente exclusiva a nossa definição atual, podemos incrementar ela com o seguinte:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Um programa é visto como uma rede de objetos, sendo estes representações de conceitos do domínio, se comunicando por meio de troca de mensagens, no qual se busca programar evitando os dados, focando nas interações, de forma que uma mensagem possa carregar vários significados. Sendo sua estrutura geral algo semelhante a uma simulação do comportamento de uma parte real ou imaginária do mundo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Uma consideração que pode ser feita é que isso pode direcionar as pessoas a focarem na "ideia menor", mas assim como admitimos antes é necessário reconhecer como as ideias evoluem ao longo do tempo pois uma palavra só tem valor se as pessoas entendem o que ela quer comunicar, portanto eu acredito que esta perspectiva encontra balanço o suficiente entre manter os objetivos iniciais de Alan Kay, e incorporar os valores do sistema de objetos de Nygaard e Dahl.&lt;/p&gt;

&lt;h2&gt;
  
  
  Definindo conceitos
&lt;/h2&gt;

&lt;p&gt;Com o texto atual da definição, eu já poderia me dar por satisfeito, sendo essa a minha resposta a questão apresentada neste artigo, mas eu acredito que uma definição completa de um paradigma deveria incluir tanto a sua "perspectiva" do que representa a execução de um programa, quanto um conjunto de princípios associados a ela.&lt;/p&gt;

&lt;p&gt;Por isso, podemos dizer que estamos na metade do caminho, e agora podemos voltar à aquela lista extensa de definições que eu dei mais cedo para buscar quais princípios se adequam a nossa perspectiva ao mesmo tempo que não traem a nossa visão base (o foco na troca de mensagens).&lt;/p&gt;

&lt;p&gt;Para isso, novamente, vamos voltar a nossa fonte primária, os princípios da OO do Smalltalk:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Troca de mensagens;&lt;/li&gt;
&lt;li&gt;Retenção local dos dados, junto com proteção e ocultamento do estado;&lt;/li&gt;
&lt;li&gt;Extremo &lt;em&gt;late binding&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se usarmos o critério de relevância histórica de novo, poderia ser argumentado que como esses termos nem se usam mais hoje (com exceção de troca de mensagens), por isso deveríamos considerar usar os 4 pílares no lugar, e, novamente, acredito que usar uma abordagem conciliadora aqui seria o melhor dos dois mundos sem contradições:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Troca de mensagens;&lt;/li&gt;
&lt;li&gt;Polimorfismo;&lt;/li&gt;
&lt;li&gt;Encapsulamento;&lt;/li&gt;
&lt;li&gt;Abstração;&lt;/li&gt;
&lt;li&gt;Herança;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Existe uma explicação para a escolha desses 5 princípios é que:&lt;/p&gt;

&lt;h3&gt;
  
  
  Troca de mensagens
&lt;/h3&gt;

&lt;p&gt;A troca de mensagens é algo inegociável dentro do contexto original da OO, afinal Alan Kay afirma ser a grande ideia do paradigma, seu conceito mais importante, por isso todos os outros conceitos devem ter algo a ver com ela.&lt;/p&gt;

&lt;p&gt;Sua adoção na prática é bem considerável até, visto que linguagens com relevância histórica como Self, Objective-C, e Ruby mantém uma forte conexão com este conceito, e o próprio Ruby é considerado uma linguagem mainstream nos dias de hoje, com grandes aplicações construídas nele como o próprio github, além de ter uma comunidade bem ativa.&lt;/p&gt;

&lt;p&gt;E eu diria que junto com herança e encapsulamento, é um dos conceitos que mais carrega a identidade da OO, visto que as outras duas instâncias (piada proposital) onde o termo é usado seria no &lt;a href="https://en.wikipedia.org/wiki/Actor_model" rel="noopener noreferrer"&gt;Actor Model&lt;/a&gt;, que é um modelo matemático formal de lógica que basicamente tem quase as mesmas ideias de Alan Kay, mas é totalmente baseado em concorrência (algo como se OO fosse 100% async para vocês dev JS entenderem).&lt;/p&gt;

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

&lt;p&gt;Esse é um conceito que acerta todos os critérios de nossa análise, visto que assim como notado por Nygaard e Dahl, ele está presente em praticamente todas as linguagens que implementam o paradigma, mesmo que de forma implícita (se tem suporta a herança, implícitamente se admite o suporte a polimorfismo também).&lt;/p&gt;

&lt;p&gt;Ele está super alinhado com a ideia de troca de mensagens também, visto que é um benefício natual de seu uso. Fora que ele está presente na definição de Alan Kay (embora ele diga que prefere o termo genericidade) afinal &lt;em&gt;late binding&lt;/em&gt; é o nome do processo presente em linguagens&lt;br&gt;
de programação que permite a elas não relacionarem uma chamada a uma função com um código em específico, mas sim executarem baseado no contexto (que no caso da OO é o objeto que recebe a mensagem), sendo essa exatamente a definição de polimorfismo.&lt;/p&gt;

&lt;p&gt;Em termos de percepção pública, seria o conceito mais importante dos 5 listados, sendo definido até mesmo como a &lt;a href="https://blog.cleancoder.com/uncle-bob/2018/04/13/FPvsOO.html" rel="noopener noreferrer"&gt;essência da OO&lt;/a&gt; pelo Uncle Bob, além disso mesmo em situações onde não se planeja programar exatamente em orientação a objetos, se considera esse princípio como um bloco fundamental para a construção de algumas ideias como a arquitetura hexagonal ou a arquitetura limpa.&lt;/p&gt;

&lt;p&gt;Entretanto, o conceito não é único da OO, sendo um conceito mais geral presente ao longo de vários paradigmas, muitas vezes com implementações de &lt;a href="https://en.wikipedia.org/wiki/Polymorphism_(computer_science)" rel="noopener noreferrer"&gt;tipos diferentes&lt;/a&gt; na mesma linguagem. Apesar disso, pode-se argumentar que específicamente o polimorfismo de subtipo é único da OO, pois é um tipo dependente da capacidade da linguagem de realizar herança.&lt;/p&gt;

&lt;h3&gt;
  
  
  Encapsulamento
&lt;/h3&gt;

&lt;p&gt;Se você leu o &lt;a href="https://dev.to/terminalcoffee/voce-foi-enganado-encapsulamento-nao-e-apenas-sobre-getters-e-setters-42g4"&gt;nosso artigo&lt;/a&gt; sobre o assunto (sim, gostamos de dar pitaco sobre definições por aqui), deve saber que dizer "Retenção local dos dados, junto com proteção e ocultamento do estado" é basicamente a definição completa de encapsualmento, então o lado do alinhamento conceitual, assim como os anteriores, está 100% neste princípio aqui.&lt;/p&gt;

&lt;p&gt;Apesar de algumas linguagens não citarem o encapsulamento como princípio, o conceito está presente nelas mesmo que pela metade, o fato de ter objetos (ou como no caso de Java e Self enfatisar o conceito de campos nos objetos) mostra que elas possuem um mecanismo para menter os dados apenas sendo operados num contexto local junto as suas funções (o próprio objeto em si), por outro lado linguagens como o C++ e Eiffel apresentam mecanismos para proteção e ocultamento do estado na forma de modificadores de acesso (C++) ou asserções, pré-condições, pós-condições, e invariantes (Eiffel). Em Java mesmo temos um dos artigos mais famosos sobre a orientação a objetos que discute exatamente a aplicação do encapsulamento: &lt;a href="https://www.infoworld.com/article/2073723/why-getter-and-setter-methods-are-evil.html" rel="noopener noreferrer"&gt;Why getters and setters are evil&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Então eu diria que é um princípio que amadureceu muito bem no teste do tempo, apesar de ainda poder sofrer das mesmas críticas do polimorfismo já que não é um conceito associado exclusivamente com a OO, uma vez que é possível realizar ele com módulos (o que seria semelhante a ter um objeto singleton), ou closures, visto que elas podem atuar como objetos de pobre, entretanto, assim como no caso do polimorfismo, o conceito é aplicado "com um sabor único" na OO, visto que o mecanismo de retenção local dos dados é o objeto, e o ocultamento das informações ocorre por meio dos modificadores de acesso, essa sim uma funcionalidade amplamente associada com o paradigma.&lt;/p&gt;

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

&lt;p&gt;Ela não aparece tanto quanto o resto dos 4 pílares, entretanto, similar ao encapsulamento, sua presença ainda pode ser sentida de forma implícita ao invés de explícita, visto que, com exceção de Self, todas as linguagens mencionadas dispõe de um mecanismo de abstração de dados na forma das classes.&lt;/p&gt;

&lt;p&gt;Adentrando na questão do Self, ele dá grande enfase nos objetos em si e na troca de mensagens, o que nos podemos aproveitar para analisar a questão do alinhamento conceitual, que nesse caso, eu diria que programar com troca de mensagens, em palavras mais modernas (apesar dos conceitos não serem exatamente a mesma coisa) seria o mesmo que "programar para uma interface", ou seja, programar apenas com abstrações, sem se preocupar com como a implementação final vai ser de fato, método esse muito bem descrito no livro &lt;a href="https://rmod-files.lille.inria.fr/FreeBooks/ByExample/SmalltalkByExampleNewRelease.pdf" rel="noopener noreferrer"&gt;Smalltalk by Example: The Developer's Guide&lt;/a&gt;, de Alec Sharp, como sendo "a forma orientada a objetos de se programar".&lt;/p&gt;

&lt;p&gt;A ideia de abstração em conjunto com o polimorfismo que permite que toda metáfora de troca de mensagens funcione, pois a ideia é que não tem como saber qual vai ser o resultado da execução do código apenas olhando para as mensagens, afinal elas são abstrações (no mesmo sentido de que não dá para saber como as coisas vão executar ao ler os métodos de uma interface na OO moderna), e o resultado depende de suas implementações concretas que se encontram nos objetos em si, logo, a execução pode variar dependendo de qual objeto responde à aquela mensagem.&lt;/p&gt;

&lt;p&gt;De todos os princípios, eu diria que a abstração é o mais fraco no critério de exclusividade, visto que abstração de dados é um princípio geral, acima do conceito de paradigmas como afirma Peter Van Roy no seu artigo &lt;a href="https://webperso.info.ucl.ac.be/~pvr/VanRoyChapter.pdf" rel="noopener noreferrer"&gt;Programming Paradigms for Dummies&lt;/a&gt;, apesar disso, novamente, estamos numa situação semelhante aos outros princípios no qual ela se utiliza de um mecanismo extremamente característico na forma das classes, que são amplamente reconhecidas como uma funcionalidade de OO, tão reconhecidas que muitas pessoas pensam que o paradigma se resume a programar com classes (esquecendo até dos objetos, e pior ainda, das mensagens no processo).&lt;/p&gt;

&lt;h3&gt;
  
  
  Herança
&lt;/h3&gt;

&lt;p&gt;Ela está aqui pelo motivo oposto a troca de mensagens, se a troca de mensagens tem baixa pontuação de percepção pública, mas a mais altíssima em alinhamento conceitual, a herança tem o menor alinhamento conceitual dos conceitos selecionados (o que pode ser confirmado com a citação de que Alan Kay apenas adicionou herança em Smalltalk pois não sabia muito bem para quê ia servir direito, mas pensou que talvez fosse ser útil), mas possui a maior percepção pública, além de altíssimas contribuições históricas.&lt;/p&gt;

&lt;p&gt;Para começar que ela era uma das princípais funcionalidades de Simula, era tida como a essência da OO, na era pós Smalltalk, embora isso tenha sido completamente invertido após a públicação da ideia de composição ao invés de herança pelo GoF.&lt;/p&gt;

&lt;p&gt;Apesar disso, é o único conceito exclusivamente associado com a OO, sendo uma funcionalidade cujo a presença já seria o suficiente para diferenciar uma linguagem como orientada a objetos em muitos casos. Sendo os únicos argumentos que poderiam ir contra isso a ideia de &lt;em&gt;records&lt;/em&gt; de Hoare, mas ela foi o que deu origem a herança em Simula, e product types, mas esse é um assunto bem diferente de herança, e nem se sofre dos mesmos problemas e polêmicas.&lt;/p&gt;

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

&lt;p&gt;Finalmente temos ambos a perspectiva e os princípios, por isso nossa definição final fica:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Um programa orientado a objetos é visto como uma rede de objetos, sendo estes representações de conceitos do domínio, se comunicando por meio de troca de mensagens, no qual se busca programar evitando os dados, focando nas interações, de forma que uma mensagem possa carregar vários significados. Cujo os princípios são a troca de mensagens, polimorfismo, encapsulamento, abstração, e a herança. Tendo como estrutura geral algo semelhante a uma simulação do comportamento de uma parte real ou imaginária do mundo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Enfim, essa é a minha resposta final para a pergunta apresentada no título do artigo, essa pesquisa toda deu bastante trabalho, então espero que o texto possa pelo menos ter te ensinado algo novo, ou levando algumas reflexões.&lt;/p&gt;

&lt;p&gt;Caso concorde, ou discorde da minha definição não se esqueça de compartilhar sua opinião nos comentário, e até a próxima!&lt;/p&gt;

&lt;h2&gt;
  
  
  Links que podem te interessar
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Programming_paradigm" rel="noopener noreferrer"&gt;Wikipedia sobre paradigmas de programação&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Polymorphism_(computer_science)" rel="noopener noreferrer"&gt;Wikipedia sobre polimorfismo&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://wiki.c2.com/?NobodyAgreesOnWhatOoIs" rel="noopener noreferrer"&gt;C2 Wiki - Nobody Agrees On What OO Is&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://wiki.c2.com/?ObjectOrientedProgramming" rel="noopener noreferrer"&gt;C2 Wiki - Object Oriented Programming&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pt.stackoverflow.com/a/88685" rel="noopener noreferrer"&gt;Stackoverflow - Significado da terminologia "Orientado a objeto"&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://arxiv.org/pdf/2111.13384" rel="noopener noreferrer"&gt;EOLANG and Phi-Calculus&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ia902308.us.archive.org/15/items/c-15_20211009/C15.pdf" rel="noopener noreferrer"&gt;Concepts, Techniques, and Models of Computer Programming&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://webperso.info.ucl.ac.be/~pvr/VanRoyChapter.pdf" rel="noopener noreferrer"&gt;Programming Paradigms for Dummies&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://rmod-files.lille.inria.fr/FreeBooks/ByExample/SmalltalkByExampleNewRelease.pdf" rel="noopener noreferrer"&gt;Smalltalk by Example&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://citeseerx.ist.psu.edu/document?repid=rep1&amp;amp;type=pdf&amp;amp;doi=8f1492ddefd8d9864d43f259761f90e6f0b27d36" rel="noopener noreferrer"&gt;Object-Oriented Programming in the BETA Programming Language&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.stroustrup.com/oopsla.pdf" rel="noopener noreferrer"&gt;Why C++ is not just an Object-Oriented Programming Language&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en" rel="noopener noreferrer"&gt;Dr. Alan Kay on the meaning of "Object Oriented Programming"&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.mn.uio.no/ifi/english/about/ole-johan-dahl/bibliography/the-birth-of-object-orientation-the-simula-languages.pdf" rel="noopener noreferrer"&gt;The Birth of Object Orientation: the Simula Languages&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://stereobooster.github.io/two-big-schools-of-object-oriented-programming" rel="noopener noreferrer"&gt;Two big schools of Object-Oriented Programming&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.iso.org/obp/ui/#iso:std:iso-iec:2382:ed-1:v2:en" rel="noopener noreferrer"&gt;ISO/IEC 2382:2015&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/pavel-krivanek/articles/tree/master/SelfObjectModel" rel="noopener noreferrer"&gt;SelfObjectModel&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://handbook.selflanguage.org/2017.1/index.html" rel="noopener noreferrer"&gt;The Self Handbook&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dl.acm.org/doi/pdf/10.1145/38807.38828" rel="noopener noreferrer"&gt;Self: The Power of Simplicity&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://lukasatkinson.de/2016/dynamic-vs-static-dispatch/" rel="noopener noreferrer"&gt;Dynamic vs. Static Dispatch&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://lukasatkinson.de/dump/2023-08-25-interpretations-of-oop/" rel="noopener noreferrer"&gt;(Wrong) Interpretations of OOP&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://lukasatkinson.de/2015/emerging-objects/" rel="noopener noreferrer"&gt;Emerging Objects Building a simple object system out of closures&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://lukasatkinson.de/2015/mopping-it-up/" rel="noopener noreferrer"&gt;MOPping it up Building a simple Metaobject-Protocol&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://lukasatkinson.de/2018/interface-dispatch/" rel="noopener noreferrer"&gt;Interface Dispatch&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://curtispoe.org/articles/alan-kay-and-oo-programming.html" rel="noopener noreferrer"&gt;Alan Kay and OO Programming&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.hillelwayne.com/post/alan-kay/" rel="noopener noreferrer"&gt;Alan Kay Did Not Invent Objects&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://lists.squeakfoundation.org/pipermail/squeak-dev/1998-October/017019.html" rel="noopener noreferrer"&gt;prototypes vs classes was: Re: Sun's HotSpot&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://apps.dtic.mil/sti/pdfs/AD0731349.pdf" rel="noopener noreferrer"&gt;On the Future of Computer Program Specification and Organization&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.rand.org/content/dam/rand/pubs/research_memoranda/2007/RM5290.pdf" rel="noopener noreferrer"&gt;Dataless Programming&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://worrydream.com/EarlyHistoryOfSmalltalk/#p2" rel="noopener noreferrer"&gt;The early story of Smalltalk&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.cs.utexas.edu/~EWD/ewd02xx/EWD215.PDF" rel="noopener noreferrer"&gt;Go-to statement considered harmful&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cse.buffalo.edu/~rapaport/111F04/greatidea3.html" rel="noopener noreferrer"&gt;Teorema Boehm-Jacopini&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.eiffel.org/doc/glossary/Glossary#Object-oriented" rel="noopener noreferrer"&gt;Eiffel sobre OO&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.devmedia.com.br/os-4-pilares-da-programacao-orientada-a-objetos/9264#:~:text=A%20maior%20parte%20das%20linguagens,ligam%20a%20televis%C3%A3o%20est%C3%A3o%20encapsulados." rel="noopener noreferrer"&gt;Devmedia sobre OO&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pt.wikipedia.org/wiki/C%C3%A1lculo_lambda" rel="noopener noreferrer"&gt;Wikipedia sobre calculo lambda&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ada-lang.io/docs/style-guide/s9/" rel="noopener noreferrer"&gt;Ada sobre OO&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.oracle.com/javase/specs/jls/se6/jls3.pdf" rel="noopener noreferrer"&gt;Especificação do Java 3° edição&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://learn.microsoft.com/pt-br/dotnet/csharp/fundamentals/tutorials/oop" rel="noopener noreferrer"&gt;C# sobre OO&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.python.org/3/tutorial/classes.html" rel="noopener noreferrer"&gt;Python sobre OO&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.php.net/oop" rel="noopener noreferrer"&gt;PHP sobre OO&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ruby-doc.com/docs/ProgrammingRuby/" rel="noopener noreferrer"&gt;Doc do Ruby&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object-oriented_programming" rel="noopener noreferrer"&gt;MDN sobre OO&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://zjnu2017.github.io/OOAD/reading/Object.Oriented.Analysis.and.Design.with.Applications.3rd.Edition.by.Booch.pdf" rel="noopener noreferrer"&gt;Object-Oriented Analysis and Design With Applications&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.javier8a.com/itc/bd1/articulo.pdf" rel="noopener noreferrer"&gt;Livro do Design Patterns&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.infoworld.com/article/2073723/why-getter-and-setter-methods-are-evil.html" rel="noopener noreferrer"&gt;Why getters and setters are evil&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://blog.cleancoder.com/uncle-bob/2018/04/13/FPvsOO.html" rel="noopener noreferrer"&gt;Clean Coder Blog - FP vs. OO&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Actor_model" rel="noopener noreferrer"&gt;Wikipedia sobre Actor Model&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://doc.akka.io/docs/akka/current/typed/guide/actors-intro.html" rel="noopener noreferrer"&gt;Akka (linguagem de programação) sobre Actor Model&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://stately.ai/blog/what-is-the-actor-model" rel="noopener noreferrer"&gt;Stately sobre Actor Model&lt;/a&gt;;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ass: Suporte cansado&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>oop</category>
      <category>programming</category>
    </item>
    <item>
      <title>Personas - Como perfis psicográficos moldaram o game design</title>
      <dc:creator>Terminal Coffee</dc:creator>
      <pubDate>Sun, 28 Jul 2024 22:18:31 +0000</pubDate>
      <link>https://dev.to/terminalcoffee/personas-como-perfis-psicograficos-moldaram-o-game-design-5402</link>
      <guid>https://dev.to/terminalcoffee/personas-como-perfis-psicograficos-moldaram-o-game-design-5402</guid>
      <description>&lt;p&gt;Se você se interessa pelo assunto de UX Design já deve ter se deparado com o conceito de personas, e talvez não tenha dado tanto valor quanto deveria, por isso no post de hoje vamos ver como game designers aplicaram isso na área de jogos de carta para planejar as evoluções do conhecido Magic: The Gathering (MTG), assim analisando como esse conceito simples foi utilizado para causar impacto positivo num produto da vida real.&lt;/p&gt;

&lt;h1&gt;
  
  
  O que são personas
&lt;/h1&gt;

&lt;p&gt;Persona aqui não se refere a uma série de jogos, mas sim a um conceito aplicado na área de UX Design onde se é criado uma representação fictícia de um usuário ideal para um determinado produto, serviço, site ou marca.&lt;/p&gt;

&lt;p&gt;A ideia seria facilitar o processo de se empatizar com o seu público-alvo imaginando como um usuário ideal dentro desse grupo seria, seu nome, o que faz, quais os seus gostos, o que não gosta, etc. Assim, a partir disso, tentar imaginar como essa pessoa interagiria com o seu produto/serviço, e quais suas reações quanto a ele, de forma a encontrar os seus pontos positivos e negativos, fornecendo uma ótima fundação para que se começa a pensar em como melhorar ou projetar a experiência desse produto/serviço.&lt;/p&gt;

&lt;p&gt;Normalmente, se criam várias personas de forma a capturar os diversos tipos de usuários que podemos ter, por isso antes de se criar qualquer persona é necessário que pesquisas sejam feitas com os usuários para entender quais os seus perfis, e coletar os detalhes que iremos utilizar para formar as nossas personas depois, pois elas devem capturar os aspectos-chave desse público.&lt;/p&gt;

&lt;p&gt;As informações que buscamos coletar durante esse processo, geralmente, são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dados demográficos (idade, sexo, localização, ocupação, etc);&lt;/li&gt;
&lt;li&gt;Relacionamento com seu produto/serviço, no caso como eles interagem com ele;&lt;/li&gt;
&lt;li&gt;Quais objetivos eles possuem ao utilizar/consumir o seu produto/serviço;&lt;/li&gt;
&lt;li&gt;As suas dores, ou seja, quais problemas, frustrações, e aspectos negativos em geral ele tem durante seu uso;&lt;/li&gt;
&lt;li&gt;As suas motivações, afinal se tudo fosse dores, seu produto não estaria sendo utilizado, precisamos coletar os pontos positivos também né? Aqui descobrimos as razões pelo qual o seu produto/serviço é utilizado;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Elas podem ser coletadas de diversas maneiras como entrevistas, questionários, dados coletados durante o uso, trabalho de campo, ou seja, indo observar os seus usuários em seu ambiente natural pessoalmente, etc.&lt;/p&gt;

&lt;p&gt;Assim, após analisar todos esses dados, podemos criar uma persona, por exemplo:&lt;/p&gt;

&lt;h4&gt;
  
  
  Persona: Maria Silva
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Nome&lt;/strong&gt;&lt;br&gt;
Maria Silva&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Idade&lt;/strong&gt;&lt;br&gt;
34 anos&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sexo&lt;/strong&gt;&lt;br&gt;
Feminino&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Localização&lt;/strong&gt;&lt;br&gt;
São Paulo, SP&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ocupação&lt;/strong&gt;&lt;br&gt;
Gerente de Marketing&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Biografia&lt;/strong&gt;&lt;br&gt;
Maria é uma profissional de marketing digital que vive em São Paulo. Ela adora aprender sobre novas tendências em marketing e está sempre procurando ferramentas que a ajudem a otimizar suas campanhas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comportamentos&lt;/strong&gt;&lt;br&gt;
Usa redes sociais diariamente, lê blogs de marketing, participa de webinars.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Objetivos&lt;/strong&gt;&lt;br&gt;
Aumentar o engajamento das campanhas de marketing, melhorar a conversão de leads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Frustrações&lt;/strong&gt;&lt;br&gt;
Falta de tempo para analisar dados, dificuldade em acompanhar todas as novidades do mercado.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Motivações&lt;/strong&gt;&lt;br&gt;
Ver os resultados de suas campanhas, ganhar reconhecimento profissional.&lt;/p&gt;

&lt;h2&gt;
  
  
  Perfis psicográficos em MTG: um caso da vida real
&lt;/h2&gt;

&lt;p&gt;Agora que introduzimos todo mundo ao assunto, vamos a parte mais interessante do artigo de hoje: como o time de game design do jogo de cartas Magic: The Gathering (MTG) integrou o conceito de personas na prática no processo de desenvolvimento do jogo.&lt;/p&gt;

&lt;p&gt;Existe um &lt;a href="https://magic.wizards.com/en/news/making-magic/timmy-johnny-and-spike-2013-12-03" rel="noopener noreferrer"&gt;artigo&lt;/a&gt; no blog oficial do cardgame onde Mark Rosewater, colunista e designer-chefe do &lt;a href="https://magic.wizards.com/" rel="noopener noreferrer"&gt;MTG.com&lt;/a&gt;, conta que o seu time tinha a missão de criar um jogo que fizesse os jogadores felizes, e para tal, eles precisavam descobrir o que fazia os jogadores felizes, nisso eles realizaram a sua pesquisa se utilizando de vários métodos como: questionários, grupos focais, monitoraram sites de Magic, conversaram com os jogares pessoalmente, e até mesmo analisaram quais artigos no site oficial os usuários mais visualizavam.&lt;/p&gt;

&lt;p&gt;Após vários anos coletando e analisando esses dados, eles chegaram a conclusão que haviam 3 tipos de jogadores, no qual eles nomearam esses tipos como "perfis psicográficos" que citamos anteriormente.&lt;/p&gt;

&lt;p&gt;A ideia de perfis psicográficos que eles chegaram é basicamente a ideia de personas que nós estudamos até aqui, no caso do time do MTG, eles representam coisas como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O que motiva esse perfil a jogar?&lt;/li&gt;
&lt;li&gt;Quais cartas ele gosta?&lt;/li&gt;
&lt;li&gt;O que o encoraja a continuar jogando?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O Resultado foi a criação de 3 perfis psicográficos (personas): Timmy, Johnny, e Spike.&lt;/p&gt;

&lt;h2&gt;
  
  
  Timmy
&lt;/h2&gt;

&lt;p&gt;Timmy seria o tipo de jogador que anseia pela experiência, apesar de gostar de vencer, ele seria do tipo onde a jornada importa mais do que o destino, portanto, ele prefere realizar uma jogada muito incrível e perder uma partida à vencer várias delas de maneira apertada ou de uma forma que ele considere chata.&lt;/p&gt;

&lt;p&gt;A "experiência" nesse caso varia muito de Timmy para Timmy, por exemplo existem os que gostam de grandes monstros, feitiços com grandes efeitos, tudo o que dê a ele a sensação de poder durante a partida.&lt;/p&gt;

&lt;p&gt;Existem os que gostam do aspecto social do jogo, e apreciam a experiência em si de jogar com os amigos, ou de modos multi-player.&lt;/p&gt;

&lt;p&gt;Também existem aqueles que gostam de explorar as possibildades que o jogo tem a oferecer testando todos os tipos de arquetipos, decks, modos de jogo, estilos de jogo, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Johnny
&lt;/h2&gt;

&lt;p&gt;O Johnny seria o tipo de jogador que gosta de se expressar ao jogar MTG, ele seria o diferentão, aquele que joga com o que ninguém mais joga, gosta de demonstrar ao mundo sua criatividade através de suas jogadas inteligentes. Dessa forma, ele é um perfil que aprecia o aspecto de personalização de um deck do jogo.&lt;/p&gt;

&lt;p&gt;Assim como os Timmies, os Johnnies também variam entre si no que eles consideram uma "expressão".&lt;/p&gt;

&lt;p&gt;Existem aqueles que gostam de pegar uma carta, analisar o seu potencial, e são fascinados pela conexão que as cartas podem ter, dessa forma se especializam em montar decks em volta de uma única carta, e todas as interações que ela pode ter com outras cartas.&lt;/p&gt;

&lt;p&gt;Existem aqueles que gostam de expressar uma ideia como um deck apenas de terras, um deck que rouba todas as cartas do oponente, etc.&lt;/p&gt;

&lt;p&gt;Também existem aqueles que gostam de remar contra a maré, eles não são convencidos que um deck não funciona, que algo é ruim, etc. Se não funciona, eles vão fazer funcionar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Spike
&lt;/h2&gt;

&lt;p&gt;MTG é um jogo onde o conceito de vitória existe, logo, grande parte de seus jogares são do tipo competitivo, e é exatamente isso que os Spikes representam: o meta player. Eles querem provar algo: o quão bons eles são. O que o motiva é a vitória, pois ela é uma prova de suas habilidades ao mundo, da mesma forma, ao contrário dos Timmies, ele odeia perder.&lt;/p&gt;

&lt;p&gt;Existem Spikes que buscam sempre o novo deck que vai dominar o meta do jogo, assim como alguns Johnnies, gostam de analisar as cartas do jogo, suas interações, julgar o seu potencial, e sempre buscar por novos decks, no entanto, ao contrário dos Johnnies, eles o fazem para encontrar a nova melhor forma de se vencer, e não pela descoberta em si. Muitos Spikes nesse ramo seriam o que formam as comunidades envolvidas com theorycraft do jogo.&lt;/p&gt;

&lt;p&gt;Apesar disso, eles podem não necessariamente ligar para descobrir novos decks, lembre-se a intenção é vencer, por isso se algo funciona, eles vão usar aquilo, o objetivo é dominar algo por completo para vencer da forma mais eficiente possível.&lt;/p&gt;

&lt;p&gt;Nessa linha existem aqueles que estudam o metagame, analisando quais as forças e fraquezas dos decks mais populares, e bolando estratégias para lidar com cada uma dessas situações.&lt;/p&gt;

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

&lt;p&gt;Com esses perfis em mente, o time de MTG agora pode ter um alvo em suas mentes ao desenhar uma nova carta, além de conseguir tentar prever como seria a sua recepção na comunidade, afinal o que agrada a um Spike pode não agradar um Johnny e vice e versa por exemplo.&lt;/p&gt;

&lt;p&gt;Dessa forma, suas decisões de design são bem mais focadas, além de darem um direcionamento em seus lançamentos de novos conjuntos de cartas, onde eles tentam adicionar cartas que podem agradar pelo menos um dos 3 perfis em cada um.&lt;/p&gt;

&lt;p&gt;Eles aprenderam muito com isso ao longo dos anos e compartilham várias de suas experiências em seu &lt;a href="https://magic.wizards.com/en/news/making-magic" rel="noopener noreferrer"&gt;blog&lt;/a&gt;, mas e você? Aprendeu algo novo no artigo de hoje? Conhecer os perfis psicográficos te fez entender melhor que tipo de jogador você é mesmo que não seja um jogador de MTG? Conta para gente aqui nos comentários e não deixe de deixar a sua reação também.&lt;/p&gt;

&lt;p&gt;Até a próxima!&lt;/p&gt;

&lt;h2&gt;
  
  
  Links que podem te interessar
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://mtg.fandom.com/wiki/Player_type" rel="noopener noreferrer"&gt;MTG Wiki - Player type&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://magic.wizards.com/en/news/making-magic/timmy-johnny-and-spike-2013-12-03" rel="noopener noreferrer"&gt;TIMMY, JOHNNY, AND SPIKE&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://magic.wizards.com/en/news/making-magic/timmy-johnny-and-spike-revisited-2006-12-18" rel="noopener noreferrer"&gt;TIMMY, JOHNNY, AND SPIKE REVISITED&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://magic.wizards.com/en/news/making-magic/designing-timmy-2009-03-05" rel="noopener noreferrer"&gt;DESIGNING FOR TIMMY&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://magic.wizards.com/en/news/making-magic/designing-johnny-2009-07-31" rel="noopener noreferrer"&gt;DESIGNING FOR JOHNNY&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://magic.wizards.com/en/news/making-magic/designing-spike-2009-11-24" rel="noopener noreferrer"&gt;DESIGNING FOR SPIKE&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://magic.wizards.com/en/news/making-magic/timmy-johnny-and-spike-2013-12-03" rel="noopener noreferrer"&gt;TIMMY, JOHNNY, AND SPIKE (Origem dos nomes)&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=veQgZDiCLlg" rel="noopener noreferrer"&gt;(YT - Golden Owl) Misunderstanding Se Jun Park's World Champion Pachirisu&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ass: Suporte cansado.&lt;/p&gt;

</description>
      <category>design</category>
      <category>braziliandevs</category>
      <category>learning</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>Você foi enganado! Encapsulamento não é apenas sobre getters e setters</title>
      <dc:creator>Terminal Coffee</dc:creator>
      <pubDate>Sun, 07 Jul 2024 13:49:14 +0000</pubDate>
      <link>https://dev.to/terminalcoffee/voce-foi-enganado-encapsulamento-nao-e-apenas-sobre-getters-e-setters-42g4</link>
      <guid>https://dev.to/terminalcoffee/voce-foi-enganado-encapsulamento-nao-e-apenas-sobre-getters-e-setters-42g4</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Quando o assunto é encapsulamento é bem comum encontrar esse princípio tão central para a OO sendo associado ou até mesmo confundido com a ideia de getters e setters, e apesar deles terem uma certa relação, encapsulamento vai muito além de simplesmente getters e setters, por isso no artigo de hoje, iremos caçar mais esse mito da orientação a objetos.&lt;/p&gt;

&lt;p&gt;Encapsulamento é um conceito meio complicado de pegar corretamente, visto que ele é um pouco abstrato, ainda mais se você vem só do paradigma procedural (lógica de programação) como conhecimento prévio, além disso ele tem várias definições, então a chance é que você já se deparou com uma que diz algo como:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Encapsulamento se refere a capacidade de controlar o acesso a um membro de um objeto&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nessa definição encapsulamento seria equivalente a um outro princípio que chamamos de &lt;em&gt;information hiding&lt;/em&gt; (ocultamento de informação), além de ser, geralmente, utilizado para se referir aos mecanismos de modificadores de acesso em linguagens orientadas a objetos, o que nos leva a ideia de getters e setters visto que o primeiro (e único muitas vezes) exemplo nos mais variados conteúdos sobre OO por ai demontram o uso dessa funcionalidade por meio dos getters e setters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Encapsulamento é sobre controlar acesso
&lt;/h2&gt;

&lt;p&gt;Ao nos depararmos com as possibilidades que linguagens orientadas a objeto nos trazem, também entramos em contato com uma nova classe (piada intencional) de problemas que esse conjunto de ferramentas nos ajuda a resolver.&lt;/p&gt;

&lt;p&gt;Por exemplo, nem todas as informações que vamos agrupar num módulo qualquer (como uma classe/objeto por exemplo) deveriam ser acessíveis fora dele, além disso existem casos onde você só quer expor ela parcialmente (por exemplo só permitir a leitura de uma informação ou só permitir a sobrescrita dela), ou controlar como ela vai ser exposta ou modificada.&lt;/p&gt;

&lt;p&gt;Para ilustrar isso considere o seguinte exemplo:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PositiveNumber&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;value&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="nf"&gt;constructor&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="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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&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="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Um número positivo deve ser maior do que 0&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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="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;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PositiveNumber&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;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui temos uma classe que representa um número positvo, ou seja, por definição, a propriedade &lt;code&gt;value&lt;/code&gt; não poderia ser um número negativo ou zero, afinal isso não seria um número positivo, então o fato de podermos fazer algo como &lt;code&gt;x.value = -1&lt;/code&gt; demonstra que é possível fazer com que esse objeto contenha um estado inválido.&lt;/p&gt;

&lt;p&gt;Para resolver isso, podemos modificar o código para que se faça um if antes de realizar a operação de atribuir um novo valor em value:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PositiveNumber&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;value&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="nf"&gt;constructor&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="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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&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="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Um número positivo deve ser maior do que 0&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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="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;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PositiveNumber&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&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;newValue&lt;/span&gt; &lt;span class="o"&gt;&amp;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="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&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;Só que isso gera um novo problema, pois não temos como garantir que um objeto &lt;code&gt;PositiveNumber&lt;/code&gt; vai ser sempre um número positivo, afinal quem garante que ele vai continuar sendo positivo é o código que usa ele, e não ele em si. Logo, se você esquecer de colocar esse if em um local que seja, isso abrirá uma brecha para que &lt;code&gt;x&lt;/code&gt; deixe de representar um número positivo, e se uma abstração mente sobre sua premissa, você constrói seu código sobre premissas falsas, o que certamente não é uma receita para o sucesso. &lt;/p&gt;

&lt;p&gt;Modificadores de acesso oferecem uma solução para esse problema, dessa forma podemos dizer &lt;strong&gt;quem&lt;/strong&gt; pode acessar determinado membro de um objeto:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;public (público) - qualquer um pode acessar, é o mesmo que não ter modificador nenhum;&lt;/li&gt;
&lt;li&gt;private (privado) - apenas o código dentro da própria classe pode acessar/modificar;&lt;/li&gt;
&lt;li&gt;protected (protegido) - apenas o código dentro da própria classe ou de classes que herdam dela podem acessar/modificar;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Atualizando o nosso exemplo ficaria algo como:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PositiveNumber&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;value&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="nf"&gt;constructor&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="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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&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="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Um número positivo deve ser maior do que 0&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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="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;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PositiveNumber&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;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&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;// Erro!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso nos permite resolver o problema de códigos que não são o próprio objeto mexam no valor &lt;strong&gt;dele&lt;/strong&gt;, se alguém tentar acessar/modificar um membro privado, isso vai gerar um erro, o que garante que estamos protegidos ao menos do código dos outros.&lt;/p&gt;

&lt;p&gt;Só que isso gera um novo problema, não tem mais como fazer nada com o &lt;code&gt;value&lt;/code&gt;, ele vai receber um valor durante a instanciação por meio do construtor, e vai ficar parado lá para sempre sem a gente poder mexer nele ou fazer qualquer coisa que seja com ele, certamente não parece ser o código mais útil do mundo.&lt;/p&gt;

&lt;p&gt;Nesse cenário que getters e setters se apresentam como uma solução para tudo isso que discutimos até qui. Eles são um padrão onde substituímos as propriedades que estamos escondendo utilizando os modificadores de acesso por métodos que representam as operações de leitura e escrita nelas, assim controlando nos mínimos detalhes até mesmo os dados do objeto:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;getter - representa a operação de leitura, então ao invés de fazer &lt;code&gt;obj.prop&lt;/code&gt; usamos um método getter &lt;code&gt;obj.getProp()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;setter - representa a operação de escrita, então ao invés de fazer &lt;code&gt;obj.prop = value&lt;/code&gt; usamos um método setter &lt;code&gt;obj.setProp(value)&lt;/code&gt;;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Isso permite que nós personalizemos a forma padrão como isso acontece nativamente no código, por exemplo, ao invés de só substituir o valor de uma propriedade ao realizar uma operação de escrita, um setter pode realizar uma validação ou transformar o dado antes dele substituir o valor original da propriedade.&lt;/p&gt;

&lt;p&gt;Veja o código utilizando eles:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PositiveNumber&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;value&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="nf"&gt;constructor&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="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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setValue&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="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;setValue&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="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&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;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&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="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Um número positivo deve ser maior do que 0&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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="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;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PositiveNumber&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;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setValue&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="c1"&gt;// Muda o value para 2&lt;/span&gt;
&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&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;// Erro!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui nós atingimos todos os critérios levantados até então:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mesmo realizando a mesma operação (escrita) em mais de um lugar (no construtor e no código que usa o objeto &lt;code&gt;x&lt;/code&gt;), a validação é aplicada todas as vezes sem falta;&lt;/li&gt;
&lt;li&gt;Limitamos o acesso a propriedade &lt;code&gt;value&lt;/code&gt; apenas a classe &lt;code&gt;PositiveNumber&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Ainda é possível realizar computações com &lt;code&gt;value&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Encapsulamento é sobre unir dados e funções
&lt;/h2&gt;

&lt;p&gt;Até o momento parece que getters e setters são uma forma bem efetiva de se aplicar o princípio do encapsulamento, ainda mais levando em conta a definição que utilizamos inicialmente, some isso com os exemplos mais comuns serem os próprios getters/setters, algumas bibliotecas te forçarem a usar o padrão, e um conselho comum ao se aprender OO ser:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Sempre mantenha as suas propriedades privadas ou protegidas&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Não é surpresa que muita gente escuta a definição formal, não entende nada, olha o mundo ao redor dela, só vê getters/setters, e chega a conclusão que, sim, encapsulamento é só usar getters e setters ou saber colocar as propriedades como private ou protected.&lt;/p&gt;

&lt;p&gt;O problema disso é que o que discutimos até aqui é só metade da definição, como disse mais cedo, se a definição fosse apenas essa não teria motivo para termos um princípio separado apenas para se referir a isso quando já tinhamos o &lt;em&gt;information hiding&lt;/em&gt; para descrever essa ideia. Uma definição melhor seria: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Encapsulamento se refere a juntar dados com as funções que operam neles, formando uma unidade com capacidade de controlar o acesso a seus membros&lt;br&gt;
~ Adaptado da &lt;a href="https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Existem definições que englobam apenas a primeira parte (juntar dados e funções), então acredito que a definição mais razoável para o termo seja essa que une ambas.&lt;/p&gt;

&lt;p&gt;A princípio pode não parecer que isso muda muito, afinal, os getters e setters, de fato, se encaixam nessa definição. O pulo do gato é quando começamos a fazer algumas reflexões sobre essa definição:&lt;/p&gt;

&lt;p&gt;Dados e funções formarem uma unidade significa que existe uma ou mais funções que usam aquele conjunto de dados representados nas propriedades de um objeto, então ao invés de fazer todas elas receberem os mesmos parâmetros repetidas vezes, nós podemos criar um objeto que permite que todas elas compartilhem dos mesmos dados.&lt;/p&gt;

&lt;p&gt;Para visualizar isso vamos supor que vamos criar um sistema de conta bancária simples:&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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Account&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;money&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&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="k"&gt;void&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;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;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="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;money&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;amount&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="nf"&gt;withdraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&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="k"&gt;void&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;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;money&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;money&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="nx"&gt;amount&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="nf"&gt;showBalance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;money&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;anAccount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Account&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;money&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nf"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;anAccount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;showBalance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;anAccount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 150&lt;/span&gt;

&lt;span class="nf"&gt;withdraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;anAccount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;125&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;showBalance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;anAccount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 25&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note como todas as funções dependem dos dados de Account para funcionar, podemos tornar esse código bem menos repetitivo, mais limpo, e evitar os problemas de dados públicos, que exploramos anteriormente, aplicando o encapsulamento para unir todas elas numa única classe nos valendo dos modificadores de acesso ao mesmo tempo:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Account&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;money&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="nf"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&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="k"&gt;void&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;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;money&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;amount&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="nf"&gt;withdraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&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;money&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&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;money&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="nx"&gt;amount&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="nf"&gt;showBalance&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&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;money&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;const&lt;/span&gt; &lt;span class="nx"&gt;anAccount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;anAccount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;anAccount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;showBalance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 150&lt;/span&gt;

&lt;span class="nx"&gt;anAccount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withdraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;125&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;anAccount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;showBalance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 25&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Encapsulamento é a arte de esconder coisas
&lt;/h2&gt;

&lt;p&gt;Isso nos permite criar uma boa abstração (trabalhar com uma conta usando termos como depositar, sacar, ou mostrar saldo, ao invés das computações realmente sendo feitas por de baixo dos panos) sem nos preocupar com como isso tudo é implementado internamente.&lt;/p&gt;

&lt;p&gt;O fato de mantermos os dados escondidos usando os modificadores de acesso, nos dá um outro benefício que é a capacidade de esconder &lt;strong&gt;COMO&lt;/strong&gt; estamos resolvendo o problema de quem usa o nosso código.&lt;/p&gt;

&lt;p&gt;Pode não parecer, mas isso é uma grande vantagem quando se trata de dar manutenção e escalar as coisas. Isso porque força quem vai usar o código a confiar na abstração que estamos provendo, ou seja nos que estamos prometendo que vamos fazer, ao invés de confiar no que estamos fazendo de fato.&lt;/p&gt;

&lt;p&gt;Programar com abstrações é muito mais fácil do que sem, é por isso que você usa uma linguagem de programação de alto nível como JS ao invés de programar a nível de máquina usando assembly por exemplo, cada coisa que torna sua vida mais fácil numa linguagem de programação advem do fato que ela está abstraindo algo complexo de você.&lt;/p&gt;

&lt;p&gt;Então nos forçar a criar abstrações melhores é um ponto positivo, outra vantagem que vem quando escondermos como estamos resolvendo o problema é que isso torna o código mais independente.&lt;/p&gt;

&lt;p&gt;Veja, se quem usa não tem acesso a como as coisas funcionam internamente, caso mudarmos completamente o código de um método, mas mantivermos ele funcionando da exata mesma forma (por exemplo trocar um algoritmo por uma versão mais performática dele), o usuário dessa função vai se beneficiar da mudança sem ter que mudar uma linha do código que ele escreveu usando ela.&lt;/p&gt;

&lt;p&gt;Podemos demonstrar isso com uma class Bhaskara que representa uma formula para cálcular equações de segundo grau:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bhaskara&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;a&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="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;b&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="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;c&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="nf"&gt;delta&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;b&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&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;a&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;c&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;x1&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="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;b&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delta&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;2&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;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;x2&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="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;b&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delta&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;2&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;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;result&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="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;x1&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;x2&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;Aqui temos uma situação onde controlar a modificação de &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt;, ou &lt;code&gt;c&lt;/code&gt; não parece impactar em nada o objeto, afinal, ao chamar qualquer um de seus métodos, simplesmente eles vão recalcular tudo com base nessa mudança.&lt;/p&gt;

&lt;p&gt;Só que se você já ouviu a frase "se está no jogo é para usar", então talvez tenha sacado qual o problema dessa versão do código, nós podemos usar as propriedades &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt;, e &lt;code&gt;c&lt;/code&gt; para mostrar elas por exemplo:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bhaskara&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Bhaskara&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="o"&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bhaskara&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso é um caso de uso da nossa classe que nós não previmos ao criar ela, afinal o objetivo dela é prover para quem for usar uma forma simples de calcular o resultado usando a formula de bhaskara.&lt;/p&gt;

&lt;p&gt;Só que, e se a gente resolver renomear as propriedades da classe para tentar falar a mesma lingua dos matemáticos, tornando assim o código mais descritivo?&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bhaskara&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;quadraticCoefficient&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="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;linearCoefficient&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="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;constantTerm&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="nf"&gt;delta&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;linearCoefficient&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&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;quadraticCoefficient&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;constantTerm&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;x1&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="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;linearCoefficient&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delta&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;2&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;quadraticCoefficient&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;x2&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="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;linearCoefficient&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delta&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;2&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;quadraticCoefficient&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;result&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="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;x1&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;x2&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;Isso quebraria totalmente o nosso código que fazia &lt;code&gt;console.log(bhaskara.a)&lt;/code&gt;, visto que agora &lt;code&gt;a&lt;/code&gt; não existe mais, virou &lt;code&gt;quadraticCoefficient&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Por isso que esconder seria uma solução melhor, a gente só libera o que realmente for a nossa intenção que deveria ser utilizado, assim evitando que usos não previstos sejam realizados, o que nos dá paz de espírito para realizar uma mudança em como as coisas funcionam internamente sabendo que isso não vai afetar o código que usa o nosso código (o famoso bug que só some de um lugar para aparecer em outro), de quebra a gente ainda ganha uma abstração melhor ela vai, de fato, só mostrar o que interessa para quem for usar o código.&lt;/p&gt;

&lt;p&gt;Podemos levar a ideia ainda mais longe, e esconder como os resultados são obtidos, assim não importaria se nós tivessemos implementado cada coisa em seu método como no exemplo, ou se fizemos tudo numa única função, ex:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bhaskara&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;a&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="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;b&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="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;c&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="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;delta&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;b&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&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;a&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;c&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;x1&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="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;b&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delta&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;2&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;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;x2&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="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;b&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delta&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;2&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;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;result&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="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;x1&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;x2&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="c1"&gt;// ou&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bhaskara&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;a&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="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;b&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="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;c&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="nf"&gt;result&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;delta&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;b&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&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;a&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;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&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;b&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;delta&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;2&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;a&lt;/span&gt;&lt;span class="p"&gt;),&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;b&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;delta&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;2&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;a&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;Em qualquer uma dessas implementações, o método result é a única operação que um cliente dessa classe poderia realizar, e como ambos se comportam da mesma forma, efetivamente, por termos deixado os métodos privados, essa refatoração foi possível, visto que podemos remover eles em favor de um código menor por conta da garantia que eles não estavam sendo utilizados em nenhum outro lugar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Encapsulamento não é sobre getters e setters
&lt;/h2&gt;

&lt;p&gt;Agora que exploramos as motivações por trás do uso de getters e setters, além das diversas aplicações do encapsulamento, vamos voltar a questão que abriu este artigo.&lt;/p&gt;

&lt;p&gt;Getters e setters, assim como vimos no início do artigo, até podem ser uma aplicação do encapsulamento, entretanto se nós considerarmos os outros pontos que vimos até aqui, fica claro que eles são uma forma bem pobre de aplicar o princípio, ao passo de que deveriam ser a exceção ao invés da regra.&lt;/p&gt;

&lt;p&gt;Podemos avaliar isso de forma mais pragmática analisando como eles são usados, de fato, na prática. O que vemos na grande maioria dos casos é uma aplicação do padrão que claramente viola o YAGNI, onde criamos getters e setters no automático (muitas vezes até por comodidade da IDE prover uma função de criar eles com um click) pensando que, no futuro, pode ser que tenha que adicionar uma validação ali que justifique a criação deles, ex:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;age&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="nf"&gt;getName&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;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;getAge&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;age&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;setAge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;age&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;age&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;Com esse simples código, acabamos de violar completamente o princípio do encapsulamento, perdemos tudo o que estamos tentando ganhar ao usar o princípio.&lt;/p&gt;

&lt;p&gt;A começar que tudo o que fizemos aqui foi criar a mesma classe que teríamos se as propriedades fossem públicas, só que com 10 vezes mais código e trabalho.&lt;/p&gt;

&lt;p&gt;Não apenas foi esforço desperdiçado como criamos potênciais problemas de abstração com isso, pois agora qualquer código fora da classe pode alterar qualquer estado interno dela sem problemas, o que volta no problema que discutimos na própria seção que justifica a existência desse padrão: a sobre controle.&lt;/p&gt;

&lt;p&gt;Aqui você poderia argumentar que o problema não seria o padrão, mas sim quem usa errado, entretanto mesmo considerando que vamos ter setters que validam as coisas para evitar invariantes dos dados, getters que fazem algum tipo de transformação antes de retornar a propriedade, entre outras aplicações "perfeitas" do padrão, isso, novamente, ainda seria uma aplicação pobre do encapsulamento, e que potenciamente ainda viola o princípio.&lt;/p&gt;

&lt;p&gt;Afinal, o benefício de centralizar o controle na classe não foi o único que perdemos ao fazer isso, nós também perdemos as vantagens discutadas no tópico sobre como encapsulamento seria a arte de esconder coisas, pois como temos a mesma coisa que teríamos caso as propriedades fossem públicas, nada do objeto foi escondido, como criamos &lt;strong&gt;cada par representando uma propriedade&lt;/strong&gt;, se ela mudar, vamos ter que mudar o par junto, além de expor como o objeto faz as coisas internamente, dessa forma temos uma clara noção de como os seus dados estão estruturados.&lt;/p&gt;

&lt;p&gt;Note como isso é um problema que permanece mesmo com os getters e setters cumprindo os seus papéis, assim por mais que tenhamos garantido que o objeto não vai aceitar estados inválidos, nada realmente foi escondido ali, o que vai contra um dos objetos de se usar o encapsualmento em primeiro lugar.&lt;/p&gt;

&lt;p&gt;Além disso, eles não são lá uma forma muito interessante de abstração, visto que não traduzem nenhum conceito do problema sendo modelado na forma de uma classe, mas sim um problema seu como desenvolvedor. Por exemplo, numa classe Personagem, o que seria mais interessante um método &lt;code&gt;setVida&lt;/code&gt; ou mais de um como &lt;code&gt;tomarDano&lt;/code&gt; e &lt;code&gt;curar&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Esse exemplo ilustra bem a natureza do encapsulamento como a união entre dados e funções, um dos motivos para criarmos funções seria abstrair alguma alteração que um dado ou um conjunto deles deveria sofrer, e se algo precisa ser alterado, é porque reflete uma necessidade do problema que existe na vida real.&lt;/p&gt;

&lt;p&gt;De fato, existem casos onde a operação na vida real seria redefinir o valor de algo, como mudar uma configuração num painel ou o seu nome de usuário num formulário por exemplo, tornando um setter uma abstração correta no contexto do domínio.&lt;/p&gt;

&lt;p&gt;Só que o mais provável é que a operação tenha um significado maior do que a ação que é executada na maioria dos casos, é só que não tentamos pensar nisso muitas das vezes, o que leva a uma abstração fraca do problema, indo contra o propósito de se tentar criar uma abstração em primeiro lugar.&lt;/p&gt;

&lt;p&gt;A operação de dar um like num comentário por exemplo, apesar de no fim das contas ser a operação de pegar o número de likes de um post, e incrementar ela, carrega um significado importante para o contexto do problema, então ao invés de ter um setLikes que é usado por uma outra classe para atualizar o valor de uma classe Post, a própria classe Post poderia prover um método para se atualizar chamado &lt;code&gt;curtir&lt;/code&gt; por exemplo.&lt;/p&gt;

&lt;p&gt;A importância dessa abordagem fica ainda mais clara quando temos operações que envolvem atualizar múltiplas propriedades de um objeto de uma vez só, pois reflita comigo se tivermos um setter para cada propriedade, estamos protegidos de estados inválidos ao atualizar uma propriedade diretamente, só que nesse caso não temos nada que garante que vamos atualizar outra propriedade B como resultado de atualizar uma propriedade A em primeiro lugar. Assim, poderíamos considerar criar um "setter geral" que atualiza todas as propriedades de uma vez só, o que nesse caso só provaria o ponto que eu estou fazendo de que isso seria uma operação complexa, e portanto provavelmente existe um nome mais apropriedade para ela do que &lt;code&gt;setTudo&lt;/code&gt; por exemplo.&lt;/p&gt;

&lt;p&gt;E para fechar, quando se tem um setter, isso pressupõe a existência de pelo menos uma operação que vai alterar os dados do objeto, caso contrário isso é só código inútil que nunca vai ser usado, visto que o objeto seria imutável, fora isso vimos que se uma operação existe, ela provavelmente tem um nome melhor que &lt;code&gt;setAlgumaCoisa&lt;/code&gt;, mas existe uma situações onde, de fato, você teria que pensar em métodos com nomes de verdade, que seria o caso da classe Personagem citada anteriormente, nela, existem pelo menos duas operações envolvendo a propriedade vida, sendo assim não poderíamos ter um método setter apenas, teríamos que diferenciar um do outro, e nesse ponto já provamos que cada ação deveria ter um nome mais apropriado.&lt;/p&gt;

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

&lt;p&gt;Quando somos introduzidos a orientação a objetos, no que diz respeito ao encapsulamento, muitas vezes os getters e setters acabam sendo o nosso todo em relação a esse assunto, mas espero que com o artigo de hoje, você, caro leitor, tenha entendido as várias nuances que o princípio possui, além de ter entendido o motivo de muitas pessoas, eu incluso, considerarem getters e setters ruins, e sempre recomendarem ou a evitar eles completamente, ou usar apenas em último caso onde as outras estratégias para criar uma classe com bom encapsulamento já falharam.&lt;/p&gt;

&lt;p&gt;Ass: Suporte cansado...&lt;/p&gt;

&lt;h2&gt;
  
  
  Links que podem te interessar
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Encapsulation_%28computer_programming%29" rel="noopener noreferrer"&gt;Encapsulamento (Wikipedia)&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.yegor256.com/2014/09/16/getters-and-setters-are-evil.html" rel="noopener noreferrer"&gt;Getters/Setters. Evil. Period. (Yegor256)&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.yegor256.com/2016/04/05/printers-instead-of-getters.html" rel="noopener noreferrer"&gt;Printers Instead of Getters (Yegor256)&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.yegor256.com/2018/08/22/builders-and-manipulators.html" rel="noopener noreferrer"&gt;Builders and Manipulators (Yegor256)&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.infoworld.com/article/2073723/why-getter-and-setter-methods-are-evil.html" rel="noopener noreferrer"&gt;Why getter and setter methods are evil (InfoWorld)&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.infoworld.com/article/2072302/more-on-getters-and-setters.html" rel="noopener noreferrer"&gt;More on getters and setters (InfoWorld)&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.infoworld.com/article/2075271/encapsulation-is-not-information-hiding.html" rel="noopener noreferrer"&gt;Encapsulation is not information hiding (InfoWorld)&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.eiffel.org/doc/glossary/Glossary#Encapsulation" rel="noopener noreferrer"&gt;Encapsulamento (Eiffel lang)&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.stroustrup.com/oopsla.pdf" rel="noopener noreferrer"&gt;Why C++ is not just an Object-Oriented Programming Language (Bjarne Stroustrup)&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en" rel="noopener noreferrer"&gt;Definição de Alan Kay sobre Orientação a Objetos&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.baeldung.com/java-why-getters-setters" rel="noopener noreferrer"&gt;Significance of Getters and Setters in Java (Baeldung)&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Mutator_method" rel="noopener noreferrer"&gt;Getters/Setters (Wikipedia)&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://1kevinson.com/why-setters-are-evil-avoid-using-them/" rel="noopener noreferrer"&gt;Why Setters are Evil: Avoid Using Them (KK_)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>braziliandevs</category>
      <category>beginners</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>Por que a Apple Odeia o Brasil? A História Proibida que Ninguém Contou!</title>
      <dc:creator>Terminal Coffee</dc:creator>
      <pubDate>Sat, 29 Jun 2024 15:55:13 +0000</pubDate>
      <link>https://dev.to/terminalcoffee/por-que-a-apple-odeia-o-brasil-a-historia-proibida-que-ninguem-contou-21ek</link>
      <guid>https://dev.to/terminalcoffee/por-que-a-apple-odeia-o-brasil-a-historia-proibida-que-ninguem-contou-21ek</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Bom dia, boa tarde e uma boa noite a todos nossos leitores. Já faz um tempinho que eu não escrevo aqui no blog, e hoje apresento uma história diferente e meio lenda urbana. Se gostar da ideia e quiser mais desse tipo de conteúdo, deixe nos comentários e dê seu like, pois o feedback de vocês é muito importante. Sem mais delongas, bora pro vídeo.&lt;/p&gt;

&lt;h1&gt;
  
  
  História
&lt;/h1&gt;

&lt;p&gt;Você provavelmente já se perguntou por que os produtos da Apple são tão caros no Brasil. E você, usuário que recebe dois salários no nosso grande país, não consegue ter seu iPhone, MacBook ou iPad sem parcelar a alma junto. Claro, sabemos que a culpa disso é da economia atual e de mais um monte de coisas que não têm relação direta com a nossa história, independente se você gosta ou não do governo. Até porque o buraco é mais embaixo.&lt;/p&gt;

&lt;p&gt;Sabemos que no Brasil não existe fabricação de produtos licenciados da Apple. Bom, se não sabia, tá aí a informação em primeira mão. ✋ Mas você, caro entusiasta da tecnologia, já pensou por um momento por que a Apple nunca nem ao menos ficou tentada em firmar base nas terras tupiniquins? Afinal de contas, o Brasil é muito populoso e um possível grande mercado consumidor da maçã mordida, mas mesmo assim eles nunca nem cogitaram. Desde 2021, o Brasil é o lugar mais caro para se comprar um celular que nem vem com o carregador na caixa. Vou deixar a matéria nas referências para provar que eu não tô mentindo.&lt;/p&gt;

&lt;p&gt;Continuando ao que interessa, existe uma história que é meio lenda urbana, pois nunca foi confirmada pelo Steve Jobs, e agora nem é mais possível que ele confirme por motivos que não precisamos mencionar (F nos comentários em respeito) do real motivo dessa relação Brasil e Apple nunca ter acontecido. Jobs declaradamente não gostava do Brasil, e essa treta começa no final dos anos 1980, quando a Apple já tinha revolucionado o mercado de computadores pessoais com o Apple II em 1977, sendo o primeiro equipamento com interface amigável a usuários comuns. A empresa se superou com o lançamento do primeiro Macintosh em 1984 (acompanha as datas que vai ser importante), com a ideia de ser um aparelho fácil de usar e barato. Sim, eu sei, Apple e barato na mesma frase parece até piada, mas era a ideia da equipe de desenvolvimento na época e deu super certo novamente, sendo mais bem-sucedido que seu antecessor.&lt;/p&gt;

&lt;p&gt;Esse era o contexto da Apple. Agora, no Brasil, a situação em todo o país era muito mais complicada. Nos anos 70/80, o Brasil estava na ditadura/regime militar e a vinda de tecnologia para nós não era muito simples. Mas com seu final em 1985, com a eleição do então presidente da época, Tancredo Neves, que acabou não assumindo por uma fatalidade na época, deixando seu vice no comando, José Sarney (uma pequena aulinha de história na faixa), e nesse momento, com mudança de gerência, se podemos dizer assim, o Brasil precisava correr atrás do tempo perdido e foi em busca de tecnologias. E qual era a tecnologia que estava em alta em 1985, 86 e 87? Exatamente, o Macintosh da Apple. E agora vamos à pergunta de 1 milhão de reais: o que o governo brasileiro fez a seguir?&lt;/p&gt;

&lt;p&gt;Opções e valendo:&lt;/p&gt;

&lt;p&gt;A) Comprou uma porrada de licenças e equipamentos Apple.&lt;/p&gt;

&lt;p&gt;B) Firmou um acordo com a Apple para conseguir seus equipamentos na base da amizade.&lt;/p&gt;

&lt;p&gt;C) Roubou o firmware do Macintosh e pirateou a sua BIOS para criar um clone do sistema.&lt;/p&gt;

&lt;p&gt;D) Chorou e aceitou que é pobre.&lt;/p&gt;

&lt;p&gt;Se você conhece um pouco do que é o Brasil, já sabe que demos nosso jeitinho especial de conseguir. Então, ponto para quem respondeu a opção "C". Sim, sem sacanagem, o governo brasileiro foi um dos primeiros do mundo a piratear o sistema operacional do Macintosh da Apple. Vai Brasil, finalmente sendo pioneiro em alguma coisa: avião e piratear Mac você encontra por aqui. E para fechar essa história com chave de ouro, o governo brasileiro foi pego com a mão na massa e recebeu uma carta do próprio Steve Jobs reivindicando direito à sua propriedade. Reza a lenda que o Brasil simplesmente mandou um: “Fica na tua, Jobs, e um cala a boca” e desde então o Jobs abertamente se dizia contra o mercado brasileiro e se recusando a ter produtos oficiais no Brasil.&lt;/p&gt;

&lt;p&gt;O mais impressionante é que essa situação gerou tanto ódio na Apple que, mesmo Jobs tendo sido expulso da Apple nos anos 90, de todos os erros cometidos pela empresa sem o seu fundador, um deles não foi vir para o Brasil para ter operações (até para ser burro tudo tem limites). Mesmo com a morte do seu criador em 2011, eles não vieram para o Brasil e podemos ter certeza que eles nunca vão vir para o Brasil e a imagem abaixo mostra o porque eles nem precisam vir para o Brasil, todo dia um 7X1 diferente &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%2Fg5tlgpbq47d5pkg9nloq.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%2Fg5tlgpbq47d5pkg9nloq.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Notícia da época
&lt;/h1&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%2Fmbw9natwq3dljtsigeix.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%2Fmbw9natwq3dljtsigeix.png" alt="Image description" width="800" height="565"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Claro, sabemos que mesmo que a Apple tivesse base na terra de Lulinhas, o valor do seu aparelho principal, seja o iPhone ou MacBook, ainda seria caro para o bolso do consumidor médio. Mas com certeza estaria mais barato e no valor médio de seu maior competidor, a sul-coreana Samsung.&lt;/p&gt;

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

&lt;p&gt;Novamente se gostou desse formato de conteúdo com histórias e tretas da tecnologia e quiser mais desse quadro, coloque nos comentários alguma história cabulosa que nossa equipe de desocupados vai em busca de averiguar as informações e trazer em primeira mão. E claro, se souber alguma coisa do conteúdo, também deixa aí embaixo. Agradecemos a leitura e até a semana que vem com mais conteúdo informativo (ou não) sobre a tecnologia.&lt;/p&gt;

&lt;p&gt;Ass: Estagiário mal remunerado.&lt;/p&gt;

&lt;h1&gt;
  
  
  Referências:
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://www.jornalopcao.com.br/ultimas-noticias/brasil-e-o-lugar-mais-caro-do-mundo-para-se-ter-um-apple-veja-motivos-364549/" rel="noopener noreferrer"&gt;https://www.jornalopcao.com.br/ultimas-noticias/brasil-e-o-lugar-mais-caro-do-mundo-para-se-ter-um-apple-veja-motivos-364549/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ipdec.org/aniversario-de-35-anos-do-primeiro-macintosh-lancado-em-1984/#:%7E:text=O%20projeto%20Macintosh%20come%C3%A7ou%20a,barato%20para%20o%20consumidor%20comum" rel="noopener noreferrer"&gt;https://ipdec.org/aniversario-de-35-anos-do-primeiro-macintosh-lancado-em-1984/#:~:text=O%20projeto%20Macintosh%20come%C3%A7ou%20a,barato%20para%20o%20consumidor%20comum&lt;/a&gt;.&lt;br&gt;
&lt;a href="https://www.estadao.com.br/link/nos-anos-80-apple-foi-copiada-no-brasil/" rel="noopener noreferrer"&gt;https://www.estadao.com.br/link/nos-anos-80-apple-foi-copiada-no-brasil/&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.evolucaotecnologica.com.br/?p=1589" rel="noopener noreferrer"&gt;http://www.evolucaotecnologica.com.br/?p=1589&lt;/a&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>news</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Design para programadores - Cores</title>
      <dc:creator>Terminal Coffee</dc:creator>
      <pubDate>Tue, 04 Jun 2024 20:41:53 +0000</pubDate>
      <link>https://dev.to/terminalcoffee/design-para-programadores-1m28</link>
      <guid>https://dev.to/terminalcoffee/design-para-programadores-1m28</guid>
      <description>&lt;p&gt;Design é uma área que muitos programadores acabam por ter bastante dificuldade em lidar, em alguns casos, a pessoa pode achar que não leva jeito para isso, que ela não tem criatividade, que ela não sabe desenhar (mesmo que essas áreas não tenham tanto assim em comum), que ela funciona melhor com lógica e números, enfim, diversos motivos diferentes, eu mesmo nunca me considerei como tendo uma grande veia artistica, entretanto existem coisas sim que podemos aprender sobre design (muitas na verdade), e inclusive utilizar lógica para lidar com isso, em favor de pelo menos não entregar algo que não sangre aos olhos dos usuários, ou pelo menos entender melhor o trabalho entregue a nós pelos designers com quem trabalhamos.&lt;/p&gt;

&lt;p&gt;Algo que a área de design tem em comum com a de programação é que eles também seguem princípios e padrões por lá, e um dos princípais pílares do design visual seriam as cores, sendo isso que iremos explorar hoje.&lt;/p&gt;

&lt;h1&gt;
  
  
  O circulo cromático
&lt;/h1&gt;

&lt;p&gt;Quando passamos pelo ensino básico, nas aulas de artes, certamente você já deve ter tido uma aula sobre as cores, aprendendo que existem as cores primárias, as secundárias - formadas pela combinação entre as primárias, e, dependendo, até mesmo as cores terciárias - formadas pela combinação entre as primárias e as secundárias - em diante.&lt;/p&gt;

&lt;p&gt;Dessa forma, se organizarmos como essas cores se relacionam na forma de um circulo, conseguimos o circulo cromático, algo como:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbqkdhtsorq2osnk45ofy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbqkdhtsorq2osnk45ofy.png" alt="Image description" width="363" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Organizando elas dessa forma podemos utilizar essas relações entre as cores para formar as nossas paletas de cores. Aqui uma dica seria manter a quantidade de cores entre 1 e 3, isso desconsiderando as variantes de uma cor em específico, por exemplo se escolhermos azul, verde e roxo, as nossas 3 cores seriam essas, mas poderíamos ter azul escuro e verde claro na paleta também, de fato, paletas monocromáticas são baseadas em pegar uma cor, e derivar variações dela.&lt;/p&gt;

&lt;p&gt;Vale lembrar que diferentes sistema de representação de cores vão mapear para circulos cromáticos diferentes, visto que eles são só sistemas de coordenadas para que o computador possa representar as cores, e é por isso que nós temos sistemas diferentes no CSS como: RGB, HSL, Hexadecimal, e etc. O circulo apresentado anteriormente segue a ideia de que as cores primárias são: Azul, Amarelo, e Vermelho, entretanto no computador, as cores são representadas pelo sistema RBG, então as cores primárias seriam: Vermelho, Azul, e Verde, por isso o circulo cromático usado pelo CSS seria algo próximo a esse daqui:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F27r0izydriwnb6cci7ly.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F27r0izydriwnb6cci7ly.png" alt="Image description" width="650" height="555"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Montando uma paleta de cores
&lt;/h1&gt;

&lt;p&gt;Decidir uma paleta de cores não é uma tarefa fácil, mas também não é algo totalmente abstrato onde nós precisamos sentir algo para conseguir criá-la. Existem inumeras técnicas para escolher quais cores vão fazer parte dela.&lt;/p&gt;

&lt;h2&gt;
  
  
  Paleta monocromática
&lt;/h2&gt;

&lt;p&gt;A escolha mais simples é simplesmente pegar uma cor só, por exemplo a cor princípal da logo do sistema sendo trabalhado, e derivar o resto das variações dela utilizando cálculos, algo que podemos fazer graças a um dos sistemas de cores suportados pelo CSS: o HSL.&lt;/p&gt;

&lt;h3&gt;
  
  
  Derivando variações de uma cor
&lt;/h3&gt;

&lt;p&gt;O HSL é um sistema onde dizemos qual cor nós queremos, informando o &lt;strong&gt;H&lt;/strong&gt;ue, que significa qual cor no circulo cromático queremos usar por meio de um valor em graus, depois a &lt;strong&gt;Saturação&lt;/strong&gt;, que seria o quanto daquela cor queremos aplicar (por isso que deixar a saturação em 0 deixa as fotos cinza no photoshop, e que dizemos que uma foto com cores muito fortes está muito saturada), e por fim a &lt;strong&gt;Luz&lt;/strong&gt;, sendo o quão clara ou escura aquela cor vai ser (0 é preto e 100 é branco para qualquer cor). Ex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;hsl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;50%&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 estamos representando o vermelho puro, pois 0 corresponde ao vermelho, estamos aplicando o máximo de vermelho possível com o 100% na saturação, e com 50% de luz estamos bem no meio entre preto e branco.&lt;/p&gt;

&lt;p&gt;Um truque aqui é considerar saturação como inversamente proporcional a luz, então quanto mais escura uma cor, mais saturada ela deve ser, e quanto mais clara, menos saturada.&lt;/p&gt;

&lt;p&gt;Assim é possível ir criando uma transição natural entre os tons, ao ponto de se colocar cada tom lado-a-lado é possível ver a formação de um degradê.&lt;/p&gt;

&lt;p&gt;Isso é bem útil para gerar as variantes, mas também para conseguir variações de preto e branco, visto que uma técnica muito comum entre os designers é nunca usar preto ou branco puros, e sim versões mescladas com as cores sendo utilizadas para quando elas forem combinadas na interface, a composição final parecer mais harmoniosa.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cores complementares
&lt;/h2&gt;

&lt;p&gt;Aqui seria como aquele ditado: os opostos se atraem. Podemos combinar cores que são opostas uma da outra no circulo cromático, por exemplo vermelho e verde no sistema tradicional, ou azul e amarelo no RGB.&lt;/p&gt;

&lt;p&gt;Vale lembrar que por essas cores serem completos opostos uma da outra, é interessante utilizar a técnica mencionada na seção anterior para combinar cores com valores de saturação e luz diferentes, dessa forma a diferença entre elas vai ser amenizada, evitando combinações famosas por agredirem os olhos. Caso as saturações sejam iguais, o efeito tende a ser o contrário, fazendo as cores colidirem ao invés de se combinarem na interface, causando desconforto em quem vê.&lt;/p&gt;

&lt;p&gt;Essa combinação é particularmente útil para formar paletas com duas cores, e pode ser formada a partir de qualquer cor, pois considerando que o círculo tem 360 graus, podemos pegar qualquer valor de Hue, e adicionar mais 180, afinal metade de 360 é 180, dessa forma parando no exato oposto dessa cor no círculo cromático.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tríade e Quadrado em diante
&lt;/h2&gt;

&lt;p&gt;Seguindo o aumento na quantidade de Hues escolhidas, caso você queira formar uma paleta de 3 cores, uma opção é seguir a lógica das cores complementares, e dividir os 360 graus por 3, obtendo 120, dessa forma começando com 1 cor e ir somando 120 até ter as 3 cores.&lt;/p&gt;

&lt;p&gt;Essa é uma abordagem onde você consegue as 3 cores primárias se começar por uma delas, ou as 3 secundárias caso começa por uma secundárias.&lt;/p&gt;

&lt;p&gt;Se você tiver 4, pode formar um quadrado, se ir somando de 90 em 90 graus, de fato, se você pegou a lógica até aqui pode escalar isso para quantas cores você tiver na sua paleta simplesmente dividindo 360 (o circulo todo), pela quantidade de cores que você tiver.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cores análogas
&lt;/h2&gt;

&lt;p&gt;Outra forma de lidar com várias cores de uma vez só, seria utilizar os vizinhos no circulo para formar a sua paleta, voltando as aulas de arte, nós aprendemos sobre esse tipo de agrupamento quando pensamos nas cores quentes e nas cores frias.&lt;/p&gt;

&lt;p&gt;Nesse modelo, o tamanho do pulo funciona bem seria somar ou subtrair 30 graus de cada vez, e ele funciona bem pois cada cor seria o próximo passo no circulo, assim sendo uma combinação natural para os nossos olhos.&lt;/p&gt;

&lt;h1&gt;
  
  
  Aplicando a paleta
&lt;/h1&gt;

&lt;p&gt;Agora que já montamos a nossa paleta de cores, podemos aplicar ela no nosso projeto seguindo uma técnica conhecida como princípio 60-30-10, nesse modelo nós escolhemos uma cor primária, uma cor secundária, e uma cor de acento (normalmente chamada de accent). Por isso que paletas de até 3 cores são preferíveis, mas caso você tenha 4 ou mais, você pode dividir as cores que sobrarem entre as cores secundárias e de acento.&lt;/p&gt;

&lt;p&gt;Nesse tópico vai ser necessário um pouco mais de sensibilidade para aplicar a técnica, pois não existe bem uma forma de calcular os valores, mas depois de um pouco de treino com esse princípio em mente, as coisas tendem a ficar mais fáceis, até porque você não precisa dividir perfeitamente.&lt;/p&gt;

&lt;p&gt;A cor primária vai ser a cor predominante na sua interface, a princípal, ela vai ser a cor mais aparente quando se olhar para a tela, e por isso você deveria utilizar ela em cerca de 60% da sua interface.&lt;/p&gt;

&lt;p&gt;A cor secundária seria a cor utilizada para dar contraste a cor primária, e enquanto ela ainda vai ser bem perceptível na tela, deve ser utilizada com parcimonia, em cerca de 30% das coisas.&lt;/p&gt;

&lt;p&gt;Já a cor de acento seria a cor que você utiliza para os detalhes, e deve ser utilizada com ainda mais cuidado que as secundárias, estando presente em apenas 10% da tela.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fck99psusoo88bbjrvkn4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fck99psusoo88bbjrvkn4.jpg" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
(Não deixe de conferir o artigo original desta imagem no [uxmisfit.com]&lt;/p&gt;

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

&lt;p&gt;Espero que tenha gostado do artigo de hoje, não se esqueça de compartilhar com aquele seu amigo que sofre para escolher uma paleta de cor, e até a próxima.&lt;/p&gt;

&lt;h1&gt;
  
  
  Links que podem te interessar
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;[Usando cores na prática do uxmisfit.com]- &lt;a href="https://uxplanet.org/the-60-30-10-rule-a-foolproof-way-to-choose-colors-for-your-ui-design-d15625e56d25"&gt;Princípio 60-30-10 no UX Planet&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://color.adobe.com/pt/create"&gt;Adobe Color - Um site que cria paletas de cores&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@imperavi/how-to-create-a-color-palette-for-design-systems-a803e90adc15"&gt;Um guia em mais detalhes para designers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bootcamp.uxdesign.cc/why-you-should-ditch-hex-and-use-hsl-to-make-picking-colors-easy-c376f69ae34e"&gt;Sobre criar shades via HSL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl"&gt;HSL no MDN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.dio.me/articles/modelos-de-cores-e-porque-o-sol-e-branco"&gt;Sobre sistemas de cores&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ass: Suporte cansado...&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>design</category>
    </item>
    <item>
      <title>Como classificar a sua linguagem - Introdução a sistema de tipos</title>
      <dc:creator>Terminal Coffee</dc:creator>
      <pubDate>Tue, 28 May 2024 19:49:09 +0000</pubDate>
      <link>https://dev.to/terminalcoffee/como-classificar-a-sua-linguagem-introducao-a-sistema-de-tipos-kgk</link>
      <guid>https://dev.to/terminalcoffee/como-classificar-a-sua-linguagem-introducao-a-sistema-de-tipos-kgk</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Quando o assunto é linguagens de programação dois termos muito utilizados para classifica-las são: fortemente tipada, e fracamente tipada, o problema com essa abordagem é que ambos são termos meio subjetivos quanto ao seu significado, o que dificulta um debate sério ao tentar classificar algo como forte ou fracamente tipado. Entretanto, a teoria sobre sistemas de tipos nos fornece conceitos mais úteis nessa tarefa de classificar uma linguagem de programação pelo seu sistema de tipos.&lt;/p&gt;

&lt;h1&gt;
  
  
  TL;DR;
&lt;/h1&gt;

&lt;p&gt;Podemos classificar um sistema de tipos pelas suas características:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Se é dinâmico ou estático;&lt;/li&gt;
&lt;li&gt;Se é estrutural ou nominal;&lt;/li&gt;
&lt;li&gt;Se a tipagem é implícita ou explícita;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Dinâmico vs estático
&lt;/h1&gt;

&lt;p&gt;O primeiro critério que podemos usar para classificar propriamente um sistema de tipos, seria se o processo de checar e reforçar as restrições dos tipos ocorre em &lt;em&gt;compile-time&lt;/em&gt; ou em &lt;em&gt;run-time&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Em uma linguagem onde a checagem durante a execução do programa, ela ocorre em &lt;em&gt;runtime&lt;/em&gt;, ou seja, ela seria considerada uma linguagem dinâmica.&lt;/p&gt;

&lt;p&gt;Da mesma forma, se a checagem ocorre antes do código rodar, apenas analisando o conteúdo do código através de uma ferramenta, seja ela um analisador estático, o compilador, um linter, e etc, ela é considerada como ocorrendo em &lt;em&gt;compile-time&lt;/em&gt;, dessa forma uma linguagem onde isso acontece seria uma com sistema de tipos estático.&lt;/p&gt;

&lt;p&gt;Linguagens dinâmicas geralmente são mais simples de executar, e por isso são associadas com curvas menores de aprendizado, além de não necessariamente exigirem que os tipos sejam declarados explícitamente (tópico que iremos abordar em breve), tornando o aprendizado inicial bem mais simples, facilitando abordagens mais interativas de desenvolvimento (escrever o programa, rodar para testar, e repetir o ciclo).&lt;/p&gt;

&lt;p&gt;Enquanto isso, as estáticas geralmente acabam por serem um pouco mais complicadas de executar devido a exigência de uma validação quanto a se o programa está "correto" antes que ele possa ser executado, resultando nas famosas experiências onde "o código não compila", em contrapartida, oferecem uma segurança maior quanto ao programa que vai ser executado, uma vez que esses tipos de erros são pegos durante o desenvolvimento, e não de surpresa depois que o código já está rodando em produção, e algum usuário faz algo que não devia, e acaba recebendo um erro inesperado na cara.&lt;/p&gt;

&lt;p&gt;Apesar de linguagens dinâmicas serem associadas com uma experiência de desenvolvimento (DX) melhor, as estáticas possuem uma qualidade nesse quesito bem significativa, que é a capacidade de ajudar os editores a mostrarem os erros diretamente no código que o programador estiver escrevendo, além de ajudarem ele a navegar pelo código, e proverem funcionalidades de auto-complete, devido a capacidade analisar o código estáticamente enquanto ele é escrito.&lt;/p&gt;

&lt;h1&gt;
  
  
  Estrutural vs nominal
&lt;/h1&gt;

&lt;p&gt;As linguagens mais famosas a serem associadas como "tipadas" ou "fortemente tipadas" como C ou Java, que acabaram por ditar parte do senso comum relacionado a tipagem, utilizavam o que é conhecido como sistema de tipos nominal, nesse caso, mesmo que dois valores sejam identicos, se eles pertecerem a tipos com nomes diferentes, então eles são de tipos diferentes, por exemplo, se você tiver duas classes com as mesmas propriedades e métodos no PHP, os objetos produzidos por essas classes não serão dos mesmos tipos, ex:&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;Foo&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="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$property&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;function&lt;/span&gt; &lt;span class="n"&gt;method&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;echo&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="n"&gt;property&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;Bar&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="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$property&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;function&lt;/span&gt; &lt;span class="n"&gt;method&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;echo&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="n"&gt;property&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;function&lt;/span&gt; &lt;span class="n"&gt;acceptFoo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Foo&lt;/span&gt; &lt;span class="nv"&gt;$foo&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="nv"&gt;$foo&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;acceptFoo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'A'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// Roda normal&lt;/span&gt;
&lt;span class="nf"&gt;acceptFoo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Bar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'A'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// Erro!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso ocorre pois apesar do conteúdo desses objetos ser o mesmo, eles são de tipos com &lt;strong&gt;nomes&lt;/strong&gt; diferentes, e por isso são de um sistema &lt;strong&gt;nominal&lt;/strong&gt; de tipos.&lt;/p&gt;

&lt;p&gt;O contrário do sistema nominal seria o sistema estrutural, aqui se segue a filosofia do &lt;em&gt;duck typing&lt;/em&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Se algo anda como um pato, faz quack como um pato, então deve ser um pato&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Dessa forma, um valor é considerado de um tipo, se a sua &lt;strong&gt;estrutura&lt;/strong&gt; é identica a estrutura desse tipo, então no caso de linguagens como o TS, nosso exemplo anterior rodaria sem problemas:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Foo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&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;property&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;Bar&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&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;property&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="nf"&gt;acceptFoo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;acceptFoo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// Ok&lt;/span&gt;
&lt;span class="nf"&gt;acceptFoo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Bar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// Ok&lt;/span&gt;
&lt;span class="nf"&gt;acceptFoo&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;method&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="c1"&gt;// Ok&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui por Foo, Bar, e até o objeto literal declarado no final terem a mesma estrutura (métodos e propriedades obedecendo aos mesmos tipos), eles são considerados como do mesmo tipo, e por isso, dessa vez, a função executa sem problemas.&lt;/p&gt;

&lt;p&gt;A comparação acaba sendo que um sistema estrutural acaba por ser mais flexível, e portanto mais amigável, enquanto um sistema nomimal acaba por ser um pouco mais rígido, embora nesse caso, ambos não serem diretamente opostos em seus prós e contras, pois existem muitas situações onde ter um sistema estrutural acaba sendo uma vantagem, geralmente em código que usa o paradigma funcional acaba por ser o caso, e existem situações onde o sistema nominal acaba por ser melhor como quando se tem valores "do mesmo tipo", mas com semântica diferente na aplicação, e por isso necessitam que o nome do tipo seja levado em consideração também, ex: moedas e números inteiros, seriam number em TS, mas possuem semânticas completamente diferentes, e não poderiam ser utilizados intercambiavelmente.&lt;/p&gt;

&lt;h1&gt;
  
  
  Implícito vs Explícito
&lt;/h1&gt;

&lt;p&gt;Para nosso último critério podemos observar se a tipagem é explícita ou implícita, o que significa verificar se a linguagem necessita que todos os tipos sejam declarados (explícita), ou se podemos omitir a declaração deles, dessa forma deixando que a linguagem advinhe qual o tipo (implícito), funcionalidade também conhecida como inferência de tipos.&lt;/p&gt;

&lt;p&gt;Em linguagens como o Java, antes da introdução do &lt;code&gt;var&lt;/code&gt;, era necessário que você declarasse o tipo de tudo, variáveis, parâmetros, anotações de retorno e etc. Ex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Point&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;Point&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Point&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Point&lt;/span&gt;&lt;span class="o"&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;y&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O que tem o benefício de garantir que se um valor errado foi inserido/retornado em qualquer uma dessas ocasiões, um erro vai ser desparado logo naquele ponto, além de deixar o código auto-documentado, já que os tipos estão explícitos para qualquer um que ler aquilo ler, assim já obtendo várias informações só de ler por cima o código.&lt;/p&gt;

&lt;p&gt;O problema é que essa abordagem torna o código muito verboso, além de muitas vezes forçar com que o programador digite código que a acaba por dar a sensação de ser repetitivo, chato, ou desnecessário, uma vez que o tipo correto parece óbvio, e a linguagem até mesmo poderia advinhar qual seria o tipo nesse caso.&lt;/p&gt;

&lt;p&gt;Sendo assim, quando uma linguagem possui suporte a inferência de tipos, ela tenta advinhar o máximo possível sobre a tipagem das coisas com base no código já escrito, e assim reforça a tipagem mesmo que o programador não tenha, de fato, tipado nada ainda, ex:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;x&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="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;y&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="nf"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Point&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;x&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;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&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;y&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;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&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;new&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&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;Aqui, apesar de termos que tipar algumas coisas, o TypeScript tenta adivinhar boa parte dos tipos utilizados nesse código, por exemplo inferindo qual seriam os tipos das constantes &lt;code&gt;x&lt;/code&gt; e &lt;code&gt;y&lt;/code&gt;, além do tipo de retorno do método &lt;code&gt;move&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A vantagem é uma DX bem melhor, uma vez que a linguagem trabalha para te ajudar ao invés de fazer você digitar tudo, muitas vezes sendo até um fator que faz com que pessoas que não gostem de tipagem pelo fato de considerarem uma tarefa que deixa o código muito verboso ao mesmo tempo que não tem benefícios que compensem isso, começarem a gostar das vantagens de um sistema estático, graças a implementação de um sistema onde a tipagem é implícita na maioria dos casos também.&lt;/p&gt;

&lt;p&gt;A desvantagem seria que ao confiar demais na linguagem, algumas vezes pode se tornar mais difícil de identificar erros de tipagem, pois eles vão ocorrer em outros lugares, além de tornar a função menos documentada, apesar do código mais limpo e conciso.&lt;/p&gt;

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

&lt;p&gt;Ao utilizarmos esses 3 critérios, conseguimos descrever muito melhor as capacidades de uma linguagem e de forma bem mais objetiva, além de poder lançar um julgamento mais adequado quanto as capacidades disponíveis em uma linguagem ou outra.&lt;/p&gt;

&lt;p&gt;Normalmente o termo fortemente tipado é relacionado a linguagens estáticas e explicítas, enquanto o termo fracamente é relacionado a linguagens dinamicas e implícitas, mas ainda existem nuances que variam de pessoa para pessoa, então fora que cada critério discutido ao longo deste artigo pode ser misturado com os demais na mesma linguagem, portanto dificultando a classificação entre forte ou fracamente tipado, pois a linguagem pode ser mais permissiva ao ser estrutural, mas mais rigída ao também exigir tipagem explícita por exemplo.&lt;/p&gt;

&lt;p&gt;Assim, na próxima vez que for discutir o mérito, tente descrever a tipagem de uma linguagem com esses critérios, e acredito que será uma abordagem bem mais frutífera.&lt;/p&gt;

&lt;p&gt;Não se esqueça de compartilhar esse artigo se ele te ajudou a aprender algo novo, até a próxima e deixe nos comentários o seu tipo favorito.&lt;/p&gt;

&lt;h1&gt;
  
  
  Links que podem te interessar
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Strong_and_weak_typing"&gt;Wikipedia sobre forte ou fracamente tipado&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Type_system#Static_type_checking"&gt;Wikipedia sobre estático vs dinâmico&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Manifest_typing"&gt;Wikipedia sobre tipagem explícita&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Type_inference"&gt;Wikipedia sobre tipagem implícita&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Nominal_type_system"&gt;Wikipedia sobre sistema nominal&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Structural_type_system"&gt;Wikipedia sobre sistema estrutural&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.baeldung.com/cs/statically-vs-dynamically-typed-languages"&gt;Baeldung sobre estático vs dinâmico&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://stackoverflow.com/questions/1517582/what-is-the-difference-between-statically-typed-and-dynamically-typed-languages"&gt;Questão do Stackoverflow sobre estático vs dinâmico&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://stackoverflow.com/questions/1931654/what-is-the-difference-between-latent-type-and-manifest-type#:~:text=In%20explicit%20%2F%20manifest%20typing%2C%20the,are%20thus%20implicit%20or%20latent."&gt;Questão do Stackoverflow sobre explícito vs implícito&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nullprogram.com/blog/2014/04/25/"&gt;Artigo interessante sobre vários aspectos de sistemas de tipos&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.typescriptlang.org/play?#code/PTAEBUE8AcFMGUDGAnAltALqVBnUBDUeDZAV0Q1OXwBsIZYjIcNYBbAOlAEFQWyKVWqAwMAUCD7NWbUG1j4AdngwALfFgDuq2ItCIA9m2j40igOYiGOADT04SNJlAHFNSBLAZ8Aa1h5URQwDAkRDUiCRHTl2ACNYZDxXKMZROA4xTwhVXGwAvUMg6hYREMUjQOE0xhxpdltQbQTGSANSLPCaABN9ZAVWEU0Q6rxY0ixOnvKsfBwcVHM9NXZS0AVEVSyDZeQueFhGWAAPfGMaWAAucrZKmgBaNMDzTMkAMQNkNZOz2DtlnFSQ2wQQSADN8Ih-AQ+vojNBzqx3FkSEocKCEtRYudgQQ+CRyJRqHRqlIWOwLplAqxkODIaAAEK0OgAbzEoFAXVQp1g1IuoEUpDY8WQAG4xABfMRUsEQxjwaA6GGs9mc7m8-mC4ViyViBGgWJMvmMmh0AC8oGZHK58nVAEYAAygcVivU4BXNPnyxWMc2W1U2hJ8gBMjudmTd3tA5oNJrFMbNfHdfTFWQAkqDGox8F0eoFcSTtKgNniBISmZBYUF8IE8EyXKDkdF5EKEkkM8a6Eoel7mn8dHpUDMaDgQoglPrYFkAVhghPcfGXJ8I80MlKQTTZRBSPELWyrWrAxqW6K9+cLGo+QLj9rMnrKPE+eBtz6LfuA8g+bag3Yz+YL6AAGYnRTe8X3jOM63NUCU0kelYDHUgAXnOsugMKFplAdQADcs1AX81D7XRsAmJQMPiLJZnmRZYB6WdlhEZ9QCw0wuSxWAuAACQMTRYBw5A7DrAwM3o5thRwLZ2zrUxGBrVAulSZ8BMUHoR2I-Rxx3SiFkUGjV0kKAHBQdAsFyQxjBYiw1ghVQYmPHF6JJfBzGrZQMCydYbO2RVVj41BQQrZZUE+WAAEdSFoQdID0sBeFBCIKFQZJcnHAxYgAK3gky9AAKXwZjHGMghlLU0y4WkrosjzQh5huGhTFAcEcByVwuAAdUHTydNARDYDiuhjhREQ0EQHxoTaZTG0YExqDYHAKV1Hlen6WAOyjUAAAp-R5Q8r2FABKKMAD4Nr9a1ts+cU9pdRaUGWnsYXNTazvVXaEjsHrU0UDZ-D5WIDAMc4lAO01juVUA+kJPRToPD9uoBT7vrwAB+N9ztAAAqUB7Q4ACAE5QD5LbqWAiUU1ujQECTF9ydYDsxRplbIKWin7tgGCwAMhAjOcTRUBNAgTW4jbXuQA7Z1C8K6HWkW7D+gGFEUPbKqWaJpphhoxiwDDpc1N79X+wHFdAO5jp148layTmCp5vm6E5HAx2QWjojlw37OiUEgpKLTFnkIIsniBCkMHAByPA+IrMy2GSUEPlAXL8u5iYDHk1YcB8dBQBMOYniyNXZsafsUkgEOYQwnSaN0l4wHeYLvnhVJolMagS7wWPkAAUWssP1JNA0Rsw2Yoj6KbTFOWwsmYmhSF+YF5KOIrncYPrO2QFvjewDMraTq0ukUEO3MkHBSGgaAPiwe3Hc5Sz8-Ohplj0VpSEaNpukHnDSmVxBp9T3iEgrAwmBEpLBCGwXwjdl7xQwMAvAYCMDFhPvNAA2gzDs61bR7TsKgpk60gx7QALocHbl3DY611rxjsAAfUCPPKh8YcDA1BnuQoI5zgcBoAYcw5CmRXQlLwrIAA5EIrhGAVy6CodQGBoqgAAEo8ioEsaw0JUh9Apj0GgqA-AuHSplBoXYioVk5KCdEfQvr+AojCMy00aKNA6ikPg3JtEZQoGsMKEVRDg1IOcWsf0cKrj1AzORXRVqPSJjtXWosjonVRtSLBAMPh8gAER9C6Ikp0-DsH83NIEmidMxA5OCUzTJNB2agFapGeintEgzBzr7XQWgPg+DwOtZYFY-pqHfowMJosA7jHsQCQoPRUL+H3lgFpLsUJoRwKMzpuJDAcNFhkIAA"&gt;TS sobre sistema estrutural&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.typescriptlang.org/play?#code/PTAEEFQOwewWwJZQIYBtQBcCeAHApqAM5aEZ5yhx7JSGYAWyGo1AxvZrgQnQK5QIAjrzwAoEKBoATFgDc8UUAgBmnfHUbyGBQsiqgpTZKCwxeoVjVjNkhQggDmUcWGSsATjDtq8hAHSiLqAAKlwAyh4IOBgA5HTY+EQkZBQ8RBjuvKwYvO5oADSgAO70COyU1LRBKto+SnSEjPgyqAgA1gTGUllthQixdF09fqAAkqrIQQ4wXgSMg6joGPQ6ep0YGQgARrxkg4MGPYXLCko2qIQw1QfdrG0jAJpmFjSgqNTuinAw7nN4vwAuFgADz0OHeANImWyuTQAFoEkgHIEJMFSnRLIpNAQpHkils3G1CIVlD8QWD3tpfpJqZZCL4giV-p10u4kaAyVBeHAtv8XljkFpCPhWAg0BYYFAyMCbFAZKZeEEpJKYswijRmBgYHI+XBkB1arI0CJ4nlaMp-nktu8RgAxH5BPCguDgvAAlxBOGgUAAVXp7jGUBwu1AYU2UAcdAAFPxdBaAJSe73BM2EVBMBCS0PhyNJ33+sZSBQYFRlDNZgBy3N57kIefArFYvjowRgHSqQQA6gRMaAHHhmN9SBzVCdQEbUCJQMpPBRjLBECgllwgsRSORiv0OMZWhtKVt+iOQRljKwYEWAl28DFqdN2VrQLx6ZJFEgyLW8NlM0ufIUilvJEfARhDECQz1oE83yURQx1JdwKBgCZQBwTx8HcbAXkWPAZAAfRwrYzRkKNlh4a4JSgeQpW-eNilKco9Q6OhDwQF0vHsa0CAfWx7CcSQglgeDxShe9tWMAA1NAEEMMgpFGINdjDNkI0vBICAk1ppOwuTgwwRT2QAXlZdkADJQAAb1APCCOkIEACI-T5bSQwABS8Zh1Kk8soFs0AAF8AG4UTAbtN0WR9n2MZR+C-LMHxPc0fjnIyI0wK4JHEyTNNk+TdJzUAvR2TUVmQmAoKKH5lmgGASwjMjliYYpr2pAArJ9mBwshFiRHCQnCSJogYBr+jiTBMjwS9wOHCdPLIBz3Cc5hDKjJAdKBYSIxo-SAD5zNEb1JuYewXXeDysoW0BDJW3Y-F+cE3DwKNgAAHQAHmABxClswATIls+NAu9X4ck+IgWNdU6mC0nLJDocGZIWvSI0CgKgtACsYCKRr+QsX4IenaKS0lOgSjKDh-zCyVUCwSRGzwaIgjMAMoDwDGFyQcVVMKaQqqKgh+yZvJ0HWhwfAmwnmBQt8KzWC7QCjFAqCBWHIZ0hGHE2nazL28jLhtVAYAcOW1j+0RkaCe0AydCk8EKFZfhGy59FjZALWgnTp1nQCn3+Qo71qiRlk8XgHA4MdpukskuZORReXZNA9aKbDUtAXlkKUmT3VEA7XZDQzbLQf4MCjGIthgLYtipjBkA4wgYnjWzAqzsOIeyt3DKb2b-QW5acuNiWpSlqgo3b5XdmNoIAHkYOK6rbdARg5UKHBuPvYr+DhYeZCF1Kgj7jAB4IMn0DyHgWTPF0EHeC33E8dwM93-fu50seJCecxexxmRT3gFC8BWWgEC0DAeQ7hZAIGZkeE4SoVAWl+FKYoyASBJw8NQMgVVFzsy4MSF8MgTgIHcEEE8RY4SIWUExKeaQAAsAAGKhEo4BUDgXrFKABxfoAAJXgWx6iEBEO6EAQR6AbBwIQAEIAHBbk4X4M+wAACyZRPCXGUBgYAoR8ARDZNEYAPAeG+GAAAJioXoj06U5QMDSDgNy9RAIOBxodbkep3BYD4cAARQiREgEQOwNAAAvfOdwEBSPgMAVmS4ES4CRHCJAYT1D9WUaIIAA"&gt;TS sobre sistema nominal&lt;/a&gt;;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ass: Suporte Cansado...&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>A Verdade Inconveniente sobre a Lógica de Programação - Por que Ela não Prepara os Alunos para a Orientação a Objetos</title>
      <dc:creator>Terminal Coffee</dc:creator>
      <pubDate>Mon, 13 May 2024 20:02:10 +0000</pubDate>
      <link>https://dev.to/terminalcoffee/a-verdade-inconveniente-sobre-a-logica-de-programacao-por-que-ela-nao-prepara-os-alunos-para-a-orientacao-a-objetos-3l28</link>
      <guid>https://dev.to/terminalcoffee/a-verdade-inconveniente-sobre-a-logica-de-programacao-por-que-ela-nao-prepara-os-alunos-para-a-orientacao-a-objetos-3l28</guid>
      <description>&lt;p&gt;Sendo você um estudante de programação ou até mesmo um programador, é bem provável que já tenha ouvido falar da tal lógica de programação seja como uma das "coisas essências para programar", ditados populares como "a lógica de programação é a mesma em todas as linguagens, então se aprender ela, aprende qualquer linguagem", como parte do conteúdo programático de algum curso, requisito de alguma vaga de emprego, e etc.&lt;/p&gt;

&lt;p&gt;Dessa forma definindo a importância dela, na programação, como a base para todas as outras coisas, no entanto será que isso é realmente verdade? Normalmente, ela tende a ser o primeiro passo no ensino formal de programação, seguindo essa linha de "conceitos-chaves" que todos temos que aprender, viriam coisas como estruturas de dados, e a tal da orientação a objetos, conceito esse que, curiosamente, é motivo de relato de dificuldade para muitas pessoas (não acredita em mim? Faça uma busca rápida sobre a fama do Java entre iniciantes na internet).&lt;/p&gt;

&lt;p&gt;Naturalmente, este é um assunto bem difícil, denso, e complexo, não a toa existe muito debate mesmo hoje em dia quanto a o que, de fato, seria a orientação a objetos, interpretação de seus princípios, real valor no desenvolvimento moderno, seus mais variados usos, e etc.&lt;/p&gt;

&lt;p&gt;Agora, o que tudo isso tem a ver com a lógica de programação? Bom, acredito que ela, para além dos motivos já expostos, é um dos princípais motivos em dificultar o aprendizado de algo que já é muito complicado, o que contribui para os vários relatos que ouvimos por ai.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como ela seria tão ruim assim?
&lt;/h2&gt;

&lt;p&gt;Podemos começar com um problema de definição, não existe uma definição oficial para lógica de programação, apesar disso, ela, muitas vezes, é definida como: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;O raciocínio lógico para escrever programas de computador, por meio da criação de algoritmos, ou seja, uma sequência de passos para se executar uma tarefa.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sendo uma definição bem vaga, podendo causar várias confusões quanto ao seu significado, por exemplo, muita gente diz "lógica de programação" quando na verdade quer dizer "raciocínio lógico", e pior, muitas vezes direciona a pessoa a aprender algo completamente diferente, pois o que é ensinado quando se ensina lógica de programação não é o raciocínio lógico, mas sim princípios de programação procedural, estes sendo o que eu realmente considero como "lógica de programação".&lt;/p&gt;

&lt;p&gt;Isso é algo que você pode confirmar por si mesmo indo pesquisar a ementa de diversos cursos, posts em blogs, e etc, só como exemplo vou deixar 3 links aqui que demonstram esse ponto:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.infoescola.com/informatica/logica-de-programacao/"&gt;Um post do InfoEscola&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://moocs.ggte.unicamp.br/course/logicadeprogramacao/intro"&gt;Ementa do curso da Unicamp&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.alura.com.br/cursos-online-programacao/logica"&gt;Ementa de cursos da Alura&lt;/a&gt;;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O que um site que nem é sobre programação, uma universidade bem renomada aqui no Brasil, e uma das princípais plataformas de cursos de programação também aqui no Brasil teriam em comum nesse assunto? Justamente a presença do ensino sobre princípios de programação procedural ao invés de um treinamento sobre como desenvolver o seu raciocínio lógico, e embora isso faça sim parte do processo em alguma medida, não seria o suficiente para justificar que raciocínio lógico é a mesma coisa que lógica de programação.&lt;/p&gt;

&lt;p&gt;Outra definição que parece colaborar mais com esse ponto seria essa dada pelo Chat-GPT:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A lógica de programação é a base fundamental para a criação de algoritmos e programas de computador. Ela envolve a habilidade de pensar de forma estruturada e sequencial para resolver problemas, transformando essas soluções em instruções claras e precisas que um computador pode entender e executar. Isso inclui entender os conceitos de variáveis, estruturas de controle (como loops e condicionais), operadores, funções e estruturas de dados básicas, entre outros elementos. Em essência, a lógica de programação é a capacidade de pensar logicamente e expressar esse pensamento de maneira que um computador possa seguir.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Essa diferença entre o que se fala e o que, realmente, se quer dizer seria o que resulta na diferença entre expectativa vs realidade nos conteúdos a serem aprendidos posteriormente a este assunto.&lt;/p&gt;

&lt;p&gt;O ponto que este artigo gostaria de fazer é que não tem como tem como esperar atingir certos resultados se suas premissas iniciais estão erradas quanto aquilo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ok, mas mesmo que mal interpretada, ela ainda assim é basilar para todo resto que vem depois, não é mesmo?
&lt;/h2&gt;

&lt;p&gt;Este é um questionamento bem válido quanto a linha de raciocínio apresentada até aqui, entretanto os conceitos normalmente relacionados a lógica de programação não são conceitos universais de programação, eles são os conceitos que servem de base para o paradigma procedural apenas.&lt;/p&gt;

&lt;p&gt;Ao se estudar "lógica de programação", no fim, você vai ter desenvolvido uma forma de pensar na construção de algoritmos que envolve um raciocíonio bem imperativo, pois se aprende que um algoritmo seria como uma receita de bolo, na declaração de estados mutáveis, as variáveis, no controle fino de como a execução do programa vai se dar por meio das estruturas de controle de fluxo, e, se o ensino realmente for bom, na modularização de partes reutilízaveis do programa.&lt;/p&gt;

&lt;p&gt;Só que cada ponto disso não é válido em todas as linguagens de programação (como é comumente dito), existem linguagens baseadas no paradigma declarativo, que é o contrário do imperativo, que não possuem variáveis, como as do paradigma funcional, e que não necessariamente precisam de estruturas de controle de fluxo para expressar lógica condicional ou de repetição, como o caso da orientação a objetos.&lt;/p&gt;

&lt;p&gt;O único ponto realmente universal seria a ideia de modularizar o programa, no entanto, cada paradigma tem os seus próprios mecanismos de abstração e, geralmente, apenas se ensina sobre as funções durante a "fase da lógica de programação", mas funções tem um significado diferente em programação funcional, e a orientação a objetos usa classes por exemplo. &lt;/p&gt;

&lt;p&gt;Existem sim conceitos bem universais aplicáveis a todos os paradigmas, entretanto não são eles que constituem a ideia de lógica de programação.&lt;/p&gt;

&lt;h2&gt;
  
  
  Isso quer dizer que lógica de programação é ruim?
&lt;/h2&gt;

&lt;p&gt;Não, programação procedural ainda é um dos principais paradigmas adotados no mercado, sendo até considerado como sinônimo de programar em si dependendo do contexto (não a toa que existe toda essa confusão em relação ao tema de lógica de programação), a maioria das linguagens mainstream tem suporte a esse paradigma em alguma medida, e etc.&lt;/p&gt;

&lt;p&gt;O problema é que um paradigma de programação é como se fosse um sistema de "lógica de programação" por si só, ele seria um conjunto de princípios, técnicas e funcionalidades utilizados para resolver um problema, ou seja, cada paradigma é como se fosse uma escola de pensamento sobre como programar a solução de determinado problema por si só, com cada uma tendo as suas vantagens e desvantagens para cada cenário.&lt;/p&gt;

&lt;p&gt;Então, normalmente, aprender um novo paradigma tende a ser uma das coisas mais dificeis em programação, pois para aprender ele de fato, você tem que jogar fora tudo o que aprendeu até então para começar a reconstruir sua forma de pensar e encarar problemas do zero seguindo esse novo conjunto de ferramentas e princípios.&lt;/p&gt;

&lt;p&gt;Logo, fica claro qual o problema de tratar a lógica de programação como o centro de tudo quando ela não é, só se refere aos princípios de um paradigma em específico. Além dos desafios já citados em se trocar de paradigma, a pessoa vai se aproximar desse tema com a mentalidade completamente errada, visto que ela vai tender a encarar esse novo paradigma como uma progressão do seu aprendizado até aqui, muitas vezes como "uma forma melhor" ou complementar ao que ele entende por lógica de programação, e pior, tentar programar usando a lógica de programação num cenário onde ele deveria estar aprendendo uma "nova lógica de programação".&lt;/p&gt;

&lt;p&gt;Resumindo, trocar de paradigma já é dificil, imagina se você tentar aprender pelo caminho contrário ao ideal para se abordar este tema.&lt;/p&gt;

&lt;p&gt;Isso trás complicações para além da dificuldade de aprendizado, visto que a pessoa pode até absorver os novos conceitos introduzidos pelo paradigma, e até conciliar com o que ele já sabe de alguma forma (o que é bem possível visto que ambos estão no espectro de paradigmas imperativos), o problema é que por ela estar tentando jogar nas regras de um paradigma estando no outro, muitos dos princípios vão ser mal aplicados (dado o vício de já saber fazer de outra forma), ou vão parecer sem sentido, resultando em um programador que conhece os princípios mas ou não sabe aplica-los corretamente ou nem ao menos os aplica.&lt;/p&gt;

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

&lt;p&gt;Lógica de programação, ou melhor, a programação procedural realmente é uma parada bem importante nessa jornada rumo à aprender a programar, entretanto, ao contrário da crença popular, ela não realmente representa a base para tudo o que vem depois, e somado com as confusões associadas com o termo, isso se torna uma bola de neve que prejudica bastante o aprendizado de outros temas muito importantes no futuro como a orientação a objetos.&lt;/p&gt;

&lt;p&gt;Então se esse artigo te trouxe uma nova perspectiva sobre esse assunto não deixe de dar o seu pitaco sobre esse assunto nos comentários, e compartilhar esse artigo para que mais pessoas possam aprender de forma mais informada também.&lt;/p&gt;

&lt;p&gt;Até a próxima!&lt;/p&gt;

&lt;p&gt;Ass: suporte Cansado&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>beginners</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Lidando com valores inexistentes no JS</title>
      <dc:creator>Terminal Coffee</dc:creator>
      <pubDate>Sat, 04 May 2024 18:37:50 +0000</pubDate>
      <link>https://dev.to/terminalcoffee/lidando-com-valores-negativos-no-js-27cc</link>
      <guid>https://dev.to/terminalcoffee/lidando-com-valores-negativos-no-js-27cc</guid>
      <description>&lt;p&gt;Um dos erros mais comuns no JS, principalmente entre iniciantes, seria o famoso:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Uncaught TypeError: Cannot read property 'value' of &lt;strong&gt;null&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Com outra variação aparecendo &lt;code&gt;undefined&lt;/code&gt; no lugar de &lt;code&gt;null&lt;/code&gt;, prova de como esse é um erro comum seria &lt;a href="https://stackoverflow.com/questions/22057610/uncaught-typeerror-cannot-read-property-value-of-null"&gt;essa pergunta no stack overflow&lt;/a&gt;, o maior fórum de programação do mundo, com mais de 891 mil views ao longo de 9 anos.&lt;/p&gt;

&lt;p&gt;Este problema ocorre ao tentar acessar um membro de um objeto, onde ele seria na verdade um valor nulo (&lt;code&gt;null&lt;/code&gt;) ou indefinido (&lt;code&gt;undefined&lt;/code&gt;). Aqui um exemplo:&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;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Onde se nós mudarmos o valor de &lt;code&gt;obj&lt;/code&gt; para &lt;code&gt;null&lt;/code&gt; ou &lt;code&gt;undefined&lt;/code&gt;, o erro citado no início deste artigo irá acontecer. Ex:&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;let&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// TypeError: Cannot read property 'property' of null&lt;/span&gt;
&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;//&lt;/span&gt;

&lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// TypeError: Cannot read property 'property' of undefined&lt;/span&gt;
&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E este não é exatamente um problema novo no mundo da programação, sendo até mesmo chamado de &lt;a href="https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare/"&gt;o erro de 1 bilão de dólares&lt;/a&gt;, por isso hoje iremos explorar formas de lidar com esse problema no JS.&lt;/p&gt;

&lt;h1&gt;
  
  
  # 1 Programação defensiva
&lt;/h1&gt;

&lt;p&gt;A solução mais simples para isso seria validar se o valor é null ou undefined antes de usar esse valor (inclusive se você utilizar TypeScript, isso pode ajudar ele a inferir um novo tipo para a sua variável dentro do if agora que ele tem certeza que ela existe), ex:&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;h1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;h1&lt;/span&gt;&lt;span class="dl"&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;h1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Existo por aqui&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;Ou se realmente quisermos verificar por null e undefined:&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;let&lt;/span&gt; &lt;span class="nx"&gt;acceptBool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&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;acceptBool&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;acceptBool&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;false não é undefined e nem null&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;A forma abreviada é útil quando você sabe que o valor que você vai validar não pode ser um valor falsy (que pode ser convertido em false, por exemplo uma string vazia ou 0 ou o próprio false), assim você garante que só vai cair na sua validação caso esse valor realmente não exista.&lt;/p&gt;

&lt;p&gt;Para poder lidar com esses casos onde a forma abreviada não se aplica, podemos verificar diretamente se o valor é undefined ou null, porém assim como se pode notar no segundo exemplo, isso é o código mais legível do mundo, fora que existem diversas ocasiões onde precisamos lidar com esses tipos de valores, então uma forma de melhorar essa solução poderia ser tendo uma função que abstrai essa verificação, ex:&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;isNone&lt;/span&gt; &lt;span class="o"&gt;=&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;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  # 2 Usando operadores do JS
&lt;/h1&gt;

&lt;p&gt;Por ser um problema tão comum o JS tem algumas funcionalidades nativas para lidar com alguns desses cenários, por exemplo o null coalescing operator (??), que nós podemos utilizar para prover um valor padrão caso o valor desejado seja null ou undefined:&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;valorOrNone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;valueOrNone&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Valor padrão&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Porém, apesar de muito útil, caso estivermos lidando com um objeto com outros objetos possivelmente nulos dentro dele, isso pode rapidamente se tornar um pouco confuso:&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="nf"&gt;showDeepProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&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;deepProperty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deepProperty&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;showDeepProperty&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
 &lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="na"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="na"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;propriedade profunda&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="c1"&gt;// TypeError: Cannot read property 'b' of undefined&lt;/span&gt;
&lt;span class="nf"&gt;showDeepProperty&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para corrigir isso teríamos que usar o operador de coalescencia nula para cada propriedade sendo acessada, ex:&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="nf"&gt;showDeepProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&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;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="na"&gt;c&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;c&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deepProperty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deepProperty&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;Por isso podemos utilizar um outro operador do JS para tornar esse código bem legível e conciso novamente, o optional chaining operator, ex:&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="nf"&gt;showDeepProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&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;deepProperty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deepProperty&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;Ao utilizar &lt;code&gt;?.&lt;/code&gt; antes de acessar uma propriedade ele vai acessar o valor dela se existir, entretanto se o valor for null ou undefined ele retornaria undefined, sendo a inovação aqui que ele além de não lançar um erro, permite que você vá encadeando (por isso o chaining no nome) esse operador para ir acessando camadas mais profundas desse objeto, e se em qualquer momento alguma dessas propriedades não existir ou cair no critério dito anteriormente, ele vai simplesmente retornar undefined ao invés de um erro.&lt;/p&gt;

&lt;p&gt;Com isso, podemos combinar os dois e também definir um valor padrão ao final do encadeamento:&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="nf"&gt;showDeepProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&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;deepProperty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deepProperty&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;Sendo isso o equivalente ao código mostrado que utilizava diversos operadores de coalescencia nula.&lt;/p&gt;

&lt;h1&gt;
  
  
  # 3 Null Object
&lt;/h1&gt;

&lt;p&gt;Também podemos nos utilizar de técnicas dos paradigmas suportados pelo JS para resolver esse problema, por exemplo, ao utilizarmos as funcionalidades relacionadas a orientação a objetos presentes no JS podemos implementar um &lt;em&gt;design pattern&lt;/em&gt; conhecido como &lt;strong&gt;Null Object&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;O cenário onde podemos utilizar ele seriam os casos onde precisariamos retornar um valor nulo no código, e a solução seria retornar outro valor no lugar, afinal já vimos ao longe deste artigo como ele pode não ser o melhor valor para representar a não existencia de algo no código.&lt;/p&gt;

&lt;p&gt;A ideia do Null Object para isso seria utilizar herança para ter uma classe que cria uma versão do objeto real, e outra nula, assim ambos vão ter os mesmos métodos, assim podemos confiar no polimorfismo para chamar os métodos do objeto real quando ele for retornado, e os métodos do objeto nulo no caso do valor não existir, e nesse caso os métodos do objeto nulo não fariam nada. Ex:&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;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&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;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&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;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&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;tags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tags&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;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;ifMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;perform&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;perform&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="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;NullPost&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;id&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="na"&gt;title&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="na"&gt;tags&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="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_tags&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="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;ifMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_tags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;_perform&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="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;PostsGateway&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;posts&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&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;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;NullPost&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;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PostsGateway&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;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findById&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;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ifMatch&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;oop&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;js&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Post is of OOP in JS&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;Dessa forma, caso seja retornado um objeto Post real, ele vai executar a lógica correta e se as tags do artigo baterem, ele vai mostrar a mensagem no console, e caso seja retornado um null object, nada iria acontecer.&lt;/p&gt;

&lt;h1&gt;
  
  
  # 4 Optional Monad
&lt;/h1&gt;

&lt;p&gt;Se você achou a ideia anterior interessante vai achar esta, que desta vez vai utilizar as capacidades de programação funcional do JS, muito útil também.&lt;/p&gt;

&lt;p&gt;Na programação funcional um conceito que vem cada vez se tornando mais popular mesmo fora do paradigma são as monads, que são formas de representar computações dentro de um contexto, geralmente um efeito colateral, e compor essas computações, duas delas em específico vem aparecendo mesmo em linguagens tradicionalmente orientadas a objeto como a Optional, que vamos explorar hoje e representa computações em valores possívelmente nulos, e a Result, que representa computações que podem falhar. A propósito, as Promises do JS são inspiradas nesse conceito, sendo algo semelhante a uma Monad de Result assíncrona, muitas vezes conhecida como Task.&lt;/p&gt;

&lt;p&gt;Dadas as explicações, &lt;em&gt;show me the code&lt;/em&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isNone&lt;/span&gt; &lt;span class="o"&gt;=&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;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&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;Optional&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;none&lt;/span&gt;&lt;span class="p"&gt;:&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="na"&gt;map&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&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;Optional&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;none&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;flatMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&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;Optional&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;none&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;none&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;none&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;isNone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;isSome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;some&lt;/span&gt;&lt;span class="p"&gt;:&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="na"&gt;map&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&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;Optional&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fn&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;flatMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;fn&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;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;some&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;some&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;isNone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;isSome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="p"&gt;:&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="nf"&gt;isNone&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="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;none&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;some&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="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;Optional&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;some&lt;/span&gt;&lt;span class="p"&gt;:&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&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;none&lt;/span&gt;&lt;span class="p"&gt;:&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Valor não existe&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="c1"&gt;// 2&lt;/span&gt;

&lt;span class="nx"&gt;Optional&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;some&lt;/span&gt;&lt;span class="p"&gt;:&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&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;none&lt;/span&gt;&lt;span class="p"&gt;:&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Valor não existe&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="c1"&gt;// Valor não existe&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse caso nós temos o &lt;code&gt;Optional.of&lt;/code&gt; para pegar um valor qualquer (mesmo null ou undefined) e envolver ele num Optional, em FP nós chamamos isso de lifting pois estamos elevando o valor a um dado contexto.&lt;/p&gt;

&lt;p&gt;Assim, podemos utilizar o &lt;code&gt;Optional.map&lt;/code&gt; para aplicar funções no valor dentro do Optional, semelhante a como se utilizaria o método &lt;code&gt;then&lt;/code&gt; numa promise ou o &lt;code&gt;map&lt;/code&gt; em um array, e assim como no Null Object, se for um valor &lt;code&gt;some&lt;/code&gt;, então ele, de fato, vai aplicar a função callback no valor de dentro do Optional e fazer algo com ele, agora caso ele seja um &lt;code&gt;none&lt;/code&gt;, ai nada acontece, ele simplesmente devolve outro &lt;code&gt;none&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Podemos ver o Optional quase que como uma versão do Null Object, mas que funciona para qualquer valor, semelhante a como um Array funciona para qualquer valor e não precisamos sair por ai criando uma classe de Array para cada objeto existente no sistema só para fazer a mesma coisa todas as vezes.&lt;/p&gt;

&lt;p&gt;O &lt;code&gt;Optional.match&lt;/code&gt; serve para quando precisarmos retirar o valor de dentro desse contexto, assim nós provemos uma função para cada possibilidade, seja o valor real ou nulo, e o match vai devolver como resultado o valor devolvido pela função correspondente a identidade atual do valor sendo o Optional.&lt;/p&gt;

&lt;p&gt;Tudo isso é bem legal, mas ao utilizarmos o map, o valor é envolvido novamente num contexto, e por isso se nós retornarmos um Optional no map, terminariamos com um Optional de um Optional de um valor, sendo que o que nós queremos é só que ele seja um Optional de um valor, e para resolver essa situação, nós temos o &lt;code&gt;Optional.flatMap&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="nx"&gt;Optional&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&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="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;figure&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="nf"&gt;flatMap&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;figure&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;Optional&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;figcaption&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="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nf"&gt;some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;figcaption&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;figcaption&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Legenda&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="nf"&gt;none&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Figure sem legenda&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Espero que o artigo de hoje tenha aberto sua mente para as várias técnicas que você pode usar para se livrar do null no seu código, e não se esqueça de compartilhar este artigo, até a próxima.&lt;/p&gt;

&lt;h1&gt;
  
  
  Links que podem te interessar
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://refactoring.guru/pt-br/introduce-null-object"&gt;Refactoring Guru sobre Null Object&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing"&gt;Null Coalescing Operator no MDN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining"&gt;Optional Chaining no MDN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Monad_(functional_programming)"&gt;Wikipedia sobre Monads na prática&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Monad_(category_theory)"&gt;Wikipedia sobre Monads na Matemática&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jrsinclair.com/articles/2016/marvellously-mysterious-javascript-maybe-monad/"&gt;Ótimo artigo sobre o Optional&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ass: Suporte Cansado.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Especial 1 de Maio - Explorando a Diversidade da TI</title>
      <dc:creator>Terminal Coffee</dc:creator>
      <pubDate>Wed, 01 May 2024 20:50:06 +0000</pubDate>
      <link>https://dev.to/terminalcoffee/especial-1-de-maio-explorando-a-diversidade-da-ti-2nk4</link>
      <guid>https://dev.to/terminalcoffee/especial-1-de-maio-explorando-a-diversidade-da-ti-2nk4</guid>
      <description>&lt;p&gt;Introdução&lt;/p&gt;

&lt;p&gt;O dia 1º de maio no Brasil comemora o Dia do Trabalho em nossa nação, marcando um grande feriado para a maioria dos trabalhadores desfrutarem de um dia de folga e relaxamento. Por isso, hoje nós, do Terminal Coffee, vamos apresentar 4 profissões para você que deseja trabalhar na área de Tecnologia da Informação, ou simplesmente T.I. para os íntimos. Então, sem mais delongas, segue a lista!&lt;/p&gt;

&lt;h2&gt;
  
  
  1 - Desenvolvimento de Software
&lt;/h2&gt;

&lt;p&gt;No topo de nossa lista está o desenvolvimento de software, a mais famosa e, para muitos, a mais assustadora área para quem não é da área. Por isso, não poderíamos falar sobre T.I. sem começar por ela; seria quase um pecado da tecnologia. O desenvolvimento de software é a base das equipes e literalmente cria todas as ferramentas que usamos em computadores e smartphones. Eles são responsáveis pelos fundamentos e funcionalidades dos sistemas, assim como um bom pedreiro constrói uma casa. É por isso que os apelidei de 'pedreiros de código', pois quando algo dá errado, ou no caso, o sistema falha, eles são os primeiros que você lembra de ofender até a quinta geração.&lt;/p&gt;

&lt;p&gt;Por ser uma área muito versátil e abrangente, com inúmeras linguagens para se especializar, há a possibilidade de atuar em diversos projetos, desde programas web com HTML e CSS até sistemas mais complexos com Java e suas variantes.&lt;/p&gt;

&lt;h2&gt;
  
  
  2 - Redes e Segurança
&lt;/h2&gt;

&lt;p&gt;Se a pessoa que trabalha com desenvolvimento de software é como o pedreiro de um sistema, com certeza quem trabalha com redes e segurança é como o porteiro que impede a entrada de Trojans (Cavalos de Tróia), Malwares e Spywares indesejados no seu sistema. São eles que sabem como manter seus dados seguros e até mesmo encontrá-los. Portanto, agradeça todos os dias por seus dados do Facebook não terem sido vazados (quer dizer, não outra vez) e sempre tenha cuidado com onde você acessa. De nada adianta esses profissionais trabalharem se você desabilita seu firewall e DNS para baixar jogos e conteúdos ilegais.&lt;/p&gt;

&lt;h2&gt;
  
  
  3 - Análise de Dados e Business Intelligence (BI)
&lt;/h2&gt;

&lt;p&gt;Análise de dados é uma função de suma importância nas empresas atualmente, pois seu trabalho bem feito é mandatório para tomadas de decisões bem-sucedidas e lucrativas de uma empresa. É uma área extremamente complexa e frequentemente subestimada no dia a dia dos profissionais do ramo.&lt;/p&gt;

&lt;h2&gt;
  
  
  4 - Gerenciamento de Projetos de TI
&lt;/h2&gt;

&lt;p&gt;Por fim, para fechar nossa lista de hoje, temos o gerenciamento de TI. Toda equipe precisa de um bom líder para gerenciar seu desenvolvimento. É como no futebol: um bom técnico pode levar uma equipe mediana a ter grandes resultados, mas um técnico ruim pode levar a melhor das equipes a ter o pior dos resultados (Não é mesmo, Vitor Pereira?). São esses os 'caras chatos' que mantêm o cronograma de desenvolvimento em dia, calculam os gastos para o projeto não gerar prejuízos antes do término, garantem a boa comunicação da equipe e impedem que os membros se 'matem' nas reuniões de desenvolvimento. Geralmente, são eles que conversam diretamente com o cliente, tendo uma grande responsabilidade em suas mãos.&lt;/p&gt;

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

&lt;p&gt;Um post curto só para não deixar o dia passar. Um bom feriado a todos! Se gostaram do texto, deixem seu like e comentem para que possamos trazer uma parte 2 com profissões menos conhecidas na área de TI.&lt;/p&gt;

&lt;p&gt;Ass: Estagiário mal remunerado.&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>beginners</category>
      <category>programming</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
