<?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: Yuri Peixinho</title>
    <description>The latest articles on DEV Community by Yuri Peixinho (@yuripeixinho).</description>
    <link>https://dev.to/yuripeixinho</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1647416%2Fcb24132f-cdc1-4080-8977-0786f79ceb26.png</url>
      <title>DEV Community: Yuri Peixinho</title>
      <link>https://dev.to/yuripeixinho</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yuripeixinho"/>
    <language>en</language>
    <item>
      <title>POO: Polimorfismo</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Fri, 21 Aug 2026 23:26:48 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/poo-polimorfismo-1b1a</link>
      <guid>https://dev.to/yuripeixinho/poo-polimorfismo-1b1a</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Imagina que você tá fazendo um jogo com vários tipos de monstro, mas ainda &lt;strong&gt;sem&lt;/strong&gt; polimorfismo. Cada monstro é só um "tipo" e uma função central decide o que cada um faz:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Atacar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;tipoMonstro&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tipoMonstro&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Dragao"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"🔥 Cospe uma bola de fogo!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tipoMonstro&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Fantasma"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"👻 Atravessa a parede e assusta!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tipoMonstro&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Slime"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"🟢 Pula e gruda em você!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// toda vez que você inventa um monstro novo, tem que vir AQUI e adicionar mais um "else if"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso funciona, mas é uma bomba-relógio: essa função vai crescer pra sempre, e todo mundo que mexe no jogo precisa saber que ela existe e lembrar de atualizá-la. É frágil e cansativo.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;A ideia central do polimorfismo&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Em vez de uma função central que &lt;strong&gt;pergunta&lt;/strong&gt; "que tipo é você?", cada monstro &lt;strong&gt;já sabe&lt;/strong&gt; se comportar sozinho. Você não pergunta, você só manda:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;**&lt;/span&gt;&lt;span class="k"&gt;abstract&lt;/span&gt;&lt;span class="p"&gt;**&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Monstro&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Vida&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;set&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="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nf"&gt;Monstro&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Atacar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;TomarDano&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;dano&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Vida&lt;/span&gt; &lt;span class="p"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;dano&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; perdeu &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;dano&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; de vida (restam &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Vida&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E cada monstro implementa sua própria versão:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dragao&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Monstro&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Dragao&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Dragão"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Atacar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; 🔥 cospe uma bola de fogo!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Fantasma&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Monstro&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Fantasma&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Fantasma"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Atacar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; 👻 atravessa a parede e assusta!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;TomarDano&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;dano&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;danoReal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dano&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// é intangível, sofre metade do dano&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; é intangível — dano reduzido pela metade!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;TomarDano&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;danoReal&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;class&lt;/span&gt; &lt;span class="nc"&gt;Slime&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Monstro&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Slime&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Slime"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Atacar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; 🟢 pula e gruda em você!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Golem&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Monstro&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Golem&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Golem"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Vida&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// é um tanque, vida maior&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Atacar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; 🪨 esmaga o chão com o punho!"&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;Repara que &lt;code&gt;Fantasma&lt;/code&gt; não só ataca diferente — ele &lt;strong&gt;reage a dano diferente também&lt;/strong&gt;, porque sobrescreveu &lt;code&gt;TomarDano&lt;/code&gt;. Cada classe carrega sua própria lógica, não só um texto diferente.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Colocando pra rodar: a batalha completa&lt;/strong&gt;
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Monstro&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;inimigos&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Dragao&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Fantasma&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Slime&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Golem&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;inimigo&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;inimigos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;inimigo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Atacar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;inimigo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;TomarDano&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Sa&lt;/span&gt;&lt;span class="err"&gt;í&lt;/span&gt;&lt;span class="n"&gt;da&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;Drag&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="err"&gt;🔥&lt;/span&gt; &lt;span class="n"&gt;cospe&lt;/span&gt; &lt;span class="n"&gt;uma&lt;/span&gt; &lt;span class="n"&gt;bola&lt;/span&gt; &lt;span class="n"&gt;de&lt;/span&gt; &lt;span class="n"&gt;fogo&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;
&lt;span class="n"&gt;Drag&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="n"&gt;perdeu&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt; &lt;span class="n"&gt;de&lt;/span&gt; &lt;span class="nf"&gt;vida&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;restam&lt;/span&gt; &lt;span class="m"&gt;70&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="n"&gt;Fantasma&lt;/span&gt; &lt;span class="err"&gt;👻&lt;/span&gt; &lt;span class="n"&gt;atravessa&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;parede&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="n"&gt;assusta&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;
&lt;span class="n"&gt;Fantasma&lt;/span&gt; &lt;span class="err"&gt;é&lt;/span&gt; &lt;span class="n"&gt;intang&lt;/span&gt;&lt;span class="err"&gt;í&lt;/span&gt;&lt;span class="n"&gt;vel&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="n"&gt;dano&lt;/span&gt; &lt;span class="n"&gt;reduzido&lt;/span&gt; &lt;span class="n"&gt;pela&lt;/span&gt; &lt;span class="n"&gt;metade&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;
&lt;span class="n"&gt;Fantasma&lt;/span&gt; &lt;span class="n"&gt;perdeu&lt;/span&gt; &lt;span class="m"&gt;15&lt;/span&gt; &lt;span class="n"&gt;de&lt;/span&gt; &lt;span class="nf"&gt;vida&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;restam&lt;/span&gt; &lt;span class="m"&gt;85&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="n"&gt;Slime&lt;/span&gt; &lt;span class="err"&gt;🟢&lt;/span&gt; &lt;span class="n"&gt;pula&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="n"&gt;gruda&lt;/span&gt; &lt;span class="n"&gt;em&lt;/span&gt; &lt;span class="n"&gt;voc&lt;/span&gt;&lt;span class="err"&gt;ê&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;
&lt;span class="n"&gt;Slime&lt;/span&gt; &lt;span class="n"&gt;perdeu&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt; &lt;span class="n"&gt;de&lt;/span&gt; &lt;span class="nf"&gt;vida&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;restam&lt;/span&gt; &lt;span class="m"&gt;70&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="n"&gt;Golem&lt;/span&gt; &lt;span class="err"&gt;🪨&lt;/span&gt; &lt;span class="n"&gt;esmaga&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="n"&gt;punho&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;
&lt;span class="n"&gt;Golem&lt;/span&gt; &lt;span class="n"&gt;perdeu&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt; &lt;span class="n"&gt;de&lt;/span&gt; &lt;span class="nf"&gt;vida&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;restam&lt;/span&gt; &lt;span class="m"&gt;170&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mesmo código (&lt;code&gt;inimigo.Atacar()&lt;/code&gt;, &lt;code&gt;inimigo.TomarDano(30)&lt;/code&gt;) rodando pra quatro tipos diferentes, cada um reagindo do seu próprio jeito. Zero &lt;code&gt;if&lt;/code&gt;, zero &lt;code&gt;switch&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;O verdadeiro poder: extensibilidade&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Quer adicionar um &lt;code&gt;Vampiro&lt;/code&gt; que rouba vida ao atacar? Você cria a classe...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Vampiro&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Monstro&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Vampiro&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Vampiro"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Atacar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; 🧛 morde e rouba sua vida!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...e pronto. &lt;strong&gt;Não precisa tocar em nenhuma linha da lista, do &lt;code&gt;foreach&lt;/code&gt;, ou de qualquer código que já existia.&lt;/strong&gt; Isso é o Princípio Aberto/Fechado (aquele "O" do SOLID) na prática: o sistema está aberto pra crescer, mas fechado pra você precisar reabrir e editar o que já funciona.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Os dois tipos de polimorfismo (pra fechar com chave de ouro)&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Tudo que fizemos até aqui é &lt;strong&gt;polimorfismo em tempo de execução&lt;/strong&gt; (via &lt;code&gt;override&lt;/code&gt;) — o mais importante e o que todo mundo quer dizer quando fala "polimorfismo" em POO. Mas existe um segundo tipo, mais simples, decidido em &lt;strong&gt;tempo de compilação&lt;/strong&gt;: sobrecarga de métodos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Curandeiro&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Curar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Monstro&lt;/span&gt; &lt;span class="n"&gt;alvo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;alvo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;TomarDano&lt;/span&gt;&lt;span class="p"&gt;(-&lt;/span&gt;&lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// cura um&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Curar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Monstro&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;aliados&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;aliados&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;TomarDano&lt;/span&gt;&lt;span class="p"&gt;(-&lt;/span&gt;&lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// cura vários&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 o compilador escolhe qual &lt;code&gt;Curar&lt;/code&gt; chamar baseado nos argumentos que você passa — antes mesmo do programa rodar. Não tem nada de dinâmico, é só "mesmo nome, assinaturas diferentes".&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Como o C# sabe qual versão rodar&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A parte que parece mágica: repare que a lista é &lt;code&gt;List&amp;lt;Monstro&amp;gt;&lt;/code&gt;, não &lt;code&gt;List&amp;lt;Dragao&amp;gt;&lt;/code&gt; ou qualquer coisa específica.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Monstro&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Fantasma&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Atacar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// roda a versão do Fantasma, mesmo "m" sendo do tipo Monstro&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O C# decide &lt;strong&gt;qual &lt;code&gt;Atacar()&lt;/code&gt; rodar olhando pro tipo real do objeto guardado na memória&lt;/strong&gt; — não pro tipo da variável que você usou pra referenciar ele. É por isso que o &lt;code&gt;foreach&lt;/code&gt; funciona perfeitamente numa lista cheia de tipos misturados: em cada volta, o objeto "lembra" quem ele realmente é.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>csharp</category>
      <category>gamedev</category>
      <category>programming</category>
    </item>
    <item>
      <title>POO: Herança</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Fri, 21 Aug 2026 22:55:28 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/poo-heranca-52jb</link>
      <guid>https://dev.to/yuripeixinho/poo-heranca-52jb</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Uma classe (subclasse/derivada) reaproveita estrutura e comportamento de outra (superclasse/base), podendo especializar o que for necessário.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Funcionario&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;SalarioBase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Funcionario&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;salarioBase&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;SalarioBase&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;salarioBase&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;virtual&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;CalcularSalario&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;SalarioBase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Gerente&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Funcionario&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;decimal&lt;/span&gt; &lt;span class="n"&gt;_bonus&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Gerente&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;salarioBase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;bonus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;salarioBase&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_bonus&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bonus&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;override&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;CalcularSalario&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CalcularSalario&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;_bonus&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;Repare em três mecanismos importantes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;: base(nome, salarioBase)&lt;/code&gt; — chama o construtor da classe pai.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;virtual&lt;/code&gt; na base — sinaliza "isso pode ser reescrito".&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;override&lt;/code&gt; + &lt;code&gt;base.CalcularSalario()&lt;/code&gt; — reescreve mas ainda reaproveita a lógica original.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Tipos de relação que herança modela&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Regra de ouro é o teste &lt;strong&gt;"é um"&lt;/strong&gt; (is-a): &lt;code&gt;Gerente&lt;/code&gt; &lt;strong&gt;é um&lt;/strong&gt; &lt;code&gt;Funcionario&lt;/code&gt;. Se a relação real é "&lt;strong&gt;tem um&lt;/strong&gt;" (has-a), a resposta certa é composição, não herança — &lt;code&gt;Carro&lt;/code&gt; &lt;strong&gt;tem um&lt;/strong&gt; &lt;code&gt;Motor&lt;/code&gt;, não deveria herdar de &lt;code&gt;Motor&lt;/code&gt;. O livro “Head First Design Pattern”, aborda de forma eficiente sobre preferir composições ao invés de herança.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;sealed&lt;/code&gt;&lt;/strong&gt; trava a herança:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RelatorioFinal&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Funcionario&lt;/span&gt; &lt;span class="cm"&gt;/* ninguém pode herdar disso */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Útil quando você quer garantir que o comportamento não será alterado por subclasses além de ser bom pra segurança e pra o compilador otimizar chamadas (sem precisar checar override em runtime).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A armadilha da herança profunda:&lt;/strong&gt; cada nível adiciona acoplamento. Se &lt;code&gt;Funcionario → Gerente → GerenteRegional → DiretorRegional&lt;/code&gt;, uma mudança lá em cima em &lt;code&gt;Funcionario&lt;/code&gt; pode quebrar comportamento três níveis abaixo de um jeito difícil de rastrear. Regra prática: se você passar de 2 níveis de herança, pare e pergunte se composição resolveria melhor (voltamos nisso na conversa anterior, com o exemplo do &lt;code&gt;IComportamentoVoo&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C# não tem herança múltipla de classes&lt;/strong&gt; (só de interfaces) — justamente pra evitar o "problema do diamante": se &lt;code&gt;C&lt;/code&gt; herdasse de &lt;code&gt;A&lt;/code&gt; e &lt;code&gt;B&lt;/code&gt;, e ambos tivessem um método &lt;code&gt;Fazer()&lt;/code&gt;, qual implementação &lt;code&gt;C&lt;/code&gt; usaria? C# resolve isso simplesmente proibindo.&lt;/p&gt;

