<?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>Processo de Teste</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sun, 04 Oct 2026 22:38:02 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/processo-de-teste-3dci</link>
      <guid>https://dev.to/yuripeixinho/processo-de-teste-3dci</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;O ISTQB não prescreve um processo único. Descreve atividades comuns, sem as quais o teste tem menos chance de atingir seus objetivos, e deixa a adaptação para o contexto. Os fatores que mais pesam:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;modelos de ciclo de vida e metodologia do projeto;&lt;/li&gt;
&lt;li&gt;níveis e tipos de testes considerado;&lt;/li&gt;
&lt;li&gt;riscos de produto e de projeto;&lt;/li&gt;
&lt;li&gt;domínio de negócio;&lt;/li&gt;
&lt;li&gt;restrições operacionais: orçamento e recursos, prazos, complexidade, requisitos constrautias e regulatórios;&lt;/li&gt;
&lt;li&gt;políticas e práticas da organização;&lt;/li&gt;
&lt;li&gt;padrões internos e externos exigidos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As atividades podem rodar em sequência ou de forma iterativa. Em qualquer projeto, podem se sobrepor, ser combinadas, rodar em paralelo ou ser omitidas. Em ágil, o teste acontece de forma contínua, dentro de cada iteração. O que fica estável é a pergunta que cada atividade responde.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;O exemplo que atravessa o texto&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Cenário hipotético.&lt;/em&gt;&amp;nbsp;Um ERP financeiro SaaS vai gerar remessa CNAB 240 de pagamento a fornecedores para um segundo banco (Banco B). Seis semanas, três sprints, dois devs e dois testers. O banco exige homologação do arquivo e seu sandbox cobre só parte dos cenários. Risco central: arquivo rejeitado ou aceito em duplicidade.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;As sete atividades&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Atividade&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Pergunta&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Papel&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Saída principal&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Planejamento&lt;/td&gt;
&lt;td&gt;Quais objetivos e qual abordagem, dentro das restrições?&lt;/td&gt;
&lt;td&gt;Gestão&lt;/td&gt;
&lt;td&gt;Plano de teste&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monitoramento e controle&lt;/td&gt;
&lt;td&gt;Estamos no plano? O que corrigir?&lt;/td&gt;
&lt;td&gt;Gestão&lt;/td&gt;
&lt;td&gt;Relatórios de progresso&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Análise&lt;/td&gt;
&lt;td&gt;O que testar?&lt;/td&gt;
&lt;td&gt;Teste&lt;/td&gt;
&lt;td&gt;Condições de teste priorizadas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modelagem&lt;/td&gt;
&lt;td&gt;Como testar?&lt;/td&gt;
&lt;td&gt;Teste&lt;/td&gt;
&lt;td&gt;Casos de teste, requisitos de dados e de ambiente&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Implementação&lt;/td&gt;
&lt;td&gt;Está tudo pronto para rodar?&lt;/td&gt;
&lt;td&gt;Teste&lt;/td&gt;
&lt;td&gt;Procedimentos, suítes, cronograma, ambiente, dados&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Execução&lt;/td&gt;
&lt;td&gt;O resultado real bate com o esperado?&lt;/td&gt;
&lt;td&gt;Teste&lt;/td&gt;
&lt;td&gt;Status por teste, relatórios de defeitos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Conclusão&lt;/td&gt;
&lt;td&gt;O que entregamos e aprendemos?&lt;/td&gt;
&lt;td&gt;Gestão&lt;/td&gt;
&lt;td&gt;Relatório de resumo, lições, testware arquivado&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Os produtos de trabalho de todas as atividades formam o&amp;nbsp;&lt;em&gt;testware&lt;/em&gt;. Planejamento e monitoramento e controle atravessam o projeto inteiro: o plano é revisto a partir do que o monitoramento mostra.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Planejamento: quais objetivos, e qual abordagem?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Define os objetivos do teste e escolhe a abordagem que os atinge dentro das restrições e do contexto. A saída é o plano de teste. No mínimo ele aponta a base de teste (o material de onde os testes são derivados: requisitos, histórias, layouts, código) e os critérios de saída, também chamados de definição de feito. Um plano completo traz ainda escopo, premissas, partes interessadas, comunicação, riscos, abordagem, orçamento e cronograma.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No exemplo:&lt;/strong&gt;&amp;nbsp;objetivos: arquivo aceito pelo banco, zero duplicidade, sem regressão na remessa do Banco A. Abordagem baseada em risco. Critérios de saída: 100% das condições de risco alto executadas, nenhum defeito crítico ou alto aberto, homologação aprovada.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Monitoramento e controle: estamos no plano?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Compara o progresso real com o plano, usando as métricas definidas nele, e toma as ações necessárias para atingir os objetivos. Também avalia os critérios de saída: verifica a cobertura, avalia o nível de qualidade e decide se são necessários mais testes. Produz relatórios de progresso, contínuos, e relatórios de resumo, nos marcos. Relatório bom traz o que o público precisa para decidir.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No exemplo:&lt;/strong&gt;&amp;nbsp;na semana 4, 55% dos casos executados contra 70% previstos, e 62% das condições de risco alto contra 80%. Causa: sandbox fora do ar por dois dias. Ações de controle: priorizar a suíte de risco alto, alocar mais um tester por três dias e pedir ao banco uma janela dedicada.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Análise: o que testar?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Analisa a base de teste para definir e priorizar condições de teste, identificar as funcionalidades a cobrir e avaliar a testabilidade. A análise também procura defeitos na própria base: ambiguidades, omissões, inconsistências, imprecisões, contradições e afirmações supérfluas. Saídas: condições de teste priorizadas, ligadas por rastreabilidade aos elementos da base, e relatórios de defeitos da base.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No exemplo:&lt;/strong&gt;&amp;nbsp;a história US-09 ("título já enviado não reenvia") gera as condições CT-03 e CT-04. Na mesma análise aparece um defeito: o texto do layout do banco manda data em DDMMAAAA, e o exemplo do PDF usa AAAAMMDD. O defeito vai para o banco antes de existir uma linha de código.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Modelagem: como testar?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Transforma condições em casos de teste, priorizados, com apoio de técnicas como partição de equivalência, análise de valor-limite e tabela de decisão. Define os dados necessários, projeta o ambiente e identifica infraestrutura e ferramentas. O ambiente é&amp;nbsp;&lt;em&gt;projetado&lt;/em&gt;&amp;nbsp;aqui; quem o constrói é a implementação. Casos de alto nível, sem valores concretos, são reutilizáveis entre ciclos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No exemplo:&lt;/strong&gt;&amp;nbsp;o campo valor tem 13 posições inteiras e 2 decimais. Valor-limite: 0,00 (inválido), 0,01, 9.999.999.999.999,99 e 10.000.000.000.000,00 (inválido). Caso TC-03, de alto nível: "remessa com título já enviado e sem retorno de rejeição não gera segmento A".&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;5. Implementação: está tudo pronto para rodar?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Cria ou obtém o que falta para executar: procedimentos de teste priorizados, scripts automatizados, suítes, cronograma de execução, ambiente construído e verificado, dados preparados e carregados. É aqui que os casos de alto nível ganham valores concretos. Também confere e atualiza a rastreabilidade: toda condição tem caso? Todo caso tem condição?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No exemplo:&lt;/strong&gt;&amp;nbsp;validador de layout automatizado no pipeline; suítes&amp;nbsp;&lt;em&gt;smoke&lt;/em&gt;,&amp;nbsp;&lt;em&gt;risco alto&lt;/em&gt;&amp;nbsp;e&amp;nbsp;&lt;em&gt;regressão Banco A&lt;/em&gt;; versão do validador fixada no ambiente.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;6. Execução: o resultado real bate com o esperado?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Roda as suítes conforme o cronograma, manualmente ou com ferramentas. Registra IDs e versões do objeto de teste, das ferramentas e do testware; compara resultado real com esperado; analisa as anomalias antes de reportar; registra os resultados (passou, falhou, bloqueado); repete testes por correção, confirmação ou regressão. Saídas: status por teste, relatórios de defeitos e as versões envolvidas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No exemplo:&lt;/strong&gt;&amp;nbsp;TC-03 falhou e gerou D-11 (duplicidade, crítico). TC-12 falhou e gerou D-14 (calendário sem feriados municipais). TC-09 também falhou, mas era falso positivo: o ambiente rodava o validador 2.2, com a regra antiga. Atualizado o validador, o teste passou. Não havia defeito no produto, e foi a versão registrada que permitiu descobrir isso.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;7. Conclusão: o que entregamos e o que aprendemos?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Acontece nos marcos: fim de um nível de teste, de uma iteração, de uma release. Verifica se os defeitos foram fechados e registra como solicitações de mudança ou itens de backlog os que restaram. Cria o relatório de resumo, finaliza e arquiva ambiente, dados, infraestrutura e testware, e entrega o testware a quem vai mantê-lo. Analisa as lições aprendidas e usa o que aprendeu para melhorar a maturidade do processo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No exemplo:&lt;/strong&gt;&amp;nbsp;um defeito de severidade média vira item de backlog. Validador, massa de dados e configuração do ambiente vão para a manutenção, reutilizáveis num futuro Banco C. Lições: validar as ambiguidades do layout com o banco antes da modelagem; incluir o calendário de feriados na base de teste desde o planejamento; reservar a janela do sandbox no cronograma.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Rastreabilidade: o que liga as atividades&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Rastreabilidade é o vínculo entre cada elemento da base de teste e o testware associado a ele: condições, casos, procedimentos, suítes, resultados e defeitos. É estabelecido e mantido ao longo de todo o processo. Funciona nos dois sentidos. Da base para o testware, mostra cobertura: requisito sem condição de teste é lacuna. Do testware para a base, mostra por que cada teste existe: teste sem requisito é teste órfão.&lt;/p&gt;

&lt;p&gt;No exemplo, a cadeia é: US-09 → CT-03 → TC-03 → suíte risco alto → ciclo 1: falhou (D-11) → ciclo 2: passou. Além de medir cobertura, ela serve para:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;analisar o impacto de mudanças:&lt;/strong&gt;&amp;nbsp;quando o banco esclarece o formato da data, a cadeia lista as condições e os casos a revisar;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;tornar o teste auditável:&lt;/strong&gt;&amp;nbsp;a evidência de que título enviado não reenvia é US-09 → TC-03 → log do ciclo 2;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;atender critérios de governança de TI:&lt;/strong&gt;&amp;nbsp;evidência por requisito, sem retrabalho;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;melhorar a compreensão dos relatórios:&lt;/strong&gt;&amp;nbsp;status por requisito (passou, falhou, pendente) em vez de contagem de casos;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;traduzir o aspecto técnico para as partes interessadas:&lt;/strong&gt;&amp;nbsp;"reenvio de título já enviado está bloqueado e verificado", em vez de "TC-03 passou";&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;avaliar produto, processo e projeto:&lt;/strong&gt;&amp;nbsp;qualidade (1 crítico e 2 altos abertos), processo (D-14 aponta falha na base de teste) e projeto (62% do risco alto executado contra meta de 80%).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A cadeia pode viver numa ferramenta de gestão de teste ou num sistema próprio. A ferramenta é meio; o que importa é a cadeia existir e ser mantida.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Quem faz o quê&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;A gestão de teste responde pelo processo e pela equipe: planejamento, monitoramento e controle, conclusão. O papel de teste responde pela parte técnica: análise, modelagem, implementação e execução. Em times ágeis, a gestão pode ficar no próprio time.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Cinco erros comuns&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Plano sem critério de saída:&lt;/strong&gt;&amp;nbsp;ninguém sabe quando parar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tratar toda anomalia como defeito:&lt;/strong&gt;&amp;nbsp;analisar antes de reportar evita falso positivo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rastreabilidade em um sentido só:&lt;/strong&gt;&amp;nbsp;esconde os testes órfãos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confundir modelagem com implementação:&lt;/strong&gt;&amp;nbsp;uma define como testar, a outra deixa tudo pronto para rodar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pular a conclusão:&lt;/strong&gt;&amp;nbsp;lições e testware se perdem.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>agile</category>
      <category>software</category>
      <category>softwaredevelopment</category>
      <category>testing</category>
    </item>
    <item>
      <title>Sete princípios dos teste de software</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sun, 04 Oct 2026 20:40:23 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/sete-principios-dos-teste-de-software-196o</link>
      <guid>https://dev.to/yuripeixinho/sete-principios-dos-teste-de-software-196o</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Os sete princípios vêm do syllabus CTFL da ISTQB. São generalizações empíricas sobre o que teste consegue e não consegue fazer, usadas para calibrar expectativa e esforço. A numeração abaixo segue o CTFL 4.0.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Como agrupar&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1, 2 e 7:&lt;/strong&gt; limites do que teste pode garantir.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3 e 4:&lt;/strong&gt; onde e quando alocar esforço.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;5 e 6:&lt;/strong&gt; como manter a abordagem eficaz ao longo do tempo e entre projetos.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;1. Teste mostra a presença de defeitos, não a ausência&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Teste reduz a probabilidade de defeitos não descobertos, mas não prova correção. A formulação clássica é de Dijkstra. Passar em 1.000 casos não garante o comportamento no 1.001º.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Exemplo:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A suíte de cálculo de juros e multa de boleto passa com 200 casos e quebra num vencimento em 29/02.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Implicação:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Reportar "nenhum defeito encontrado com esta cobertura e estes riscos", nunca "sem bugs".&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Teste exaustivo é impossível
&lt;/h2&gt;

&lt;p&gt;Testar todas as combinações de entradas, estados e pré-condições é inviável fora de casos triviais. Por isso existem técnicas de redução (partição de equivalência, análise de valor limite, tabela de decisão, pairwise) e priorização por risco.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Exemplo:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Um formulário com 10 campos e 5 valores relevantes por campo gera 5¹⁰ = 9.765.625 combinações.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Implicação:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Apergunta deixa de ser "testei tudo?" e passa a ser "testei o que tem mais risco, com o menor número de casos que cobre as classes de comportamento?".&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Teste antecipado economiza tempo e dinheiro
&lt;/h2&gt;

&lt;p&gt;Defeito achado em requisito ou design custa menos que o achado em produção. Isso inclui teste estático (revisão de requisitos e de código, análise estática), que encontra defeitos sem executar nada: o "shift left". Os multiplicadores clássicos (10x, 100x) vêm de dados antigos e são contestados, mas a direção do argumento se mantém.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Exemplo:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Uma ambiguidade na regra de arredondamento, apontada na revisão do requisito, vira uma conversa. Essa mesma descoberta depois do fechamento do mês em produção, vira correção, reprocessamento e acerto de dados.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;4. Defeitos se agrupam&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Poucos módulos concentram a maior parte dos defeitos. Costuma-se descrever isso pelo princípio de Pareto (80/20 como heurística, não como lei).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Exemplo:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;3 de 40 módulos respondem por mais da metade dos bugs de produção.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Implicação:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Usar histórico de defeitos, churn de código e complexidade para direcionar o esforço (teste baseado em risco). Cuidado com o viés: um módulo pode parecer problemático só por ser o mais testado.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;5. Os testes se desgastam&lt;/strong&gt; (versão 3.1: "paradoxo do pesticida")
&lt;/h2&gt;

&lt;p&gt;Repetir os mesmos testes deixa de encontrar defeitos novos, porque os que eles alcançavam já foram corrigidos. Isso não invalida regressão automatizada, cujo objetivo é detectar quebra, não achar defeito novo. O problema é depender só dela.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Exemplo:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;30 cenários de checkout verdes há dois anos, sempre com o mesmo usuário e o mesmo cartão. Nenhum exercita cupom + frete grátis + estorno parcial.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Implicação:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Revisar e variar casos e dados periodicamente, complementar com teste exploratório e usar mutation testing para medir se a suíte detecta falhas de fato.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Teste depende do contexto
&lt;/h2&gt;

&lt;p&gt;Não existe abordagem única. O que, quanto e como testar depende de risco, domínio, ciclo de vida, regulação e tecnologia.&lt;/p&gt;

&lt;p&gt;Em aviônica (DO-178C, nível A) exige-se cobertura MC/DC e rastreabilidade formal, enquanto num MVP isso é desperdício. E-commerce com pico sazonal prioriza carga e performance. Sistema sob obrigação regulatória prioriza conformidade e rastreabilidade das regras.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. &lt;strong&gt;A ausência de defeitos é uma falácia&lt;/strong&gt; (versão 3.1: "falácia da ausência de erros")
&lt;/h2&gt;

&lt;p&gt;Achar e corrigir todos os defeitos não adianta se o sistema não atende à necessidade do usuário. É a distinção entre verificação (construímos conforme a especificação?) e validação (construímos a coisa certa?).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Exemplo:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;O sistema segue a especificação sem desvio algum, mas ela descrevia um fluxo que ninguém usa. Zero bugs, zero valor.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Implicação:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Incluir validação com usuário e negócio (teste de aceite, protótipo, feedback em produção), não só verificação contra requisito.&lt;/p&gt;