&lt;h1&gt;
  
  
  Exemplo de jogo
&lt;/h1&gt;

&lt;p&gt;Temos uma classe &lt;code&gt;Personagem&lt;/code&gt; e agora criamos tipos especializados que reaproveitam tudo que &lt;code&gt;Personagem&lt;/code&gt; já tem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Personagem&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Atacar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Personagem&lt;/span&gt; &lt;span class="n"&gt;alvo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;dano&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;CalcularDano&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;          &lt;span class="c1"&gt;// fórmula escondida&lt;/span&gt;
        &lt;span class="n"&gt;alvo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;TomarDano&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dano&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; atacou &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;alvo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; causando &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;dano&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; de dano!"&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="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;CalcularDano&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;critico&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Random&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Next&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="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;15&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 15% de chance&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;danoBase&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;critico&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;danoBase&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;danoBase&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Guerreiro&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Personagem&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Armadura&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&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="nf"&gt;Guerreiro&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vidaMaxima&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;150&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Armadura&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;20&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;class&lt;/span&gt; &lt;span class="nc"&gt;Mago&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Personagem&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Mana&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;set&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="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Mago&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vidaMaxima&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Arqueiro&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Personagem&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Arqueiro&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vidaMaxima&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="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;&lt;code&gt;Guerreiro&lt;/code&gt;, &lt;code&gt;Mago&lt;/code&gt; e &lt;code&gt;Arqueiro&lt;/code&gt; ganham &lt;code&gt;Nome&lt;/code&gt;, &lt;code&gt;Vida&lt;/code&gt;, &lt;code&gt;Atacar()&lt;/code&gt;, &lt;code&gt;TomarDano()&lt;/code&gt; e &lt;code&gt;Curar()&lt;/code&gt; de graça — não precisaram reescrever nada disso. Cada um só adiciona o que é específico dele (&lt;code&gt;Armadura&lt;/code&gt;, &lt;code&gt;Mana&lt;/code&gt;).&lt;/p&gt;

</description>
      <category>coding</category>
      <category>dotnet</category>
      <category>programming</category>
      <category>software</category>
    </item>
    <item>
      <title>POO: Abstração</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Fri, 21 Aug 2026 22:46:15 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/poo-abstracao-3gei</link>
      <guid>https://dev.to/yuripeixinho/poo-abstracao-3gei</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Definição: &lt;strong&gt;expor o "o quê" e esconder o "como"&lt;/strong&gt;. É a diferença entre uma interface de operação e sua implementação.&lt;/p&gt;

&lt;p&gt;Isso normalmente é confundido com encapsulamento, mas são coisas diferentes: encapsulamento é sobre &lt;em&gt;proteção&lt;/em&gt; do estado; abstração é sobre &lt;em&gt;simplificação&lt;/em&gt; da complexidade — reduzir um problema complexo a um modelo mais simples de interagir.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;INotificador&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Enviar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;mensagem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;destinatario&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NotificadorEmail&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;INotificador&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Enviar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;mensagem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;destinatario&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// conecta em SMTP, monta o corpo do e-mail, trata retry, etc — tudo escondido&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"E-mail enviado para &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;destinatario&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NotificadorSms&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;INotificador&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Enviar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;mensagem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;destinatario&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// chama API de SMS, formata número, etc — também escondido&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"SMS enviado para &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;destinatario&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quem usa &lt;code&gt;INotificador&lt;/code&gt; não sabe (nem precisa saber) se por trás tem uma chamada SMTP ou uma API REST de SMS. Só conhece o contrato: &lt;code&gt;Enviar(mensagem, destinatario)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Níveis de abstração&lt;/strong&gt; — pense numa aplicação em camadas: &lt;code&gt;Controller&lt;/code&gt; chama &lt;code&gt;IPedidoService&lt;/code&gt;, que chama &lt;code&gt;IPedidoRepository&lt;/code&gt;, que fala com o banco. Cada camada abstrai a complexidade da camada de baixo. Isso é abstração acontecendo em escala arquitetural, não só numa classe.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Abstração vazada (leaky abstraction)&lt;/strong&gt; é o antipadrão aqui: quando detalhes de implementação "vazam" pro contrato. Exemplo clássico: um método &lt;code&gt;INotificador.Enviar()&lt;/code&gt; que lança &lt;code&gt;SmtpException&lt;/code&gt; — isso força quem usa a interface a conhecer detalhes de uma implementação específica (e-mail), quebrando a abstração.&lt;/p&gt;

&lt;h1&gt;
  
  
  Exemplo aplicado a jogo
&lt;/h1&gt;

&lt;p&gt;Quando você aperta "Atacar" no controle, você não calcula chance de crítico, multiplicador elemental, redução por armadura — o jogo esconde essa complexidade toda atrás de um botão simples. Isso é abstração.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Personagem&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Atacar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Personagem&lt;/span&gt; &lt;span class="n"&gt;alvo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;dano&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;CalcularDano&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;          &lt;span class="c1"&gt;// fórmula escondida&lt;/span&gt;
        &lt;span class="n"&gt;alvo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;TomarDano&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dano&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; atacou &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;alvo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; causando &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;dano&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; de dano!"&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="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;CalcularDano&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;critico&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Random&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Next&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="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;15&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 15% de chance&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;danoBase&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;critico&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;danoBase&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;danoBase&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;Quem chama &lt;code&gt;personagem.Atacar(inimigo)&lt;/code&gt; não faz ideia de que existe cálculo de crítico rolando por trás. Só vê a ação. É exatamente essa "caixa preta simples por fora, complexa por dentro" que é a abstração.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>programming</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>POO: Encapsulamento</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Fri, 21 Aug 2026 22:42:23 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/poo-encapsulamento-36lb</link>
      <guid>https://dev.to/yuripeixinho/poo-encapsulamento-36lb</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;O conceito de encapusalento é primordial para proteger nossas classes. Vamos ser didáticos aqui e fingir que estamos desenvolvendo um jogo de RPG. Pensa na vida (HP) do personagem como aquela barrinha vermelha no topo da tela. Se qualquer parte do código puder mexer nela direto, é fácil alguém, por engano, jogar a vida pra -500 ou deixar passar do máximo — bug feio, barra quebrada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Personagem&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;VidaMaxima&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_vida&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;              &lt;span class="c1"&gt;// ninguém mexe aqui de fora&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Vida&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_vida&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="c1"&gt;// só leitura&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Personagem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;vidaMaxima&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;VidaMaxima&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vidaMaxima&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;_vida&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vidaMaxima&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;TomarDano&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;dano&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_vida&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Max&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="n"&gt;_vida&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;dano&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;// nunca fica negativo&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_vida&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="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; foi derrotado!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Curar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;quantidade&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_vida&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;VidaMaxima&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_vida&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;quantidade&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// nunca passa do máximo&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;Repara: &lt;code&gt;personagem.Vida = -50;&lt;/code&gt; nem compila. A única forma de mexer na vida é passando pelas regras (&lt;code&gt;TomarDano&lt;/code&gt;, &lt;code&gt;Curar&lt;/code&gt;), que garantem que ela nunca sai do intervalo válido. Isso é encapsulamento — o dado protegido pela lógica que mora junto dele.&lt;/p&gt;