</description>
      <category>software</category>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
      <category>testing</category>
    </item>
    <item>
      <title>Introdução ao Teste de Software</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sun, 04 Oct 2026 01:31:04 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/introducao-ao-teste-de-software-3fpe</link>
      <guid>https://dev.to/yuripeixinho/introducao-ao-teste-de-software-3fpe</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Testar um sistema não é apenas “rodar o programa e ver se não quebrou”. Formalmente, testes de software é o processo de avaliar um sistema para encontrar diferenças entre o comportamento esperado e o real, e construir confiança de que o sistema faz o que deveria fazer.&lt;/p&gt;

&lt;p&gt;Duas noções que não podem ser confundidas: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Verificação:&lt;/strong&gt; Are &lt;em&gt;we building the product right?&lt;/em&gt; O software está de acordo com a especificação/design? É o território dos testes técnicos (unitários e integração)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validação:&lt;/strong&gt; &lt;em&gt;Are we building the right product?&lt;/em&gt; O software resolve o problema real do negócio? É o território de aceitação, UAT, testes exploratórios.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Usando um caso real de testes para entender as duas noções na prática: &lt;code&gt;GetDiferencaDataEmMeses_DeveRetornarDiferencaCorreta&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Verificação:&lt;/strong&gt; a função implementa corretamente a regra de cálculo de diferença em meses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validação:&lt;/strong&gt; confirmar com a área de negócio que essa métrica é, de fato, a correta para aquele cálculo de benefício, o teste automatizado sozinho não garante isso.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Por que testamos: o custo crescente do erro&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;O argumento central é econômico: &lt;strong&gt;o custo de corrigir um defeito cresce exponencialmente quanto mais tarde ele é descoberto&lt;/strong&gt; (o clássico "custo crescente do erro", popularizado por Boehm).&lt;/p&gt;

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

&lt;p&gt;No domínio do usuário (BPO previdenciário/fiscal): um bug no cálculo de &lt;code&gt;GetDiferencaAnos&lt;/code&gt; (que define elegibilidade a um benefício) encontrado por um teste unitário custa minutos. O mesmo bug encontrado em produção pode significar cálculo errado de benefício para centenas de participantes, retrabalho manual, risco regulatório (e-Financeira é fiscalização da Receita Federal) e dano de confiança.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Os três pilares de todo teste&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Testar é uma atividade de equilíbrio entre três forças:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Correção&lt;/strong&gt;: o sistema faz o que deveria fazer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confiança:&lt;/strong&gt; o quanto a suíte de testes permite mudar o código &lt;strong&gt;sem medo&lt;/strong&gt;. Esse é o verdadeiro ROI de testes: não é "achar bugs", é permitir mudança segura.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custo:&lt;/strong&gt; tempo para escrever, rodar e &lt;strong&gt;manter&lt;/strong&gt; os testes. Testes mal escritos (frágeis, lentos, obscuros) podem custar mais do que valem.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Daqui vem um princípio que vai aparecer no curso inteiro: nem todo teste possível vale a pena escrever. Testar é otimização sob restrição de tempo, não busca por cobertura de 100%.&lt;/p&gt;

&lt;h1&gt;
  
  
  Gestão da Qualidade: QA vs. QC
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Gestão da Qualidade&lt;/strong&gt; é o guarda-chuva: tudo que a organização faz para direcionar e controlar qualidade. Dentro dela, duas disciplinas complementares:&lt;/p&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;Garantia de Qualidade (QA)&lt;/th&gt;
&lt;th&gt;Controle de Qualidade (QC)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Foco&lt;/td&gt;
&lt;td&gt;Processo&lt;/td&gt;
&lt;td&gt;Produto&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Natureza&lt;/td&gt;
&lt;td&gt;Preventiva&lt;/td&gt;
&lt;td&gt;Detectiva&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pergunta&lt;/td&gt;
&lt;td&gt;Estamos seguindo um processo que tende a gerar poucos defeitos?&lt;/td&gt;
&lt;td&gt;Este artefato específico tem defeitos?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Atividades&lt;/td&gt;
&lt;td&gt;Padrões, auditoria de processo, causa raiz, retrospectivas&lt;/td&gt;
&lt;td&gt;Teste (unitário/integração/e2e), inspeção, code review&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Efeito no tempo&lt;/td&gt;
&lt;td&gt;Muda a curva de defeitos &lt;strong&gt;pra baixo&lt;/strong&gt; ao longo dos releases&lt;/td&gt;
&lt;td&gt;Atividades distribuídas &lt;strong&gt;ao longo de todo o ciclo&lt;/strong&gt; ("mais à esquerda" — shift-left)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;QC sem QA vira jogo infinito de achar bug (o processo continua gerando os mesmos tipos de defeito todo sprint). QA sem QC é teoria sem verificação (melhora o processo "no papel", sem dado real de que funcionou). Uma retroalimenta a outra.&lt;/p&gt;

&lt;p&gt;A distinção QA/QC não é arbitrária, ela vem de um modelo mais amplo e bem antigo na gestão da qualidade, o &lt;strong&gt;Custo da Qualidade&lt;/strong&gt; (Cost of Quality, Crosby/Juran), que divide todo investimento em qualidade em quatro categorias:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Categoria&lt;/th&gt;
&lt;th&gt;O que é&lt;/th&gt;
&lt;th&gt;Exemplo em software&lt;/th&gt;
&lt;th&gt;Relação&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Custos de &lt;strong&gt;Prevenção&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Evitar que o defeito aconteça&lt;/td&gt;
&lt;td&gt;Treinamento, revisão de requisito, definição de padrão de código&lt;/td&gt;
&lt;td&gt;= QA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custos de &lt;strong&gt;Avaliação&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Encontrar o defeito antes de ir para produção&lt;/td&gt;
&lt;td&gt;Testes automatizados,code review, inspeção&lt;/td&gt;
&lt;td&gt;= QC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custos de &lt;strong&gt;Falha Interna&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Corrigir defeito encontrado antes do release&lt;/td&gt;
&lt;td&gt;Retrabalho, re-teste, bug encontrado em homologação&lt;/td&gt;
&lt;td&gt;Consequência de QC fraco&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custos de &lt;strong&gt;Falha Externa&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Corrigir defeito encontrado depois do release&lt;/td&gt;
&lt;td&gt;Incidente em produção, suporte, retrabalho de cálculo de benefício, multa regulatória&lt;/td&gt;
&lt;td&gt;O topo da curva de custo crescente do erro (veja o gráfico acima)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;O insight gerencial do modelo: &lt;strong&gt;gastar mais em Prevenção (QA) reduz Avaliação + Falha Interna + Falha Externa, com retorno maior que linear,&lt;/strong&gt; é por isso que organizações maduras investem proporcionalmente mais em QA do que em QC pura, mesmo QC sendo a atividade mais visível (é a que "acha os bugs").&lt;/p&gt;

&lt;h3&gt;
  
  
  Uma confusão muito comum no mercado
&lt;/h3&gt;

&lt;p&gt;Vale um alerta prático: na indústria, é extremamente comum um "time de QA" que, na prática, só faz &lt;strong&gt;QC&lt;/strong&gt; (só testa o produto pronto) sem nenhum mandato real sobre processo. Isso não é um erro terminológico inofensivo: uma organização que chama sua função de teste de "QA" mas nunca faz análise de causa raiz nem muda processo está, na prática, &lt;strong&gt;sem QA nenhuma&lt;/strong&gt; — só QC. O sintoma típico: os mesmos tipos de bug reaparecem release após release, porque ninguém fecha o loop.&lt;/p&gt;

&lt;h3&gt;
  
  
  O ciclo fechado, exemplo aplicado.
&lt;/h3&gt;

&lt;p&gt;Juntando com o exemplo de causa raiz já visto:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;QC encontra&lt;/strong&gt;: um teste de integração (ou, pior, produção) acusa cálculo de benefício incorreto.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RCA aponta a causa raiz&lt;/strong&gt;: regra de negócio mal especificada antes da codificação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;QA age no processo&lt;/strong&gt;: passa a exigir revisão de requisito com 2 aprovadores de negócio antes de qualquer commit de regra de cálculo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;QC mede o resultado&lt;/strong&gt;: nos sprints seguintes, a taxa de defeitos dessa categoria cai — e é esse dado (não a opinião de que "o processo melhorou") que valida se a ação de QA funcionou.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sem o passo 4, você não sabe se a mudança de processo realmente ajudou — é só teoria. Sem o passo 3, você fica reagindo ao mesmo tipo de bug para sempre.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Causa raiz e o Princípio de Pareto&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;O fluxo de QA na prática: &lt;strong&gt;defeito encontrado → análise de causa raiz (5 porquês, diagrama de Ishikawa) → ação no processo → menos defeitos daquele tipo no futuro.&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;Aplicando Pareto (regra 80/20): atacar só as duas primeiras causas já endereça a maioria dos defeitos. A decisão gerencial correta não é "escrever mais testes genéricos" — é ação de processo cirúrgica: revisão de requisito com o time de negócio antes de codificar regras de cálculo (ataca a causa #1), e checklist obrigatório de casos de borda de data para qualquer função que manipule datas (ataca a causa #2).&lt;/p&gt;

&lt;h3&gt;
  
  
  Aprofundando: a técnica dos 5 Porquês
&lt;/h3&gt;

&lt;p&gt;Exemplo aplicado (hipotético, mas realista para o domínio previdenciário):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Por que o cálculo de benefício retornou valor errado para o participante X? → Porque a função somou saldos de dois vínculos como se fossem um só.&lt;/li&gt;
&lt;li&gt;Por que ela somou os dois vínculos? → Porque o código assume implicitamente que cada participante tem só um vínculo ativo por período.&lt;/li&gt;
&lt;li&gt;Por que essa suposição foi codificada assim? → Porque o requisito original não mencionava o caso de múltiplos vínculos simultâneos.&lt;/li&gt;
&lt;li&gt;Por que o requisito não mencionava isso? → Porque a área de negócio que escreveu o requisito não foi consultada sobre esse cenário (raro, mas existente).&lt;/li&gt;
&lt;li&gt;Por que ninguém consultou a área de negócio sobre cenários raros? → Porque não há uma etapa formal de revisão de requisito com checklist de casos de borda antes da codificação.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A causa raiz real (passo 5) é de &lt;strong&gt;processo&lt;/strong&gt;, não de código — "o dev esqueceu" (uma leitura preguiçosa do passo 1) seria a resposta errada se parássemos ali.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Armadilha comum&lt;/strong&gt;: parar no primeiro "porquê" plausível e culpar uma pessoa em vez do processo. Isso é RCA malfeito. Você "resolve" repreendendo ou trocando uma pessoa, e o mesmo tipo de bug reaparece com o próximo desenvolvedor, porque a causa real (ausência de processo) nunca foi tocada.&lt;/p&gt;

&lt;h3&gt;
  
  
  Diagrama de Ishikawa (espinha de peixe)
&lt;/h3&gt;

&lt;p&gt;Categoriza causas possíveis &lt;strong&gt;antes&lt;/strong&gt; de investigar, para não convergir cedo demais numa hipótese única. Adaptação clássica dos "6M" para software:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Categoria&lt;/th&gt;
&lt;th&gt;Pergunta&lt;/th&gt;
&lt;th&gt;Exemplo no domínio&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Método/Processo&lt;/td&gt;
&lt;td&gt;O processo de desenvolvimento permitiu o defeito?&lt;/td&gt;
&lt;td&gt;Falta de revisão de requisito&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pessoas&lt;/td&gt;
&lt;td&gt;Faltou conhecimento/treinamento?&lt;/td&gt;
&lt;td&gt;Novo dev não conhecia a regra de vínculos múltiplos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ferramentas&lt;/td&gt;
&lt;td&gt;A ferramenta/framework contribuiu?&lt;/td&gt;
&lt;td&gt;ORM que esconde uma query N+1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Requisitos/Entrada&lt;/td&gt;
&lt;td&gt;A especificação era ambígua ou incompleta?&lt;/td&gt;
&lt;td&gt;Requisito não cobria vínculo duplo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ambiente&lt;/td&gt;
&lt;td&gt;Configuração de ambiente influenciou?&lt;/td&gt;
&lt;td&gt;Fuso horário diferente em produção vs. dev&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dados&lt;/td&gt;
&lt;td&gt;Dado de produção tinha formato inesperado?&lt;/td&gt;
&lt;td&gt;Campo de data vindo nulo de um sistema legado&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;O efeito (o defeito) fica na "cabeça do peixe"; cada categoria vira uma "espinha" com possíveis causas listadas, até achar a raiz real.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pareto: de onde vem, e uma armadilha
&lt;/h3&gt;

&lt;p&gt;O princípio vem de Vilfredo Pareto (economista que observou que boa parte da terra na Itália pertencia a uma pequena fração da população) — Juran aplicou à qualidade como "os poucos vitais vs. os muitos triviais" (&lt;em&gt;vital few vs. trivial many&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Armadilha gerencial&lt;/strong&gt;: Pareto ordena por &lt;strong&gt;frequência&lt;/strong&gt;, não necessariamente por &lt;strong&gt;severidade/custo&lt;/strong&gt;. Uma causa raiz que aparece em 5% dos defeitos mas gera um incidente regulatório grave (ex.: erro fiscal que atrasa a entrega da e-Financeira) pode merecer prioridade maior que uma causa de 40% que só gera retrabalho interno barato. A regra prática correta: construa o Pareto por &lt;strong&gt;impacto&lt;/strong&gt; (frequência × custo/severidade), não só por contagem bruta.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fechando o loop: como saber se a ação de RCA funcionou
&lt;/h3&gt;

&lt;p&gt;Depois de implementar a ação de processo (ex.: checklist de revisão de requisito), é preciso voltar a medir a mesma categoria de causa raiz nos próximos releases. Se a frequência não caiu, duas hipóteses: (1) a causa raiz identificada estava errada, ou (2) a ação de processo não foi realmente seguida na prática (processo no papel ≠ processo em execução) — o que puxa direto para o ponto já visto de que QA sem QC é teoria sem verificação.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Visão gerencial: garantindo testes eficientes no time&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Três camadas resolvem isso: &lt;strong&gt;quando&lt;/strong&gt; no processo, &lt;strong&gt;o que&lt;/strong&gt; exigir estruturalmente, e &lt;strong&gt;como medir&lt;/strong&gt; se está funcionando.&lt;/p&gt;

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

&lt;p&gt;Regra prática: o caso de teste de aceitação é escrito no mesmo dia que o requisito, não depois que o código existe.&lt;/p&gt;

&lt;h3&gt;
  
  
  O que exigir estruturalmente
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Definition of Done inclui teste.&lt;/strong&gt; Uma história não está "pronta" sem teste automatizado correspondente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code review cobre o teste, não só a implementação.&lt;/strong&gt; O revisor pergunta: esse teste falharia se eu reintroduzisse o bug?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI como gate, não como relatório.&lt;/strong&gt; PR com teste quebrando não mergeia (branch protection).&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Como medir sem teatro de métricas
&lt;/h3&gt;

&lt;p&gt;Cobertura de código (%) como &lt;strong&gt;meta&lt;/strong&gt; vira teatro — testes que exercitam a linha sem afirmar nada relevante. Métricas mais honestas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Taxa de escape de defeito&lt;/strong&gt; — quantos bugs chegaram em produção vs. foram pegos antes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flaky test rate&lt;/strong&gt; — testes que falham/passam aleatoriamente corroem a confiança no CI mais rápido que a ausência de testes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tempo de execução da suíte&lt;/strong&gt; — suíte lenta = time para de rodar localmente = shift-left morre na prática.&lt;/li&gt;
&lt;li&gt;Cobertura entra como &lt;strong&gt;sinalizador de risco&lt;/strong&gt;, nunca como meta isolada de OKR.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Resumo: testes eficientes vêm de integrar teste como parte indissociável da definição de pronto desde o requisito, fechando o loop com análise de causa raiz dos defeitos que escaparem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Estudo de caso: o Problema do Triângulo
&lt;/h2&gt;

&lt;p&gt;Este é o exercício clássico de design de casos de teste (Glenford Myers, &lt;em&gt;The Art of Software Testing&lt;/em&gt;). Especificação: um programa recebe 3 inteiros (lados) e responde &lt;strong&gt;escaleno&lt;/strong&gt;, &lt;strong&gt;isósceles&lt;/strong&gt; ou &lt;strong&gt;equilátero&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A armadilha pedagógica&lt;/strong&gt;: a maioria escreve apenas 3 casos (um por classificação) e considera a suíte completa. Isso falha porque:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A especificação nunca disse que a entrada é sempre um triângulo válido — e se a soma de dois lados for menor que o terceiro (desigualdade triangular violada)?&lt;/li&gt;
&lt;li&gt;O valor-limite exato, onde a soma de dois lados é &lt;strong&gt;igual&lt;/strong&gt; ao terceiro (caso degenerado, "linha reta"), é onde bugs costumam viver.&lt;/li&gt;
&lt;li&gt;Entrada inválida de domínio (zero, negativo) nem é uma pergunta geométrica — é validação de entrada.&lt;/li&gt;
&lt;li&gt;Assimetria de implementação: um bug clássico é checar &lt;code&gt;a==b&lt;/code&gt; e esquecer &lt;code&gt;b==c&lt;/code&gt; isoladamente — por isso isósceles precisa de 3 variações (qual par é igual), não 1.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Suíte reconstruída — "efetiva" (encontra os bugs comuns) e razoavelmente "eficiente" (sem redundância boba):&lt;/p&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;a&lt;/th&gt;
&lt;th&gt;b&lt;/th&gt;
&lt;th&gt;c&lt;/th&gt;
&lt;th&gt;Esperado&lt;/th&gt;
&lt;th&gt;Categoria&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Escaleno&lt;/td&gt;
&lt;td&gt;válido, caso geral&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Isósceles&lt;/td&gt;
&lt;td&gt;1º e 2º iguais&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Isósceles&lt;/td&gt;
&lt;td&gt;1º e 3º iguais&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Isósceles&lt;/td&gt;
&lt;td&gt;2º e 3º iguais&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Equilátero&lt;/td&gt;
&lt;td&gt;todos iguais&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Inválido&lt;/td&gt;
&lt;td&gt;soma &amp;lt; terceiro lado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Inválido&lt;/td&gt;
&lt;td&gt;soma = terceiro (valor-limite)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Inválido&lt;/td&gt;
&lt;td&gt;lado zero&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;-1&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Inválido&lt;/td&gt;
&lt;td&gt;lado negativo&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;O ponto central: "efetivo" e "eficiente" não vêm de cobrir as saídas possíveis, vêm de pensar em como a implementação pode estar errada, ponte direta para as técnicas formais (particionamento de equivalência e análise de valor-limite).&lt;/p&gt;

</description>
      <category>software</category>
      <category>softwareengineering</category>
      <category>testing</category>
    </item>
    <item>
      <title>Livro Head First Design Pattern: Encapsule o que varia</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sat, 03 Oct 2026 16:31:50 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/livro-head-first-design-pattern-encapsule-o-que-varia-3eho</link>
      <guid>https://dev.to/yuripeixinho/livro-head-first-design-pattern-encapsule-o-que-varia-3eho</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;No livro  &lt;em&gt;Head First Design Patterns&lt;/em&gt; ensina: não com a definição seca primeiro, mas com o problema que ele resolve. É assim que o livro faz com quase tudo — te mostra a dor antes da solução.&lt;/p&gt;

&lt;h3&gt;
  
  
  O princípio, em uma frase
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Identifique os aspectos da sua aplicação que variam e separe-os do que permanece constante.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ou seja: se uma parte do seu código muda com frequência (por causa de novos requisitos, novos tipos, novas regras de negócio) e outra parte é estável, &lt;strong&gt;não misture as duas&lt;/strong&gt;. Isole a parte instável numa classe/interface própria, para que mudar uma coisa não quebre a outra.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;O exemplo clássico do livro: o app dos patinhos (SimUDuck)&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Imagine um app de simulação de lagoa com patos. Foi feito com uma classe abstrata &lt;code&gt;Duck&lt;/code&gt; e subclasses como &lt;code&gt;MallardDuck&lt;/code&gt;, &lt;code&gt;RedheadDuck&lt;/code&gt;, etc. Cada uma herda &lt;code&gt;quack()&lt;/code&gt; (grasnar) e &lt;code&gt;swim()&lt;/code&gt; (nadar), e sobrescreve a aparência com &lt;code&gt;display()&lt;/code&gt;. Design de herança clássico, e funciona bem — até que o chefe pede: &lt;strong&gt;"agora os patos precisam voar"&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  O Problema
&lt;/h1&gt;

&lt;p&gt;A primeira ideia (ruim): adicionar &lt;code&gt;fly()&lt;/code&gt; na classe &lt;code&gt;Duck&lt;/code&gt;, já que herança é "reaproveitar código", certo?&lt;/p&gt;

&lt;p&gt;Toda subclasse herda &lt;code&gt;fly()&lt;/code&gt; automaticamente — inclusive o &lt;code&gt;RubberDuck&lt;/code&gt; (pato de borracha), que &lt;strong&gt;não deveria voar&lt;/strong&gt;. Agora você tem um pato de borracha voando pela tela. Você teria que sobrescrever &lt;code&gt;fly()&lt;/code&gt; em cada subclasse que não deveria voar, e o mesmo aconteceria com &lt;code&gt;quack()&lt;/code&gt; quando adicionarem um pato que não grasna.&lt;/p&gt;

&lt;p&gt;Segunda ideia (também ruim): tirar &lt;code&gt;fly()&lt;/code&gt; e &lt;code&gt;quack()&lt;/code&gt; da superclasse e colocar em interfaces &lt;code&gt;Flyable&lt;/code&gt; e &lt;code&gt;Quackable&lt;/code&gt;, implementadas só pelos patos que precisam.&lt;/p&gt;

&lt;p&gt;Interfaces não têm implementação (no Java clássico usado no livro). Cada subclasse que implementa &lt;code&gt;Flyable&lt;/code&gt; precisa reescrever o próprio código de voar. Se 6 tipos de pato voam do mesmo jeito, você duplica o mesmo código 6 vezes. E se um dia mudar a lógica de voo, você corrige em 6 lugares.&lt;/p&gt;

&lt;h2&gt;
  
  
  Desenho do problema
&lt;/h2&gt;

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

&lt;h3&gt;
  
  
  O que esse diagrama mostra
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Duck&lt;/code&gt; define &lt;code&gt;fly()&lt;/code&gt; diretamente na superclasse, junto com &lt;code&gt;quack()&lt;/code&gt; e &lt;code&gt;swim()&lt;/code&gt;. Toda subclasse herda os três automaticamente, sem escolha:&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;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="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;quack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Quack!"&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;swim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Nadando..."&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;fly&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Voando!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// implementação padrão&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;MallardDuck&lt;/span&gt; &lt;span class="n"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;Duck&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// não sobrescreve nada — herda fly() e quack() como estão&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;RubberDuck&lt;/span&gt; &lt;span class="n"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;Duck&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;quack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Rangido de borracha."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// esqueceu (ou nem pensou em) sobrescrever fly() — e agora ele voa&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Por que isso é frágil, mesmo quando "funciona"
&lt;/h3&gt;

&lt;p&gt;Repare que &lt;code&gt;MallardDuck&lt;/code&gt; e &lt;code&gt;RedheadDuck&lt;/code&gt; (azuis) não têm bug nenhum hoje — eles voam de verdade, então herdar &lt;code&gt;fly()&lt;/code&gt; parece inofensivo. Mas o problema não é o bug do &lt;code&gt;RubberDuck&lt;/code&gt; isoladamente; é que &lt;strong&gt;o comportamento está amarrado à árvore de herança&lt;/strong&gt;, e essa árvore não tem como expressar "esse aqui não voa" sem sobrescrever método por método, subclasse por subclasse.&lt;/p&gt;

&lt;p&gt;Isso significa duas coisas ruins:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Todo pato novo herda comportamento por padrão&lt;/strong&gt;, e alguém precisa lembrar de corrigir manualmente quando o padrão não se aplica (como aconteceu com &lt;code&gt;RubberDuck&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mudar como voar funciona significa mexer na superclasse&lt;/strong&gt;, arriscando afetar todo mundo que herda dela — mesmo patos que nunca deveriam ter sido afetados.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A correção "óbvia": tornar &lt;code&gt;fly()&lt;/code&gt; abstrato e forçar cada subclasse a implementar o próprio, parece resolver, mas cria duplicação: se 10 tipos de pato voam do mesmo jeito, você repete o mesmo código de voo 10 vezes. Mudou a física do voo? Corrige em 10 lugares.&lt;/p&gt;

&lt;p&gt;É exatamente esse impasse — herança rígida de um lado, duplicação do outro — que o &lt;strong&gt;encapsulate what varies&lt;/strong&gt; resolve, tirando o comportamento variável da árvore de herança e colocando numa família de classes própria.&lt;/p&gt;

&lt;h1&gt;
  
  
  Solução
&lt;/h1&gt;

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

&lt;p&gt;A ideia central: &lt;code&gt;Duck&lt;/code&gt; &lt;strong&gt;não é mais definida por herança&lt;/strong&gt; de comportamentos, ela &lt;strong&gt;tem&lt;/strong&gt; (composição) uma referência a um &lt;code&gt;FlyBehavior&lt;/code&gt; e a um &lt;code&gt;QuackBehavior&lt;/code&gt;. Cada família de comportamento vira sua própria hierarquia, isolada e independente da hierarquia de patos.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Como fica o código&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="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;FlyBehavior&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;fly&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;FlyWithWings&lt;/span&gt; &lt;span class="n"&gt;implements&lt;/span&gt; &lt;span class="n"&gt;FlyBehavior&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;fly&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Voando!"&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;FlyNoWay&lt;/span&gt; &lt;span class="n"&gt;implements&lt;/span&gt; &lt;span class="n"&gt;FlyBehavior&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;fly&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Não consigo voar."&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 a classe &lt;code&gt;Duck&lt;/code&gt; passa a &lt;strong&gt;delegar&lt;/strong&gt; em vez de herdar diretamente o comportamento:&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;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="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;performFly&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;flyBehavior&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fly&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;   &lt;span class="c1"&gt;// delega para o objeto de comportamento&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;performQuack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;quackBehavior&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quack&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;MallardDuck&lt;/span&gt; &lt;span class="n"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;Duck&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;MallardDuck&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;flyBehavior&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;FlyWithWings&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;quackBehavior&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;Quack&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;RubberDuck&lt;/span&gt; &lt;span class="n"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;Duck&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;RubberDuck&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;flyBehavior&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;FlyNoWay&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;   &lt;span class="c1"&gt;// agora é seguro: ele simplesmente não voa&lt;/span&gt;
        &lt;span class="n"&gt;quackBehavior&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;MuteQuack&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;Repare no que mudou:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O que varia&lt;/strong&gt; (como voar, como grasnar) virou uma família de classes separada, cada uma com uma única responsabilidade.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;O que é estável&lt;/strong&gt; (a estrutura geral de um pato — nadar, ter aparência, existir na lagoa) continua em &lt;code&gt;Duck&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Adicionar um novo tipo de voo (ex: &lt;code&gt;FlyRocketPowered&lt;/code&gt;) não exige tocar em &lt;code&gt;Duck&lt;/code&gt; nem em nenhuma subclasse existente — só criar uma nova classe que implementa &lt;code&gt;FlyBehavior&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Você pode até &lt;strong&gt;trocar o comportamento em tempo de execução&lt;/strong&gt;, já que é só uma referência a um objeto:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Isso já é o cheiro clássico de "o que varia não foi isolado".&lt;/p&gt;

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

&lt;p&gt;A ideia central: &lt;code&gt;Duck&lt;/code&gt; &lt;strong&gt;não é mais definida por herança&lt;/strong&gt; de comportamentos, ela &lt;strong&gt;tem&lt;/strong&gt; (composição) uma referência a um &lt;code&gt;FlyBehavior&lt;/code&gt; e a um &lt;code&gt;QuackBehavior&lt;/code&gt;. Cada família de comportamento vira sua própria hierarquia, isolada e independente da hierarquia de patos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Por que esse é o &lt;em&gt;primeiro&lt;/em&gt; princípio do livro
&lt;/h3&gt;

&lt;p&gt;O livro coloca esse princípio logo no capítulo 1 porque ele é o &lt;strong&gt;raciocínio de base por trás de quase todos os outros padrões&lt;/strong&gt;. Você acabou de ver, sem saber o nome, o esqueleto do &lt;strong&gt;Strategy Pattern,&lt;/strong&gt; que é exatamente isso: encapsular uma família de algoritmos intercambiáveis (aqui, os algoritmos de voar e grasnar) atrás de uma interface comum, e deixar o objeto principal delegar para eles em vez de implementar diretamente.&lt;/p&gt;

&lt;p&gt;Esse mesmo raciocínio ("o que muda, isolo; o que não muda, mantenho estável") reaparece depois em outros padrões do livro:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Observer&lt;/strong&gt; encapsula "quem é notificado e como", separado do objeto que gera o evento.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decorator&lt;/strong&gt; encapsula "quais responsabilidades extras" um objeto ganha, sem mexer na classe original.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Factory Method&lt;/strong&gt; encapsula "qual classe concreta instanciar", separado do código que usa o objeto.
****&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>learning</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Design Patterns (baixo nível)</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sat, 26 Sep 2026 23:05:37 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/design-patterns-baixo-nivel-210e</link>
      <guid>https://dev.to/yuripeixinho/design-patterns-baixo-nivel-210e</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;A ideia de "pattern" (padrão) não nasceu em software — veio do arquiteto &lt;strong&gt;Christopher Alexander&lt;/strong&gt;, que nos anos 1970 catalogou soluções recorrentes para problemas de arquitetura civil e urbanismo, em seu livro &lt;em&gt;A Pattern Language&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Em 1994, quatro autores — &lt;strong&gt;Erich Gamma, Richard Helm, Ralph Johnson e John Vlissides&lt;/strong&gt;, apelidados de &lt;strong&gt;"Gang of Four" (GoF)&lt;/strong&gt; — publicaram &lt;em&gt;"Design Patterns: Elements of Reusable Object-Oriented Software"&lt;/em&gt;, transportando essa ideia para a Programação Orientada a Objetos e catalogando &lt;strong&gt;23 padrões&lt;/strong&gt;, organizados em três categorias: Criacionais, Estruturais e Comportamentais.&lt;/p&gt;

&lt;p&gt;Um pattern &lt;strong&gt;não é código pronto para copiar&lt;/strong&gt;. É uma solução testada para um problema recorrente, documentada de forma abstrata o suficiente para se adaptar a contextos diferentes, mais parecida com uma receita estrutural do que com uma biblioteca.&lt;/p&gt;

&lt;h2&gt;
  
  
  Necessiade aplicada
&lt;/h2&gt;

&lt;p&gt;Quando você programa orientado a objetos por tempo suficiente, alguns problemas/comportamentos se repetem, não a solução exata, mas o formato do problema: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Preciso trocar de comportamento em runtime sem um monte de &lt;code&gt;if&lt;/code&gt;”;&lt;/li&gt;
&lt;li&gt;Preciso que vários objetos saibam quando algo mudou&lt;/li&gt;
&lt;li&gt;preciso criar um objeto complexo sem um construtor gigante&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Como já dito acima, essencialmente, um design pattern é apenas isso. Uma solução já testada e batizada para um desses formatos de problema. Não é uma biblioteca que você importa, não é código pronto pra colar. É mais parecido com uma receita ou um esqueleto que você adapta para o seu caso específico.&lt;/p&gt;

&lt;p&gt;A analogia que mais ajuda: é como aberturas de xadrez. Um jogador experiente reconhece a posição no tabuleiro e já sabe uma sequência de jogadas que historicamente funciona bem ali, mas ele adapta conforme o adversário reage, não copia cegamente. Design pattern é isso: reconhecer "ah, esse é um problema tipo X" e já entrar com uma estrutura que resolve bem esse tipo de problema.&lt;/p&gt;

&lt;h1&gt;
  
  
  Por que isso importa de verdade?
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Vocabulário compartilhado
&lt;/h2&gt;

&lt;p&gt;Quando um colega do time diz “aqui dá pra usar um Observer”, todo mundo que conhece o pattern já entendeu a ideia inteira na hora, sem precisar de um parágrafo explicando “ah, eu quero que vários objetos sejam avisados quando esse aqui mudar”. É um atalho de comunicação entre desenvolvedores.&lt;/p&gt;

&lt;h2&gt;
  
  
  Soluções já brigadas com a realidades
&lt;/h2&gt;

&lt;p&gt;Alguém já tentou resolver esse problema de um jeito ingênuo, tomou a dor de cabeça de manutenção, e refinou até chegar numa estrutura que aguenta essa mudança sem quebrar tudo. Usar pattern é pular direto para a versão que já sobreviveu a esse processo.&lt;/p&gt;

&lt;h1&gt;
  
  
  Os dois princípios centrais
&lt;/h1&gt;

&lt;p&gt;Todo o catálogo é uma aplicação repetida de dois mandamentos, estabelecidos no Capítulo 1 do livro:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;"Programe para uma interface, não para uma implementação"&lt;/strong&gt; — o código cliente depende de abstrações (&lt;code&gt;interface&lt;/code&gt;/classe abstrata), nunca de classes concretas específicas.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;"Prefira composição de objetos à herança de classes"&lt;/strong&gt; — relações "tem um" (montadas em runtime) são mais flexíveis que relações "é um" (fixadas em tempo de compilação).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Praticamente todo pattern do catálogo existe para viabilizar um desses dois princípios em um cenário específico.&lt;/p&gt;

&lt;h1&gt;
  
  
  As três familias de Patterns
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Criacional
&lt;/h2&gt;

&lt;p&gt;Problemas de "como eu crio esse objeto sem virar bagunça?" Se seu objeto tem 8 parâmetros opcionais no construtor, ou se você precisa decidir em runtime qual classe concreta instanciar, é um problema criacional.&lt;/p&gt;

&lt;h2&gt;
  
  
  Estrutural
&lt;/h2&gt;

&lt;p&gt;Problemas de "como eu encaixo essas peças pra formar algo maior?" Pensa em peças de LEGO: você quer que blocos diferentes se conectem de forma flexível, sem que um bloco precise saber os detalhes internos do outro.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comportamental
&lt;/h2&gt;

&lt;p&gt;Problemas de "quem fala com quem, e quem é responsável pelo quê?" É sobre distribuir responsabilidade e comunicação entre objetos sem criar uma teia de dependências onde tudo conhece tudo.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tipo&lt;/th&gt;
&lt;th&gt;O que define&lt;/th&gt;
&lt;th&gt;Exemplos relevantes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Criacional&lt;/td&gt;
&lt;td&gt;Como objetos são criados&lt;/td&gt;
&lt;td&gt;Singleton, Factory, Builder&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Estrutural&lt;/td&gt;
&lt;td&gt;Como classes e objetos se organizam / relacionam&lt;/td&gt;
&lt;td&gt;Adapter, Composite, Decorator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Comportamental&lt;/td&gt;
&lt;td&gt;Como objetos interagem e se comunicam&lt;/td&gt;
&lt;td&gt;Observer, Strategy, Mediator&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;
  
  
  Um exemplo único, para sentir a ideia geral
&lt;/h1&gt;

&lt;p&gt;Esquece os 23 nomes e conceitos por um segundo e vamos focar em um só problema puro:&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;// Sem pattern nenhum: um "if" gigante que cresce toda vez que aparece um jeito novo de pagar&lt;/span&gt;
&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ProcessarPagamento&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;metodo&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;metodo&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"cartao"&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;$"Cobrando R$&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="s"&gt; no cartão..."&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;metodo&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"pix"&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;$"Gerando QR code de R$&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="s"&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;metodo&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"boleto"&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;$"Emitindo boleto de R$&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="s"&gt;..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// daqui a um mês: "criptomoeda", "paypal"... essa função nunca para de crescer&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;// Com pattern: cada forma de pagar é sua própria peça, intercambiável&lt;/span&gt;
&lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IFormaPagamento&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;Processar&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;class&lt;/span&gt; &lt;span class="nc"&gt;PagamentoCartao&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IFormaPagamento&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;Processar&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;=&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;$"Cobrando R$&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="s"&gt; no cartão..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PagamentoPix&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IFormaPagamento&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;Processar&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;=&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;$"Gerando QR code de R$&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="s"&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;____&lt;/span&gt;
&lt;span class="n"&gt;IFormaPagamento&lt;/span&gt; &lt;span class="n"&gt;forma&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;PagamentoPix&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;forma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Processar&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="c1"&gt;// forma nova? cria a classe, nunca mexe no código que já existe&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso, especificamente, tem nome (Strategy), mas o que importa aprender &lt;strong&gt;primeiro&lt;/strong&gt; é o raciocínio: identificar que "essa parte do código vai crescer e mudar" e já desenhar pra absorver mudança sem reescrever o que já funciona. O nome do pattern vem depois, é só o rótulo pra essa forma de pensar já ter sido catalogada antes de você.&lt;/p&gt;

&lt;h1&gt;
  
  
  O template da documentação do livro (13 elementos)
&lt;/h1&gt;

&lt;p&gt;Cada um dos 23 padrões é descrito no livro seguindo exatamente esta estrutura fixa, que replicamos para cada padrão neste documento:&lt;/p&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;Elemento&lt;/th&gt;
&lt;th&gt;O que descreve&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Classificação&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Nome do padrão + categoria (Purpose) + escopo (Scope)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Intent&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;O que o padrão faz, em uma frase&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Also Known As&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Apelidos alternativos, se existirem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Motivation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Um cenário concreto ilustrando o problema&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Applicability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Situações em que o padrão se aplica&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Structure&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Representação das classes/relações envolvidas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Participants&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Classes/objetos envolvidos e suas responsabilidades&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Collaborations&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Como os participantes interagem entre si&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Consequences&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Trade-offs — o que se ganha e o que se paga&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Implementation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Armadilhas e técnicas de implementação&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Sample Code&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Código de exemplo (aqui, em C#)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Known Uses&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Onde o padrão aparece em sistemas/frameworks reais&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Related Patterns&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Com quais outros padrões ele se confunde ou combina&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Classificação Purpose x Scope
&lt;/h2&gt;

&lt;p&gt;O livro classifica os padrões em duas dimensões: &lt;strong&gt;Purpose&lt;/strong&gt; (o que o padrão faz) e o &lt;strong&gt;Scope&lt;/strong&gt; (se a relação é fixada por herança em tempo de compilação — classe — ou montada dinamicamente por composição em runtime — objeto — &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scope \ Purpose&lt;/th&gt;
&lt;th&gt;Criacional&lt;/th&gt;
&lt;th&gt;Estrutural&lt;/th&gt;
&lt;th&gt;Comportamental&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Classe&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Factory Method&lt;/td&gt;
&lt;td&gt;Adapter (classe)&lt;/td&gt;
&lt;td&gt;Template Method, Interpreter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Objeto&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Abstract Factory, Builder, Prototype, Singleton&lt;/td&gt;
&lt;td&gt;Adapter (objeto), Bridge, Composite, Decorator, Facade, Flyweight, Proxy&lt;/td&gt;
&lt;td&gt;Chain of Responsibility, Command, Iterator, Mediator, Memento, Observer, State, Strategy, Visitor&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Note que &lt;strong&gt;Adapter aparece nas duas linhas&lt;/strong&gt;: é o único padrão do catálogo documentado com duas variantes — uma via herança (Classe) e outra via composição (Objeto), sendo a segunda a preferida na prática (coerente com o segundo princípio central).&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>design</category>
      <category>programming</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>POO: Scope / Visibility</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sat, 29 Aug 2026 17:10:53 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/poo-scope-visibility-2c88</link>
      <guid>https://dev.to/yuripeixinho/poo-scope-visibility-2c88</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Se você não escrever nenhum modificador num membro de classe, ele vira &lt;code&gt;private&lt;/code&gt; por padrão. E se você não escrever nenhum modificador numa classe de nível superior, ela vira &lt;code&gt;internal&lt;/code&gt; por padrã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;Veiculo&lt;/span&gt; &lt;span class="c1"&gt;// sem "public" aqui, seria "internal" por padrão&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;_combustivel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// sem modificador = private implícito — CUIDADO, é fácil esquecer&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tabela completa de todos os níveis, incluindo as combinações que ficaram de fora do desenho anterior:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Modificador&lt;/th&gt;
&lt;th&gt;Quem acessa&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;private&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;só a própria classe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;protected&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;a classe e suas subclasses, em qualquer assembly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;internal&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;qualquer código no mesmo assembly (projeto/DLL)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;protected internal&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;subclasses &lt;strong&gt;OU&lt;/strong&gt; mesmo assembly (união dos dois)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;private protected&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;subclasses &lt;strong&gt;E&lt;/strong&gt; mesmo assembly ao mesmo tempo (interseção — C# 7.2+)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;public&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;qualquer lugar&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;file&lt;/code&gt; (C# 11+)&lt;/td&gt;
&lt;td&gt;só dentro do mesmo arquivo &lt;code&gt;.cs&lt;/code&gt; — bem de nicho, usado em código gerado&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Aplicado na nossa 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;abstract&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Veiculo&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;_senhaAlarme&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;4821&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;          &lt;span class="c1"&gt;// só Veiculo enxerga, nem subclasse vê&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;_quilometragem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;           &lt;span class="c1"&gt;// Veiculo E suas subclasses enxergam&lt;/span&gt;
    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;CodigoFrota&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"FROTA-01"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// qualquer classe do mesmo projeto enxerga&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;Placa&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="c1"&gt;// literalmente qualquer um enxerga&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Granularidade por acessor&lt;/strong&gt; — isso é subestimado: getter e setter de uma mesma propriedade podem ter visibilidades diferentes:&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;Veiculo&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// getter público (todo mundo lê a velocidade), setter privado (só o próprio Veiculo muda)&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;VelocidadeAtual&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="c1"&gt;// getter protected internal (subclasses OU mesmo assembly), setter só pra subclasses&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;double&lt;/span&gt; &lt;span class="n"&gt;Odometro&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso é como você escreve, no código de verdade, aquele princípio de "esconder o dado, expor uma leitura controlada" — sem precisar escrever um método &lt;code&gt;GetVelocidade()&lt;/code&gt; manualmente.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Regra prática pra decidir:&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Campo quase sempre &lt;code&gt;private&lt;/code&gt; (exponha via propriedade se precisar); método que é só detalhe interno de implementação, &lt;code&gt;private&lt;/code&gt;; algo que outras classes do mesmo módulo precisam mas o mundo de fora não, &lt;code&gt;internal&lt;/code&gt;; parte do "contrato público" da sua classe, &lt;code&gt;public&lt;/code&gt;. &lt;code&gt;protected&lt;/code&gt; só quando você sabe que vai ter herança e a subclasse genuinamente precisa daquele acesso direto.&lt;/p&gt;

</description>
      <category>backend</category>
      <category>csharp</category>
      <category>dotnet</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>POO: Interfaces</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sat, 29 Aug 2026 17:06:18 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/poo-interfaces-2fie</link>
      <guid>https://dev.to/yuripeixinho/poo-interfaces-2fie</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Um contrato puro. Tradicionalmente, zero implementação, zero estado só a assinatura do que um tipo promete saber fazer.&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;interface&lt;/span&gt; &lt;span class="nc"&gt;IAutonomo&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;Pilotar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IEletrico&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;NivelBateria&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="c1"&gt;// interface também pode ter propriedade, não só método&lt;/span&gt;
    &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Recarregar&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: dentro da interface você &lt;strong&gt;não escreve &lt;code&gt;public&lt;/code&gt;&lt;/strong&gt; — todo membro de interface já é implicitamente público, e você não pode restringir isso.&lt;/p&gt;

&lt;p&gt;Uma classe pode implementar &lt;strong&gt;quantas interfaces quiser&lt;/strong&gt;, além de herdar de uma única classe base:&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;CarroAutonomo&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Veiculo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IAutonomo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IEletrico&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;double&lt;/span&gt; &lt;span class="n"&gt;_bateria&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;CarroAutonomo&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;placa&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;placa&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;DescreverModo&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;"Modo carro autônomo elétrico."&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;Pilotar&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;"🤖 Dirigindo sozinho, sem motorista."&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;double&lt;/span&gt; &lt;span class="n"&gt;NivelBateria&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_bateria&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;Recarregar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_bateria&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="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;"🔋 Bateria recarregada."&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;strong&gt;O nugget mais avançado: implementação explícita de interface&lt;/strong&gt;, pra resolver conflito quando duas interfaces têm método com o mesmo nome:&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;interface&lt;/span&gt; &lt;span class="nc"&gt;IRelatorioFrota&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;GerarRelatorio&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IRelatorioManutencao&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;GerarRelatorio&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// mesmo nome, contratos diferentes!&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Caminhao&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Veiculo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IRelatorioFrota&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IRelatorioManutencao&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;Caminhao&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;placa&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;placa&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;DescreverModo&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;"Modo caminhão: carga pesada."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Implementação EXPLÍCITA: só acessível através do tipo da interface, não direto no objeto&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;IRelatorioFrota&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GerarRelatorio&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;"Relatório de frota: em rota"&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;IRelatorioManutencao&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GerarRelatorio&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;"Relatório de manutenção: revisão pendente"&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;Caminhao&lt;/span&gt; &lt;span class="n"&gt;c&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;Caminhao&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CMN-01"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;IRelatorioFrota&lt;/span&gt; &lt;span class="n"&gt;rf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="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="n"&gt;rf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GerarRelatorio&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// "Relatório de frota: em rota"&lt;/span&gt;

&lt;span class="n"&gt;IRelatorioManutencao&lt;/span&gt; &lt;span class="n"&gt;rm&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="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="n"&gt;rm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GerarRelatorio&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// "Relatório de manutenção: revisão pendente"&lt;/span&gt;

&lt;span class="c1"&gt;// c.GerarRelatorio() direto → ❌ nem compila, é ambíguo demais pra existir sem o "casting"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Interface Marcadora (marker interface)
&lt;/h1&gt;

&lt;p&gt;Sem a implementação explícita, o compilador nem saberia qual das duas assinaturas você quis dizer. Com ela, cada versão "mora" dentro do tipo da interface específica.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interface marcadora (marker interface):&lt;/strong&gt; uma interface vazia, sem nenhum membro, usada só pra "carimbar" um tipo:&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;interface&lt;/span&gt; &lt;span class="nc"&gt;IInspecionavel&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// vazia de propósito&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Caminhao&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Veiculo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IInspecionavel&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&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;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;veiculo&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;IInspecionavel&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;"Precisa passar por inspeção periódica."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>programming</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>POO: Classes Concretas</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sat, 29 Aug 2026 16:43:31 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/poo-classes-abstratas-59dl</link>
      <guid>https://dev.to/yuripeixinho/poo-classes-abstratas-59dl</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Uma classe é concreta quando está 100% implementada. Nenhum membro fica pendurado sem corpo. É por isso, e so por isso que o compilador libera o &lt;code&gt;new&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Vamos ver a anatomia completa de uma classe concreta, com todas as peças que ela pode ter:&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="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Campo privado: o dado bruto, cru&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;_combustivelLitros&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Propriedades: a porta de entrada controlada&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;Placa&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="c1"&gt;// só leitura fora do construtor&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;double&lt;/span&gt; &lt;span class="n"&gt;VelocidadeAtual&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="c1"&gt;// lê de fora, só a própria classe muda&lt;/span&gt;

    &lt;span class="c1"&gt;// Membro estático e constante: pertencem à CLASSE, não a cada objeto&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;CapacidadeTanqueMaxima&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;50.0&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;int&lt;/span&gt; &lt;span class="n"&gt;_totalCarrosCriados&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;// Construtor principal&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Carro&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;placa&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;modelo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;combustivelInicial&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Placa&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;placa&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="n"&gt;modelo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;_combustivelLitros&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;combustivelInicial&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;_totalCarrosCriados&lt;/span&gt;&lt;span class="p"&gt;++;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Construtor sobrecarregado, encadeando no principal com "this(...)"&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Carro&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;placa&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;modelo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;placa&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="n"&gt;combustivelInicial&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="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="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;incremento&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;_combustivelLitros&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;0&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;$"&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; está sem combustível!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;VelocidadeAtual&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;incremento&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;_combustivelLitros&lt;/span&gt; &lt;span class="p"&gt;-=&lt;/span&gt; &lt;span class="m"&gt;0.5&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;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;TotalCriados&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;_totalCarrosCriados&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;Vale destrinchar cada detalhe:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Placa&lt;/code&gt; sem &lt;code&gt;set&lt;/code&gt;.&lt;/strong&gt; Só pode ser atribuída dentro do construtor. Depois disso, é imutável pra sempre. É a forma mais simples de garantir que uma placa nunca muda depois de criada.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;_totalCarrosCriados&lt;/code&gt; estático&lt;/strong&gt;, ***&lt;em&gt;não pertence a nenhum carro específico, pertence à *classe&lt;/em&gt; &lt;code&gt;Carro&lt;/code&gt; inteira. Incrementa toda vez que qualquer carro nasce, e é compartilhado entre todas as instâncias.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dois construtores&lt;/strong&gt; — o segundo delega pro primeiro via &lt;code&gt;: this(...)&lt;/code&gt;, evitando duplicar a lógica de inicialização. É overloading de construtor, o mesmo mecanismo do overloading de método.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Instanciando:&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="kt"&gt;var&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="nf"&gt;Carro&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ABC-1234"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Modelo X"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;combustivelInicial&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;40&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// usa o construtor completo&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;outroCarro&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;Carro&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DEF-5678"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Modelo Y"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// usa o construtor curto, com 10L de combustível padrão&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Quando usar só uma classe concreta, sem hierarquia nenhuma:&lt;/strong&gt; quando não existe variação de comportamento por tipo. Se só vai existir um jeito de "Carro" existir no seu sistema — sem carro elétrico, autônomo, etc. — criar uma hierarquia complexa é over-engineering. Comece simples, só introduza &lt;code&gt;abstract&lt;/code&gt;/interface quando a variação aparecer de verdade.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Erro comum:&lt;/strong&gt; a "God Class" — uma classe concreta que vai crescendo e acumulando responsabilidades demais (&lt;code&gt;Carro&lt;/code&gt; cuidando de motor, de pagamento do aluguel, de geolocalização, de manutenção...). É sintoma de que faltou dividir em outras classes menores — ligação direta com o "S" do SOLID que já vimos.&lt;/p&gt;

</description>
      <category>backend</category>
      <category>csharp</category>
      <category>dotnet</category>
      <category>programming</category>
    </item>
    <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>
  </channel>
</rss>