&lt;p&gt;Um detalhe importante é:  não é só "usar &lt;code&gt;private&lt;/code&gt;", é &lt;strong&gt;agrupar dados e o comportamento que os manipula, escondendo os detalhes internos e expondo uma interface controlada&lt;/strong&gt;. O objetivo é garantir que o objeto nunca fique num estado inválido.&lt;/p&gt;

&lt;h1&gt;
  
  
  Os dois níveis de encapsulamento
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Dois níveis de encapsulamento que gente costuma confundir:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data hiding&lt;/strong&gt; — esconder os campos (&lt;code&gt;private decimal _saldo&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Information hiding&lt;/strong&gt; (mais amplo) — esconder a &lt;em&gt;implementação&lt;/em&gt;, não só os dados. Exemplo: trocar a implementação interna de uma &lt;code&gt;Lista&lt;/code&gt; de array pra lista ligada sem que ninguém que usa a classe perceba.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Nível de acesso em C
&lt;/h1&gt;

&lt;p&gt;É importante e cai muito bem dominar todos, não só o &lt;code&gt;public&lt;/code&gt;/&lt;code&gt;private&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Exemplo&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;      &lt;span class="c1"&gt;// só dentro da própria classe&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// classe e subclasses&lt;/span&gt;
    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="c1"&gt;// mesmo assembly&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// subclasses OU mesmo assembly&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// subclasses DENTRO do mesmo assembly&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="c1"&gt;// qualquer um&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Erro comum
&lt;/h1&gt;

&lt;p&gt;Um erro comum é expor um campo mutável de referência (lista, array) via getter público quebra o encapsulamento mesmo com &lt;code&gt;private set&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pedido&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_itens&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Itens&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_itens&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// PERIGO: quem chamar Itens.Add() muda o estado interno direto&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O fix é retornar uma cópia ou uma interface somente-leitura: &lt;code&gt;IReadOnlyList&amp;lt;string&amp;gt; Itens =&amp;gt; _itens.AsReadOnly();&lt;/code&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>csharp</category>
      <category>dotnet</category>
      <category>programming</category>
    </item>
    <item>
      <title>Programação Orientada a Objetos</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Fri, 21 Aug 2026 22:31:07 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/programacao-orientada-a-objetos-2623</link>
      <guid>https://dev.to/yuripeixinho/programacao-orientada-a-objetos-2623</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Programação Orientada a Objetos é um paradigma (um jeito de organizar código) onde você modela o problema como um conjunto de &lt;strong&gt;objetos&lt;/strong&gt; que têm &lt;strong&gt;estado&lt;/strong&gt; (dados) e &lt;strong&gt;comportamento&lt;/strong&gt; (métodos), em vez de modelar como uma sequência de instruções que manipulam dados soltos.&lt;/p&gt;

&lt;p&gt;A ideia central: em vez de separar "dados" de um lado e "funções que mexem nos dados" do outro, você agrupa os dois numa única unidade — o objeto.&lt;/p&gt;

&lt;h1&gt;
  
  
  Pra que serve / que problema resolve
&lt;/h1&gt;

&lt;p&gt;Antes da POO ficar popular, a programação era predominantemente &lt;strong&gt;procedural&lt;/strong&gt;: um monte de funções manipulando estruturas de dados globais ou passadas por parâmetro. Isso funciona bem em programas pequenos, mas cresce mal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Estilo procedural&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;ContaBancaria&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;decimal&lt;/span&gt; &lt;span class="n"&gt;Saldo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Sacar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;ContaBancaria&lt;/span&gt; &lt;span class="n"&gt;conta&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;conta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Saldo&lt;/span&gt; &lt;span class="p"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// nada impede alguém de fazer conta.Saldo = -9999 direto&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Qualquer parte do código pode mexer em &lt;code&gt;Saldo&lt;/code&gt; sem passar pelas regras de negócio. Conforme o sistema cresce, fica impossível garantir que os dados estão sempre num estado válido.&lt;/p&gt;

&lt;p&gt;A POO ataca esse problema principal: &lt;strong&gt;acoplar dados às regras que os protegem&lt;/strong&gt;, e além disso:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Organiza sistemas grandes em pedaços independentes e reutilizáveis&lt;/li&gt;
&lt;li&gt;Modela o domínio do problema de um jeito mais próximo de como pensamos no mundo real (um &lt;code&gt;Cliente&lt;/code&gt;, um &lt;code&gt;Pedido&lt;/code&gt;, uma &lt;code&gt;ContaBancaria&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Facilita manutenção: mudanças ficam localizadas dentro da classe responsável
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Estilo orientado a objetos&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContaBancaria&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;decimal&lt;/span&gt; &lt;span class="n"&gt;Saldo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Sacar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;valor&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Saldo&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="nf"&gt;InvalidOperationException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Saldo insuficiente"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Saldo&lt;/span&gt; &lt;span class="p"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;valor&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;Agora é &lt;strong&gt;impossível&lt;/strong&gt; deixar o saldo inválido de fora da classe — a regra mora junto com o dado.&lt;/p&gt;

&lt;h1&gt;
  
  
  Classe vs Objeto
&lt;/h1&gt;

&lt;p&gt;Essa distinção é a base de tudo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Classe&lt;/strong&gt; é o molde/template — a definição de que atributos e comportamentos algo terá.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Objeto&lt;/strong&gt; (ou instância) é uma "coisa concreta" criada a partir desse molde.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;csharp&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Carro&lt;/span&gt; &lt;span class="c1"&gt;// classe: o molde&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Modelo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Velocidade&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Acelerar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Velocidade&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Carro&lt;/span&gt; &lt;span class="n"&gt;meuCarro&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Carro&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Modelo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Civic"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;   &lt;span class="c1"&gt;// objeto 1&lt;/span&gt;
&lt;span class="n"&gt;Carro&lt;/span&gt; &lt;span class="n"&gt;carroDoAmigo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Carro&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Modelo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Corolla"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// objeto 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Carro&lt;/code&gt; é uma classe só. &lt;code&gt;meuCarro&lt;/code&gt; e &lt;code&gt;carroDoAmigo&lt;/code&gt; são dois objetos independentes, cada um com seu próprio estado.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Por que isso importa na prática&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;O ganho real não é "seguir um paradigma bonito",  é que sistemas orientados a objetos bem feitos tendem a ser mais fáceis de estender sem quebrar o que já existe, mais fáceis de testar (cada objeto isolado), e mais fáceis de entender porque o código espelha o vocabulário do problema real.&lt;/p&gt;

&lt;h1&gt;
  
  
  Aprofundamentos (Visão Geral)
&lt;/h1&gt;

&lt;p&gt;Ao entender o que o POO resolve na prática, seremos capazes de entrar nos pilares e conceitos fundamentais.&lt;/p&gt;

&lt;p&gt;São eles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Principais Pilares&lt;/li&gt;
&lt;li&gt;Funcionalidades do Paradigma&lt;/li&gt;
&lt;li&gt;Model-Driven Design&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>code</category>
      <category>programming</category>
    </item>
    <item>
      <title>Livro Head First Design Pattern: Prefira composição em vez de herança</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sat, 08 Aug 2026 16:51:44 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/prefira-composicao-em-vez-de-heranca-f8e</link>
      <guid>https://dev.to/yuripeixinho/prefira-composicao-em-vez-de-heranca-f8e</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Herança modela uma relação &lt;strong&gt;"é um"&lt;/strong&gt; (&lt;em&gt;is-a&lt;/em&gt;): &lt;code&gt;MallardDuck&lt;/code&gt; &lt;strong&gt;é um&lt;/strong&gt; &lt;code&gt;Duck&lt;/code&gt;. Composição modela uma relação &lt;strong&gt;"tem um"&lt;/strong&gt; (&lt;em&gt;has-a&lt;/em&gt;): &lt;code&gt;Duck&lt;/code&gt; &lt;strong&gt;tem um&lt;/strong&gt; &lt;code&gt;FlyBehavior&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O princípio diz: quando você precisa reutilizar código ou compor comportamento, prefira montar um objeto a partir de peças menores (composição) a herdar de uma superclasse cada vez mais inchada. Isso não significa banir herança — significa não usá-la como ferramenta padrão para todo tipo de reuso.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Por que herança vira um problema&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Você herda comportamento, mas herda &lt;strong&gt;tudo&lt;/strong&gt;, mesmo o que não serve. E como a subclasse é compilada contra a estrutura interna da superclasse, qualquer mudança na superclasse se propaga — às vezes de forma inesperada — para toda a árvore de descendentes. Isso é chamado de &lt;strong&gt;fragile base class problem&lt;/strong&gt; (problema da classe-base frágil): você não consegue mais mexer na classe-mãe com segurança, porque não sabe quais das dezenas de subclasses dependem de algum detalhe interno dela.&lt;/p&gt;

&lt;p&gt;O sintoma mais visível, porém, é a &lt;strong&gt;explosão combinatória&lt;/strong&gt;: quando um comportamento varia em mais de uma dimensão, cada combinação nova de dimensões vira uma classe nova.&lt;/p&gt;

&lt;p&gt;!image.png&lt;/p&gt;

&lt;p&gt;Repare no padrão: são só &lt;strong&gt;2 dimensões&lt;/strong&gt; (voa ou não / faz som ou fica mudo), cada uma com 2 opções, e isso já gera &lt;strong&gt;4 classes concretas&lt;/strong&gt;. Some uma terceira dimensão — digamos, cor da plumagem, com 2 variações — e você pula para &lt;strong&gt;8 classes&lt;/strong&gt;. É crescimento multiplicativo, não aditivo: 2x2x2 = 8, não 2 + 2 + 2 = 6. Cada combinação nova de comportamentos que alguém pedir vira uma classe nova, e a maior parte do código dentro dela é cópia com pequenas variações.&lt;/p&gt;

&lt;h1&gt;
  
  
  A Correção
&lt;/h1&gt;

&lt;p&gt;Em vez de &lt;code&gt;Duck&lt;/code&gt; ramificar em subclasses por combinação de comportamento, &lt;code&gt;Duck&lt;/code&gt; passa a &lt;strong&gt;compor&lt;/strong&gt; dois objetos independentes — um &lt;code&gt;FlyBehavior&lt;/code&gt; e um &lt;code&gt;QuackBehavior&lt;/code&gt; — e delega a eles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Duck&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;FlyBehavior&lt;/span&gt; &lt;span class="n"&gt;flyBehavior&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;QuackBehavior&lt;/span&gt; &lt;span class="n"&gt;quackBehavior&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&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, 2 variações de voo + 2 variações de som não geram 4 classes — geram &lt;strong&gt;2 + 2 = 4 objetos de comportamento&lt;/strong&gt;, que são livremente combinados em qualquer &lt;code&gt;Duck&lt;/code&gt;. Ao adicionar uma terceira dimensão, você não multiplica: apenas soma mais uma família de comportamentos independente. É o mesmo diagrama de composição que te mostrei antes, só que agora você já entende o problema que ele existe para evitar.&lt;/p&gt;

&lt;h1&gt;
  
  
  Quando herança ainda é a escolha certa
&lt;/h1&gt;

&lt;p&gt;O princípio não é "nunca use herança" — é "não use herança como padrão automático". Ela continua sendo a ferramenta certa quando:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a relação &lt;strong&gt;é-um&lt;/strong&gt; é genuinamente verdadeira e estável (um &lt;code&gt;Círculo&lt;/code&gt; é uma &lt;code&gt;Forma&lt;/code&gt;, e sempre será);&lt;/li&gt;
&lt;li&gt;as subclasses respeitam o &lt;strong&gt;Liskov Substitution Principle&lt;/strong&gt; — qualquer subclasse pode substituir a superclasse sem quebrar expectativas de quem usa;&lt;/li&gt;
&lt;li&gt;a hierarquia é rasa (1-2 níveis) e não vai crescer em múltiplas dimensões independentes;&lt;/li&gt;
&lt;li&gt;você quer reaproveitar uma implementação já testada e não espera variação de comportamento em runtime.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O sinal de alerta para trocar por composição é quando você percebe que está adicionando um método a uma subclasse só para sobrescrevê-lo como vazio ou lançar &lt;code&gt;UnsupportedOperationException&lt;/code&gt; (&lt;code&gt;RubberDuck.fly() { }&lt;/code&gt;) — isso é sintoma clássico de que a hierarquia está forçando um comportamento que não pertence a todos os descendentes.&lt;/p&gt;

&lt;h1&gt;
  
  
  Padrões que existem para viabilizar composição
&lt;/h1&gt;

&lt;p&gt;Vários padrões do catálogo GoF são, na prática, formas estruturadas de aplicar este princípio:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Strategy&lt;/strong&gt; — comportamento intercambiável via composição (&lt;code&gt;FlyBehavior&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decorator&lt;/strong&gt; — adiciona responsabilidades a um objeto envolvendo-o em outro objeto com a mesma interface, em vez de criar uma subclasse para cada combinação de responsabilidades (ex: &lt;code&gt;CoffeeWithMilk&lt;/code&gt;, &lt;code&gt;CoffeeWithMilkAndSugar&lt;/code&gt;... vira apenas decoradores empilhados).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Composite&lt;/strong&gt; — monta estruturas de árvore (parte-todo) compondo objetos recursivamente, sem hierarquia de herança rígida entre "folha" e "galho".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bridge&lt;/strong&gt; — separa uma abstração da sua implementação em duas hierarquias independentes que se compõem, exatamente para evitar a explosão combinatória que o diagrama acima mostra.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  O problema do "diamante" (bônus em linguagens com herança múltipla)
&lt;/h1&gt;

&lt;p&gt;Em linguagens que permitem herdar de mais de uma classe (C++, Python), a explosão de herança pode gerar um problema extra: se &lt;code&gt;ClasseD&lt;/code&gt; herda de &lt;code&gt;ClasseB&lt;/code&gt; e &lt;code&gt;ClasseC&lt;/code&gt;, e ambas herdam de &lt;code&gt;ClasseA&lt;/code&gt;, qual versão de um método sobrescrito em &lt;code&gt;B&lt;/code&gt; e &lt;code&gt;C&lt;/code&gt; prevalece em &lt;code&gt;D&lt;/code&gt;? Isso é o &lt;strong&gt;diamond problem&lt;/strong&gt;, e é uma das razões pelas quais Java e C# nunca permitiram herança múltipla de classes — só de interfaces (que não carregam implementação, então o conflito não existe). Composição simplesmente não sofre disso: você nunca tem ambiguidade sobre "de qual pai herdei esse método", porque não há herança nenhuma envolvida.&lt;/p&gt;

&lt;h1&gt;
  
  
  Resumo
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&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;Relação modelada&lt;/td&gt;
&lt;td&gt;é-um&lt;/td&gt;
&lt;td&gt;tem-um&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Acoplamento&lt;/td&gt;
&lt;td&gt;forte (subclasse depende da estrutura interna da superclasse)&lt;/td&gt;
&lt;td&gt;fraco (depende só da interface do componente)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Variação em N dimensões&lt;/td&gt;
&lt;td&gt;multiplicativa (classes explodem)&lt;/td&gt;
&lt;td&gt;aditiva (soma componentes)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Troca de comportamento&lt;/td&gt;
&lt;td&gt;fixada em tempo de compilação&lt;/td&gt;
&lt;td&gt;pode mudar em tempo de execução (&lt;code&gt;setFlyBehavior&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Risco principal&lt;/td&gt;
&lt;td&gt;fragile base class problem&lt;/td&gt;
&lt;td&gt;mais indireção, mais peças para montar mentalmente&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Quando usar&lt;/td&gt;
&lt;td&gt;relação é-um genuína, hierarquia rasa e estável&lt;/td&gt;
&lt;td&gt;comportamento varia, ou varia em mais de uma dimensão&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>architecture</category>
      <category>learning</category>
      <category>software</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Hollywood Principle</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sat, 08 Aug 2026 16:03:52 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/hollywood-principle-57l0</link>
      <guid>https://dev.to/yuripeixinho/hollywood-principle-57l0</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;O Hollywood Principle é um princípio de design de software resumido na frase &lt;em&gt;"Don't call us, we'll call you"&lt;/em&gt; — não nos chame, nós chamaremos você. É a mesma frase clássica usada por produtores em Hollywood para dispensar atores em audições sem se comprometer a retornar contato.&lt;/p&gt;

&lt;p&gt;Em código tradicional, o seu programa controla o fluxo: ele chama bibliotecas, decide a ordem das operações e "puxa" o que precisa. No Hollywood Principle isso se inverte — um componente de nível mais alto (um framework, por exemplo) mantém o controle do fluxo, e é ele quem chama o seu código, no momento que julgar apropriado, e não o contrário.&lt;/p&gt;

&lt;p&gt;Por isso o princípio é praticamente sinônimo de &lt;strong&gt;Inversão de Controle (IoC)&lt;/strong&gt;: você não chama o framework, o framework chama você.&lt;/p&gt;

&lt;h2&gt;
  
  
  Biblioteca vs. framework
&lt;/h2&gt;

&lt;p&gt;Essa é a forma mais prática de sentir o princípio no dia a dia:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Biblioteca&lt;/strong&gt;: você importa, você chama os métodos, você está no comando. Ex.: usar &lt;code&gt;Math.Sqrt()&lt;/code&gt; ou uma lib de parsing de JSON.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Framework&lt;/strong&gt;: ele define a estrutura da aplicação, e o seu código só "encaixa" nos pontos que ele espera. Ex.: você escreve um método &lt;code&gt;OnClick()&lt;/code&gt; e o WinForms decide quando chamá-lo; você escreve uma classe &lt;code&gt;Controller&lt;/code&gt; no ASP.NET Core e o runtime decide quando instanciá-la e invocar seus métodos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Resumindo em uma frase: não chame o framework, o framework chama você.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exemplos em C
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Loop manual vs. evento
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Fluxo tradicional: você fica perguntando, você está no comando&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;evento&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filaDeEventos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;PegarProximo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// você decide quando pegar&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;evento&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Tipo&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;TipoEvento&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Clique&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;TratarClique&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;evento&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;                   &lt;span class="c1"&gt;// você chama sua própria função&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Hollywood principle: você registra e espera ser chamado&lt;/span&gt;
&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;TratarClique&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EventArgs&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"botão clicado!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;botao&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Click&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;TratarClique&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// "não me chame, eu te chamo"&lt;/span&gt;
&lt;span class="n"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;formulario&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// o framework entra em loop e chama&lt;/span&gt;
                                &lt;span class="c1"&gt;// TratarClique quando o clique acontecer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No primeiro caso, &lt;code&gt;TratarClique&lt;/code&gt; aparece no seu código sendo chamada por você. No segundo, ela nunca é chamada por você em lugar nenhum — só é passada como referência (um delegate). Quem decide quando ela roda é o &lt;code&gt;Application&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;code&gt;OrderBy&lt;/code&gt; com seletor: um mini-Hollywood dentro do LINQ
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;Prioridade&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pessoa&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Idade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pessoasOrdenadas&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pessoas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;OrderBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Prioridade&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você nunca escreve &lt;code&gt;Prioridade(pessoas[0])&lt;/code&gt;, &lt;code&gt;Prioridade(pessoas[1])&lt;/code&gt;... Quem chama &lt;code&gt;Prioridade&lt;/code&gt;, quantas vezes e em que ordem, é o algoritmo de ordenação dentro do &lt;code&gt;OrderBy&lt;/code&gt;. Isso já é o princípio agindo, mesmo dentro de um método LINQ comum.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. xUnit (framework de testes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculadoraTests&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Soma_DeveRetornarQuatro&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Subtracao_DeveRetornarDois&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você roda &lt;code&gt;dotnet test&lt;/code&gt; — nunca chama &lt;code&gt;Soma_DeveRetornarQuatro()&lt;/code&gt; você mesmo. É o xUnit que varre a classe por reflection, encontra métodos marcados com &lt;code&gt;[Fact]&lt;/code&gt; e os chama um por um, decidindo ordem, capturando falhas, etc.&lt;/p&gt;

&lt;p&gt;Compare com uma versão "biblioteca", onde você está no controle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;RodarTestes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;TestarSoma&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;TestarSubtracao&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tudo passou!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;RodarTestes&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;   &lt;span class="c1"&gt;// você chama, você decide a ordem&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Template Method: o princípio dentro de uma única classe
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Relatorio&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="nf"&gt;Gerar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;                    &lt;span class="c1"&gt;// o "molde" — fica no controle&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;dados&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;BuscarDados&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;           &lt;span class="c1"&gt;// chama método que a subclasse define&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Formatar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dados&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;BuscarDados&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;Formatar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;dados&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RelatorioVendas&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Relatorio&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;BuscarDados&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&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;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;150&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;Formatar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;dados&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;$"Total: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;dados&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Sum&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RelatorioVendas&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Gerar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;BuscarDados&lt;/code&gt; e &lt;code&gt;Formatar&lt;/code&gt; são definidos na subclasse, mas quem os chama é o método &lt;code&gt;Gerar&lt;/code&gt; lá na classe base. A subclasse nunca se auto-chama — ela só fornece as peças que a classe base vai encaixar quando quiser.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Socket cru vs. ASP.NET Core
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Baixo nível: você escreve o loop, você está no controle&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;servidor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;TcpListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPAddress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;servidor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;cliente&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;servidor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AcceptTcpClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;   &lt;span class="c1"&gt;// você chama AcceptTcpClient&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cliente&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetStream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;      &lt;span class="c1"&gt;// você chama Read&lt;/span&gt;
    &lt;span class="nf"&gt;TratarRequisicao&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;                   &lt;span class="c1"&gt;// você chama sua própria função&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Framework: ASP.NET Core está no controle&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WebApplication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&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="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MapGet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/ola"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"Olá, mundo!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A lambda passada a &lt;code&gt;MapGet&lt;/code&gt; nunca é chamada em nenhuma linha que você escreveu. O ASP.NET Core recebe a requisição HTTP e decide chamar esse handler quando a rota &lt;code&gt;/ola&lt;/code&gt; é acessada.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Injeção de dependência: o Hollywood Principle institucionalizado
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PedidoService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IPedidoRepository&lt;/span&gt; &lt;span class="n"&gt;_repositorio&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;PedidoService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPedidoRepository&lt;/span&gt; &lt;span class="n"&gt;repositorio&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;// você não faz "new PedidoRepository()"&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_repositorio&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repositorio&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                        &lt;span class="c1"&gt;// o container injeta a implementação&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddScoped&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IPedidoRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PedidoRepository&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você nunca escreve &lt;code&gt;new PedidoService(new PedidoRepository())&lt;/code&gt;. O container de DI do ASP.NET Core resolve as dependências e chama o construtor de &lt;code&gt;PedidoService&lt;/code&gt; por você, no momento em que a classe é necessária.&lt;/p&gt;

&lt;h2&gt;
  
  
  O padrão nos seis exemplos
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situação&lt;/th&gt;
&lt;th&gt;Quem chama quem&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;loop manual&lt;/td&gt;
&lt;td&gt;você chama &lt;code&gt;TratarClique&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;evento (&lt;code&gt;botao.Click += ...&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;o framework/runtime chama &lt;code&gt;TratarClique&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;OrderBy(lista)&lt;/code&gt; sem seletor&lt;/td&gt;
&lt;td&gt;não há callback&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OrderBy(lista, p =&amp;gt; p.Idade)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;OrderBy&lt;/code&gt; chama o seletor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;RodarTestes()&lt;/code&gt; manual&lt;/td&gt;
&lt;td&gt;você chama &lt;code&gt;TestarSoma&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;xUnit (&lt;code&gt;[Fact]&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;o test runner chama o método de teste&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;classe abstrata chamando método virtual&lt;/td&gt;
&lt;td&gt;a classe base chama, a subclasse implementa&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;TcpListener&lt;/code&gt; cru&lt;/td&gt;
&lt;td&gt;você chama &lt;code&gt;AcceptTcpClient&lt;/code&gt;/&lt;code&gt;Read&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ASP.NET Core (&lt;code&gt;MapGet&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;o framework chama o handler&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;container de DI&lt;/td&gt;
&lt;td&gt;o container chama o construtor&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Repare que isso aparece muito mais em &lt;strong&gt;OOP&lt;/strong&gt; (polimorfismo, herança, interfaces) do que em programação estruturada pura — é por isso que frameworks orientados a objetos (ASP.NET Core, Spring, Angular, React) são o habitat natural do Hollywood Principle: eles dependem de você implementar um "contrato" (uma interface, uma classe abstrata, um delegate com assinatura esperada) para poderem chamá-lo de volta.&lt;/p&gt;

&lt;h2&gt;
  
  
  Relação com SOLID
&lt;/h2&gt;

&lt;p&gt;O Hollywood Principle é primo próximo do &lt;strong&gt;Dependency Inversion Principle&lt;/strong&gt; (o "D" do SOLID): módulos de alto nível não devem depender de módulos de baixo nível — ambos devem depender de abstrações. A ideia de "inverter" quem depende de quem é a mesma raiz conceitual por trás dos dois.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vantagens e custos
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Vantagem&lt;/strong&gt;: baixo acoplamento — seu código não precisa saber os detalhes de quando ou como é chamado, só precisa implementar o contrato esperado (uma interface, um delegate, um método abstrato).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Custo&lt;/strong&gt;: o fluxo de controle fica menos explícito. Ao ler o código isoladamente, não é óbvio &lt;em&gt;quando&lt;/em&gt; uma função vai ser executada — isso pode dificultar o debugging, já que você precisa entender o framework para saber a ordem das chamadas. Esse "fluxo invertido" costuma ser citado como uma das razões pelas quais frameworks têm curva de aprendizado maior que bibliotecas.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>programming</category>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Paradigma de Programação Orientada a Objetos (POO)</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sat, 08 Aug 2026 15:04:58 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/paradigma-de-programacao-orientada-a-objetos-poo-4cjh</link>
      <guid>https://dev.to/yuripeixinho/paradigma-de-programacao-orientada-a-objetos-poo-4cjh</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;A Programação Orientada a Objetos nasceu com a linguagem &lt;strong&gt;Simula 67&lt;/strong&gt;, considerada a primeira linguagem orientada a objetos, e foi consolidada e popularizada por &lt;strong&gt;Smalltalk&lt;/strong&gt; nos anos 1970. Ganhou adoção massiva na indústria com C++ e, posteriormente, Java e C#. A ideia central é organizar o código em torno de &lt;strong&gt;objetos&lt;/strong&gt;: unidades que combinam &lt;strong&gt;dados (atributos/estado)&lt;/strong&gt; e &lt;strong&gt;comportamento (métodos)&lt;/strong&gt; em uma única estrutura.&lt;/p&gt;

&lt;h3&gt;
  
  
  Os quatro pilares
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Encapsulamento&lt;/strong&gt; — os dados internos de um objeto são protegidos e só podem ser acessados/alterados através de métodos expostos, escondendo detalhes de implementação do mundo externo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Abstração&lt;/strong&gt; — o objeto expõe apenas o que é relevante para quem o utiliza, escondendo a complexidade interna (ex.: você chama &lt;code&gt;CalcularSalario()&lt;/code&gt; sem precisar saber como o cálculo é feito por dentro).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Herança&lt;/strong&gt; — uma classe pode herdar atributos e métodos de outra, permitindo reaproveitamento e especialização (uma classe &lt;code&gt;Desenvolvedor&lt;/code&gt; pode herdar de &lt;code&gt;Funcionario&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Polimorfismo&lt;/strong&gt; — objetos de classes diferentes podem responder de forma diferente ao mesmo "chamado" (o mesmo método &lt;code&gt;CalcularSalario()&lt;/code&gt; se comporta de forma distinta para um &lt;code&gt;Desenvolvedor&lt;/code&gt; e para um &lt;code&gt;Gerente&lt;/code&gt;, por exemplo).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Exemplo
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Exemplo de Programação Orientada a Objetos em C#&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Funcionario&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;SalarioBase&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nf"&gt;Funcionario&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;salarioBase&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;SalarioBase&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;salarioBase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Abstração: cada subclasse decide como calcular seu próprio salário&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;CalcularSalario&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Desenvolvedor&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Funcionario&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;BonusPorProjeto&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&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="nf"&gt;Desenvolvedor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;salarioBase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;bonusPorProjeto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;salarioBase&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Herança&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;BonusPorProjeto&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bonusPorProjeto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Polimorfismo: implementação específica do método herdado&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;CalcularSalario&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;SalarioBase&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;BonusPorProjeto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Gerente&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Funcionario&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;decimal&lt;/span&gt; &lt;span class="n"&gt;BonusPorEquipe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&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="nf"&gt;Gerente&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;salarioBase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;bonusPorEquipe&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;salarioBase&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;BonusPorEquipe&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bonusPorEquipe&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;override&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;CalcularSalario&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;SalarioBase&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;BonusPorEquipe&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, &lt;code&gt;SalarioBase&lt;/code&gt; é protegido (encapsulamento), &lt;code&gt;Desenvolvedor&lt;/code&gt; e &lt;code&gt;Gerente&lt;/code&gt; reaproveitam a estrutura de &lt;code&gt;Funcionario&lt;/code&gt; (herança), e cada um implementa &lt;code&gt;CalcularSalario()&lt;/code&gt; à sua maneira (polimorfismo) — tudo isso sem que o código que consome &lt;code&gt;Funcionario&lt;/code&gt; precise saber qual subtipo específico está manipulando.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vantagens e limitações
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vantagens:&lt;/strong&gt; modela bem domínios do mundo real com entidades ricas e relacionamentos complexos; favorece reuso e organização em sistemas grandes; se encaixa naturalmente em arquiteturas como Clean Architecture e DDD (Domain-Driven Design).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limitações:&lt;/strong&gt; hierarquias de herança profundas podem se tornar rígidas e difíceis de alterar; o estado mutável encapsulado em objetos ainda pode gerar efeitos colaterais difíceis de rastrear se mal gerenciado.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Linguagens representativas:&lt;/strong&gt; Java, C#, Python, C++, TypeScript (com classes).&lt;/p&gt;

</description>
      <category>computerscience</category>
      <category>programming</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Programação Funcional</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sat, 08 Aug 2026 15:03:54 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/programacao-funcional-594</link>
      <guid>https://dev.to/yuripeixinho/programacao-funcional-594</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;A Programação Funcional tem raízes no &lt;strong&gt;cálculo lambda&lt;/strong&gt;, formalizado pelo matemático Alonzo Church nos anos 1930, décadas antes da existência de computadores modernos. Sua primeira grande expressão em linguagem de programação foi o &lt;strong&gt;Lisp&lt;/strong&gt; (1958), e o paradigma ganhou força prática com linguagens como Haskell, Erlang, F# e, mais recentemente, com a incorporação de recursos funcionais em linguagens multiparadigma como JavaScript, C# e Python.&lt;/p&gt;

&lt;h3&gt;
  
  
  Princípios centrais
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Funções puras&lt;/strong&gt; — dado o mesmo input, uma função pura sempre retorna o mesmo output, sem produzir efeitos colaterais (não altera variáveis externas, não grava em disco, não modifica o argumento recebido).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Imutabilidade&lt;/strong&gt; — os dados não são alterados após criados; em vez de modificar uma estrutura existente, cria-se uma nova versão com a alteração aplicada.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Funções de primeira classe / funções de alta ordem&lt;/strong&gt; — funções podem ser tratadas como qualquer outro valor: armazenadas em variáveis, passadas como argumento e retornadas por outras funções.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Composição de funções&lt;/strong&gt; — programas são construídos combinando funções pequenas em pipelines (&lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, &lt;code&gt;reduce&lt;/code&gt; são os exemplos mais comuns no dia a dia).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recursão&lt;/strong&gt; no lugar de laços mutáveis, já que, sem estado mutável, &lt;code&gt;for&lt;/code&gt;/&lt;code&gt;while&lt;/code&gt; tradicionais perdem o sentido em sua forma pura.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Como não há estado compartilhado sendo alterado por múltiplas partes do código, o raciocínio sobre o comportamento do programa fica mais previsível — e a paralelização se torna muito mais segura, já que não existe o risco clássico de condições de corrida sobre uma mesma variável mutável.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exemplo
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Exemplo de Programação Funcional em TypeScript&lt;/span&gt;
&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Produto&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;nome&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="n"&gt;preco&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;produtos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Produto&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="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Notebook"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;preco&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3000&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Mouse"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;preco&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;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Teclado"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;preco&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;150&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// Função de alta ordem que retorna outra função (currying)&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;aplicarDesconto&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;percentual&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;preco&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="n"&gt;preco&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;percentual&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;aplicarDesconto10&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;aplicarDesconto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Composição via map + reduce, sem alterar "produtos"&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;totalComDesconto&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;produtos&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="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;aplicarDesconto10&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;preco&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;acumulado&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;precoAtual&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;acumulado&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;precoAtual&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="n"&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="n"&gt;totalComDesconto&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// produtos original permanece intacto&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Repare que &lt;code&gt;produtos&lt;/code&gt; nunca é modificado — &lt;code&gt;map&lt;/code&gt; gera um novo array, e &lt;code&gt;reduce&lt;/code&gt; agrega esse novo array em um único valor. Essa é a essência da imutabilidade e da ausência de efeitos colaterais.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vantagens e limitações
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vantagens:&lt;/strong&gt; previsibilidade, testabilidade (funções puras são triviais de testar — mesmo input, mesmo output, sem mocks de estado), facilidade de paralelização/concorrência.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limitações:&lt;/strong&gt; pode ter uma curva de aprendizado mais alta para quem vem de um background imperativo; nem todo domínio de problema se encaixa naturalmente em transformações de dados (por exemplo, interações com I/O e efeitos colaterais são inevitáveis em algum ponto — a maioria das linguagens funcionais lida com isso através de abstrações específicas, como Monads em Haskell).&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>computerscience</category>
      <category>programming</category>
      <category>software</category>
    </item>
    <item>
      <title>Programação Estruturada</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sat, 08 Aug 2026 15:03:07 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/programacao-estruturada-3ma3</link>
      <guid>https://dev.to/yuripeixinho/programacao-estruturada-3ma3</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;A Programação Estruturada surgiu no final dos anos 1960 e início dos anos 1970 como uma reação direta ao chamado "código espaguete" — programas repletos de saltos incondicionais (&lt;code&gt;GOTO&lt;/code&gt;) que tornavam o fluxo de execução quase impossível de seguir. O marco histórico é o artigo de Edsger Dijkstra, &lt;em&gt;"Go To Statement Considered Harmful"&lt;/em&gt; (1968), que propôs abandonar o &lt;code&gt;GOTO&lt;/code&gt; em favor de estruturas de controle previsíveis.&lt;/p&gt;

&lt;h3&gt;
  
  
  Princípios centrais
&lt;/h3&gt;

&lt;p&gt;O paradigma se apoia no &lt;strong&gt;Teorema da Programação Estruturada&lt;/strong&gt;, segundo o qual qualquer algoritmo pode ser expresso combinando apenas três estruturas de controle:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sequência&lt;/strong&gt; — instruções executadas uma após a outra, na ordem em que aparecem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Seleção&lt;/strong&gt; — desvios condicionais (&lt;code&gt;if/else&lt;/code&gt;, &lt;code&gt;switch&lt;/code&gt;), que escolhem um caminho entre alternativas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repetição&lt;/strong&gt; — laços (&lt;code&gt;for&lt;/code&gt;, &lt;code&gt;while&lt;/code&gt;, &lt;code&gt;do-while&lt;/code&gt;) que repetem um bloco enquanto uma condição for satisfeita.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Além disso, o paradigma incentiva a &lt;strong&gt;modularização&lt;/strong&gt;: dividir o programa em procedimentos e funções menores, cada um com uma responsabilidade clara, e o &lt;strong&gt;design top-down&lt;/strong&gt;, em que o problema é refinado de uma visão geral para os detalhes de implementação.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exemplo
&lt;/h3&gt;

&lt;p&gt;csharp&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Exemplo de Programação Estruturada em C#&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;CalcularTotalComDesconto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;valorUnitario&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;quantidade&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;desconto&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="c1"&gt;// Seleção&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quantidade&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;desconto&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0.20m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quantidade&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;desconto&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0.10m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;valorUnitario&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;quantidade&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;desconto&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Repetição&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;quantidade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Processando item&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; de&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;quantidade&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Sequência&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note que todo o fluxo é linear e previsível: entra-se no topo da função, cada linha executa em ordem, e as únicas variações de caminho vêm de &lt;code&gt;if&lt;/code&gt; e &lt;code&gt;for&lt;/code&gt; — nunca de um salto arbitrário.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vantagens e limitações
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vantagens:&lt;/strong&gt; legibilidade, facilidade de depuração, raciocínio linear, base sólida para qualquer outro paradigma (structured programming é praticamente universal — até código funcional e orientado a objetos usa sequência/seleção/repetição &lt;em&gt;dentro&lt;/em&gt; de funções e métodos).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limitações:&lt;/strong&gt; conforme o sistema cresce, o compartilhamento de estado mutável entre muitas funções torna a manutenção difícil — problema que os paradigmas seguintes tentam resolver de formas diferentes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Linguagens representativas:&lt;/strong&gt; C, Pascal, Fortran (versões modernas), e qualquer linguagem no nível de suas funções/procedimentos.&lt;/p&gt;

</description>
      <category>computerscience</category>
      <category>learning</category>
      <category>programming</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Paradigmas de Programação</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sat, 08 Aug 2026 15:02:55 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/paradigmas-de-programacao-46fk</link>
      <guid>https://dev.to/yuripeixinho/paradigmas-de-programacao-46fk</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Um &lt;strong&gt;paradigma de programação&lt;/strong&gt; é uma forma de pensar e organizar a solução de um problema em código — um conjunto de princípios, conceitos e regras que orientam &lt;em&gt;como&lt;/em&gt; o programador estrutura a lógica do software. Não se trata de uma linguagem específica, mas de uma &lt;strong&gt;filosofia de construção&lt;/strong&gt;: a mesma linguagem pode suportar vários paradigmas, e o mesmo paradigma pode ser expresso em linguagens diferentes.&lt;/p&gt;

&lt;p&gt;Uma boa analogia: pense em como se pode escrever um texto. Você pode narrar uma história cronologicamente, argumentar uma tese ponto a ponto, ou descrever uma cena através de impressões sensoriais. As palavras (a "linguagem") são as mesmas, mas a &lt;em&gt;estrutura de raciocínio&lt;/em&gt; muda completamente. Paradigmas de programação funcionam da mesma forma: mudam a maneira como você decompõe um problema, organiza o estado dos dados e estrutura o fluxo de execução.&lt;/p&gt;

&lt;h1&gt;
  
  
  Visão geral: as duas grandes famílias
&lt;/h1&gt;

&lt;p&gt;Historicamente, os paradigmas costumam ser agrupados em duas grandes famílias:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Imperativo&lt;/strong&gt; — o código descreve &lt;em&gt;como&lt;/em&gt; fazer, passo a passo, através de comandos que alteram o estado do programa (variáveis, memória). A Programação Estruturada e a Programação Orientada a Objetos derivam dessa família.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Declarativo&lt;/strong&gt; — o código descreve &lt;em&gt;o quê&lt;/em&gt; se quer obter, delegando o "como" para o mecanismo de execução da linguagem. A Programação Funcional é o principal representante dessa família (junto com a lógica, como Prolog, e consultas declarativas, como SQL).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Multiparadigma na Prática
&lt;/h2&gt;

&lt;p&gt;Vale destacar que a maioria das linguagens modernas &lt;strong&gt;não obriga a escolha de um único paradigma&lt;/strong&gt; — elas são multiparadigma. C# é um exemplo claro: seu núcleo é orientado a objetos, mas incorpora fortemente recursos funcionais através de LINQ, expressões lambda e métodos de extensão que trabalham sobre coleções imutáveis. O mesmo vale para TypeScript/JavaScript: componentes React modernos, por exemplo, tendem a favorecer funções puras e imutabilidade (hooks, &lt;code&gt;useState&lt;/code&gt; com atualizações imutáveis) mesmo dentro de um ecossistema historicamente mais orientado a objetos.&lt;/p&gt;

&lt;p&gt;Na prática profissional, é comum combinar os três paradigmas dentro do mesmo sistema: a estrutura geral e a modelagem de domínio seguem princípios de POO (classes, entidades, agregados), a lógica interna de cada método segue os fundamentos da programação estruturada (sequência/seleção/repetição), e transformações de dados — filtros, mapeamentos, agregações — são resolvidas de forma mais elegante e testável com um estilo funcional.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparando os Três Paradigmas
&lt;/h2&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;Estruturada&lt;/th&gt;
&lt;th&gt;Funcional&lt;/th&gt;
&lt;th&gt;Orientada a Objetos&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Unidade de organização&lt;/td&gt;
&lt;td&gt;Procedimentos/funções&lt;/td&gt;
&lt;td&gt;Funções puras&lt;/td&gt;
&lt;td&gt;Objetos e classes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tratamento de estado&lt;/td&gt;
&lt;td&gt;Mutável e compartilhado&lt;/td&gt;
&lt;td&gt;Imutável, isolado&lt;/td&gt;
&lt;td&gt;Encapsulado dentro do objeto&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fluxo de controle&lt;/td&gt;
&lt;td&gt;Sequência, seleção, repetição&lt;/td&gt;
&lt;td&gt;Composição e recursão&lt;/td&gt;
&lt;td&gt;Troca de mensagens entre objetos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mecanismo de reuso&lt;/td&gt;
&lt;td&gt;Chamada de funções&lt;/td&gt;
&lt;td&gt;Composição de funções&lt;/td&gt;
&lt;td&gt;Herança e composição de objetos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Facilidade de paralelismo&lt;/td&gt;
&lt;td&gt;Baixa (estado mutável)&lt;/td&gt;
&lt;td&gt;Alta (sem efeitos colaterais)&lt;/td&gt;
&lt;td&gt;Moderada&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Melhor encaixe&lt;/td&gt;
&lt;td&gt;Algoritmos lineares, scripts, lógica de baixo nível&lt;/td&gt;
&lt;td&gt;Processamento/transformação de dados, sistemas concorrentes&lt;/td&gt;
&lt;td&gt;Sistemas com domínios ricos e regras de negócio complexas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linguagens típicas&lt;/td&gt;
&lt;td&gt;C, Pascal&lt;/td&gt;
&lt;td&gt;Haskell, Elixir, Clojure&lt;/td&gt;
&lt;td&gt;Java, C#, Python&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;
  
  
  Além dos Três: Outros Paradigmas
&lt;/h1&gt;

&lt;p&gt;Embora o diagrama apresentado foque nesses três pilares fundamentais, a árvore de paradigmas de programação é mais ampla. Vale citar rapidamente outras ramificações para contexto:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Programação Lógica&lt;/strong&gt; (ex.: Prolog) — o programa é um conjunto de fatos e regras, e a execução consiste em provar consultas contra essa base de conhecimento.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Programação Orientada a Eventos&lt;/strong&gt; — o fluxo é determinado por eventos externos (cliques, mensagens, requisições) que disparam handlers, muito comum em interfaces gráficas e sistemas reativos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Programação Declarativa&lt;/strong&gt; (em sentido amplo) — engloba a funcional e a lógica, mas também se manifesta em linguagens de consulta como SQL, onde se descreve o resultado desejado, não o algoritmo para obtê-lo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Não existe um paradigma "melhor" de forma absoluta — existe o paradigma mais adequado para um problema específico, uma equipe específica e um contexto específico. A Programação Estruturada oferece a base de raciocínio linear que sustenta praticamente todo código, independentemente do paradigma "principal" escolhido. A Programação Funcional brilha em cenários de transformação de dados e concorrência, onde a previsibilidade e a ausência de efeitos colaterais reduzem bugs sutis. A Programação Orientada a Objetos se destaca na modelagem de domínios de negócio complexos, organizando entidades, comportamentos e relacionamentos de forma que espelha o mundo real.&lt;/p&gt;

&lt;p&gt;Dominar múltiplos paradigmas — e, mais importante, saber reconhecer qual estilo de raciocínio se encaixa melhor em cada parte de um sistema — é o que diferencia um desenvolvedor que apenas escreve código funcional (no sentido de "que funciona") de um desenvolvedor que projeta software sustentável, testável e fácil de evoluir.&lt;/p&gt;

</description>
      <category>computerscience</category>
      <category>learning</category>
      <category>programming</category>
    </item>
    <item>
      <title>Cluster 4: #10 testes rápidos e independentes, #13 simplicidade e refatoração contínua</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sat, 01 Aug 2026 21:50:16 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/cluster-4-10-testes-rapidos-e-independentes-13-simplicidade-e-refatoracao-continua-2ka6</link>
      <guid>https://dev.to/yuripeixinho/cluster-4-10-testes-rapidos-e-independentes-13-simplicidade-e-refatoracao-continua-2ka6</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Esse&amp;nbsp;cluster&amp;nbsp;é&amp;nbsp;diferente&amp;nbsp;dos&amp;nbsp;outros&amp;nbsp;três:&amp;nbsp;ele&amp;nbsp;não&amp;nbsp;previne&amp;nbsp;um&amp;nbsp;tipo&amp;nbsp;de&amp;nbsp;bug,&amp;nbsp;ele&amp;nbsp;&lt;strong&gt;sustenta&amp;nbsp;a&amp;nbsp;capacidade&amp;nbsp;de&amp;nbsp;manter&amp;nbsp;os&amp;nbsp;outros&amp;nbsp;nove&amp;nbsp;princípios&amp;nbsp;ao&amp;nbsp;longo&amp;nbsp;do&amp;nbsp;tempo&lt;/strong&gt;.&amp;nbsp;A&amp;nbsp;segunda&amp;nbsp;lei&amp;nbsp;de&amp;nbsp;Lehman,&amp;nbsp;a&amp;nbsp;&lt;strong&gt;Lei&amp;nbsp;da&amp;nbsp;Complexidade&amp;nbsp;Crescente&lt;/strong&gt;,&amp;nbsp;diz&amp;nbsp;que&amp;nbsp;a&amp;nbsp;complexidade&amp;nbsp;de&amp;nbsp;um&amp;nbsp;sistema&amp;nbsp;aumenta&amp;nbsp;por&amp;nbsp;padrão&amp;nbsp;a&amp;nbsp;menos&amp;nbsp;que&amp;nbsp;alguém&amp;nbsp;trabalhe&amp;nbsp;ativamente&amp;nbsp;para&amp;nbsp;reduzir-la. Refatoração não é uma tarefa opcional de “polimento”, é a única força que contrabalança uma tendência que existe independente da sua vontade. Mas refatorar só é seguro se você consegue confirmar rapidamente que nada quebrou — e é aí que testes lentos ou dependentes de ordem matam a disciplina inteira: se rodar a suíte demora 20 minutos ou falha de forma inconsistente, o time para de rodar, para de confiar, e para de refatorar, e a lei da complexidade crescente passa a valer sem oposição. Esse não é um risco teórico: o relatório The Developer Coefficient (Stripe, 2018), baseado em pesquisa com centenas de desenvolvedores e executivos de engenharia, estimou que uma fração substancial da semana de trabalho — na casa de um terço a 40% — é perdida lidando com dívida técnica e código malfeito, com impacto econômico global estimado em centenas de bilhões de dólares por ano. Esse número é, em essência, o preço agregado de organizações que pararam de fazer #10 e #13 e deixaram a lei de Lehman correr sem freio.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;#10 Testes Rápidos e Independentes&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;A base conceitual mais direta aqui é o acrônimo &lt;strong&gt;FIRST&lt;/strong&gt;, documentado por Robert C. Martin em &lt;em&gt;Clean Code&lt;/em&gt; (2008) e creditado a Tim Ottinger e Jeff Langr: um teste de unidade deveria ser &lt;strong&gt;F&lt;/strong&gt;ast (rápido), &lt;strong&gt;I&lt;/strong&gt;ndependent (independente de outros testes), &lt;strong&gt;R&lt;/strong&gt;epeatable (repetível em qualquer ambiente), &lt;strong&gt;S&lt;/strong&gt;elf-Validating (retorna verdadeiro/falso, sem exigir inspeção manual de log) e &lt;strong&gt;T&lt;/strong&gt;imely (escrito no momento certo, perto do código que testa). O título desse princípio no artigo pega exatamente as duas primeiras letras — porque são, na prática, as duas que mais diretamente disparam a espiral de morte descrita na introdução: um teste lento drena paciência a cada execução; um teste dependente de ordem drena confiança a cada falha que não devia ter acontecido.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Exemplo — teste lento e acoplado vs. teste rápido e isolado:&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Lento e acoplado — bate no banco de dados real a cada execução&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RetificacaoServiceTests&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;DeveRetificarMovimento_QuandoValorDivergente&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FiscalDbContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_connectionStringReal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// conexão real com SQL Server&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RetificacaoService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Retificar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;movimentoId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;123&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;True&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultado&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sucesso&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Cada execução: abre conexão de rede real, e depende de que a linha 123&lt;/span&gt;
        &lt;span class="c1"&gt;// já exista no banco com o estado "certo" — herdado de uma execução anterior&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Rápido e isolado — dependência trocada por um fake em memória&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RetificacaoServiceTests&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;DeveRetificarMovimento_QuandoValorDivergente&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;repositorioFake&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RepositorioMovimentoFake&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Movimento&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;500m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;StatusMovimento&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pendente&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RetificacaoService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repositorioFake&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Retificar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;movimentoId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;123&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;True&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultado&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sucesso&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Roda em memória, sem I/O — milissegundos. O estado de entrada é 100%&lt;/span&gt;
        &lt;span class="c1"&gt;// definido dentro do próprio teste, não herdado de nada externo&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Exemplo — teste dependente de ordem vs. independente:&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Frágil — os dois testes compartilham uma lista estática entre execuções&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NumeracaoNotaFiscalTests&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_numerosGerados&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PrimeiroNumero_DeveSerUm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;numero&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GerarProximoNumero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_numerosGerados&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numero&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;_numerosGerados&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numero&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SegundoNumero_DeveSerDois&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;numero&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GerarProximoNumero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_numerosGerados&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numero&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Só passa se PrimeiroNumero_DeveSerUm já rodou antes, e nessa ordem.&lt;/span&gt;
        &lt;span class="c1"&gt;// Rodar sozinho, em paralelo, ou com a suíte embaralhada: falha.&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Independente — cada teste monta seu próprio estado, do zero&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NumeracaoNotaFiscalTests&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PrimeiroNumero_DeveSerUm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;numero&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GerarProximoNumero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;());&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numero&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SegundoNumero_DeveSerDois&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;numero&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GerarProximoNumero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="c1"&gt;// pré-condição explícita, não herdada&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numero&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;O segundo exemplo é o padrão mais comum de "flakiness" na prática: dois testes que passam perfeitamente na ordem em que foram escritos, e falham de forma aparentemente aleatória assim que uma pipeline de CI paraliza a execução, ou quando algum framework de teste decide randomizar a ordem deliberadamente — justamente pra expor esse tipo de acoplamento escondido antes que ele vire um problema em produção.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;#13 Simplicidade e Refatoração Contínua&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A base conceitual mais direta vem de Kent Beck, em &lt;em&gt;Extreme Programming Explained&lt;/em&gt; (1999): as &lt;strong&gt;Quatro Regras do Design Simples&lt;/strong&gt;, nessa ordem de prioridade — (1) passa em todos os testes, (2) revela a intenção, (3) sem duplicação, (4) menor número de elementos possível. A ordem importa: só faz sentido buscar "menos elementos" depois de garantir que a intenção está clara e que não há duplicação — simplicidade não é sinônimo de "menos código a qualquer custo", é a ausência de tudo que não precisa estar ali.&lt;/p&gt;

&lt;p&gt;A ligação com dívida técnica, que a introdução já traz pelo relatório da Stripe, vem de Ward Cunningham, num relato de experiência na OOPSLA de 1992: código que corta caminho pra entregar mais rápido hoje é, literalmente, um empréstimo — você recebe velocidade agora e paga juros (retrabalho, fricção, tempo de entendimento) em cada mudança futura, até que alguém pague o principal de volta via refatoração. Cunningham não estava fazendo uma crítica moral ao atalho — dívida técnica pode ser escolha racional e deliberada —, o ponto dele é que ela tem que ser paga de algum jeito, consciente ou não.&lt;/p&gt;

&lt;p&gt;A técnica pra pagar essa dívida com segurança é formalizada por Martin Fowler em &lt;em&gt;Refactoring: Improving the Design of Existing Code&lt;/em&gt; (1999): uma sequência de pequenas transformações, cada uma preservando o comportamento observável do sistema, verificada por testes a cada passo — nunca uma reescrita de uma vez só. Robert C. Martin resume o hábito do dia a dia nisso com a &lt;strong&gt;Regra do Escoteiro&lt;/strong&gt;: deixe o código um pouco mais limpo do que você encontrou, toda vez que mexer nele — não precisa de um projeto formal de refatoração, é disciplina contínua aplicada a cada Pull Request.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Exemplo — duplicação que se acumula em silêncio:&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Complexo — a mesma validação de CPF/CNPJ duplicada em dois lugares do sistema&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ValidadorNotaFiscal&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;Validar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NotaFiscal&lt;/span&gt; &lt;span class="n"&gt;nota&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nota&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Cliente&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Documento&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;11&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ~20 linhas de validação de CPF */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ~25 linhas de validação de CNPJ */&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;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ValidadorTransmissao&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;PodeTransmitir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ArquivoEFinanceira&lt;/span&gt; &lt;span class="n"&gt;arquivo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arquivo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Titular&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Documento&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;11&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* a mesma validação de CPF, copiada e colada */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;// quem corrigir um bug aqui precisa lembrar de corrigir no outro lugar também&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Simples — a regra vive em um único lugar; os dois validadores delegam&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ValidadorDocumento&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;static&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;EhValido&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;documento&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;limpo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;Limpar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;documento&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;limpo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt; &lt;span class="k"&gt;switch&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="m"&gt;11&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;ValidarCpf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;limpo&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="m"&gt;14&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;ValidarCnpj&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;limpo&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;false&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="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;Limpar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ValidadorNotaFiscal&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;Validar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NotaFiscal&lt;/span&gt; &lt;span class="n"&gt;nota&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ValidadorDocumento&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EhValido&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nota&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Cliente&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Documento&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa é a Regra 3 de Beck (sem duplicação) na prática. O perigo da versão duplicada não é só o volume de código — é que um bug corrigido num lugar continua vivo no outro, esperando quieto até alguém notar a divergência, geralmente meses depois, geralmente em produção.&lt;/p&gt;

</description>
      <category>refactoring</category>
      <category>softwareengineering</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
