<?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.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>Descomplicando GraphQL</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sat, 09 May 2026 15:16:33 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/descomplicando-graphql-14i8</link>
      <guid>https://dev.to/yuripeixinho/descomplicando-graphql-14i8</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Podemos dizer que o GraphQL é o filhote de dois conceitos fundamentais na programação: API e Linguagens de Query/SQL&lt;/p&gt;

&lt;p&gt;É uma linguagem de consulta para APIs e um runtime para executar essas consultas. É uma alternativa ao REST que dá ao cliente controle preciso sobre os dados que recebem.&lt;/p&gt;

&lt;h2&gt;
  
  
  O problema que ele resolve
&lt;/h2&gt;

&lt;p&gt;Com &lt;a href="https://www.notion.so/REST-35b671b57a3e80aa9ac7c35d57086289?pvs=21" rel="noopener noreferrer"&gt;REST&lt;/a&gt;, os desenvolvedores frequentemente enfrentam dois problemas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Over-fetching: receber mais dados do que precisa (ex: buscar um usuário e receber 20 campos quando só quer o nome)&lt;/li&gt;
&lt;li&gt;Under-fetching: fazer múltiplas requisições para montar uma tabela (ex: buscar → post → buscar autor → buscar comentários)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Com GraphQL, você pede &lt;strong&gt;exatamente o que precisa, em uma única requisição.&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conceitos fundamentais
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. Schema
&lt;/h2&gt;

&lt;p&gt;O coração do GraphQL. Define os tipos de dados e as operações disponíveis&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;!]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Query (leitura)
&lt;/h2&gt;

&lt;p&gt;O cliente especifica exatamente o que quer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Resposta:&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Mutation (escrita)
&lt;/h2&gt;

&lt;p&gt;Para criar, atualizar ou deletar dados:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Novo Post"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Conteúdo aqui"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Subscription (em tempo real)
&lt;/h2&gt;

&lt;p&gt;Para ouvir eventos em tempo real via WebSocket:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;subscription&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;newMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chatId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"42"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Quando usar?
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;✅ Boa escolha quando:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Múltiplos clientes (web, mobile) consomem os mesmos dados de formas diferentes&lt;/li&gt;
&lt;li&gt;O frontend precisa de flexibilidade para evoluir sem depender do backend&lt;/li&gt;
&lt;li&gt;Você tem dados interconectados (grafos de relacionamentos&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;⚠️ Talvez não valha a pena quando:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API simples com poucos endpoints&lt;/li&gt;
&lt;li&gt;Time pequeno sem familiaridade com o ecossistema&lt;/li&gt;
&lt;li&gt;Caching HTTP simples é suficiente (REST se beneficia mais disso)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>api</category>
      <category>beginners</category>
      <category>graphql</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Descomplicando RPC e gRPC</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sat, 09 May 2026 14:56:24 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/descomplicando-rpc-e-grpc-20p7</link>
      <guid>https://dev.to/yuripeixinho/descomplicando-rpc-e-grpc-20p7</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;A Chamada de Procedimento Remoto (RPC) é um dos paradigmas mais simples de API, em que um cliente executa um bloco de código em outro servidor. &lt;/p&gt;

&lt;p&gt;Imagine que você tem um aplicativo no seu computador (Cliente) e ele precisa calcular uma fórmula complexa. Em vez de calcular isso localmente, ele chama uma função chamada &lt;code&gt;CalcularImposto()&lt;/code&gt;. A mágica do RPC é que essa função não existe no seu computador; ela está em um servidor do outro lado do mundo.&lt;/p&gt;

&lt;p&gt;Para fazer isso parecer local, o RPC usa um conceito chamado &lt;strong&gt;Stub&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O &lt;strong&gt;Cliente&lt;/strong&gt; chama o &lt;em&gt;Client Stub&lt;/em&gt; (um pedaço de código local que finge ser a função real).&lt;/li&gt;
&lt;li&gt;O &lt;em&gt;Stub&lt;/em&gt; pega os parâmetros que você passou, empacota tudo (processo chamado de &lt;strong&gt;Serialização&lt;/strong&gt;) e envia pela rede.&lt;/li&gt;
&lt;li&gt;O servidor recebe a mensagem, passa para o &lt;em&gt;Server Stub&lt;/em&gt;, que desempacota os dados (&lt;strong&gt;Desserialização&lt;/strong&gt;) e chama a função real.&lt;/li&gt;
&lt;li&gt;O resultado faz o caminho inverso até chegar ao seu cliente.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O grande objetivo do RPC é esconder a complexidade da rede. O desenvolvedor apenas chama funções, sem se preocupar em montar requisições HTTP ou gerenciar conexões manualmente.&lt;/p&gt;

&lt;h1&gt;
  
  
  Exemplo
&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;POST&lt;/span&gt;
&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;conversations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;archive&lt;/span&gt;
&lt;span class="n"&gt;HOST&lt;/span&gt; &lt;span class="n"&gt;slack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;urlencoded&lt;/span&gt;
&lt;span class="n"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;Bearer&lt;/span&gt; &lt;span class="n"&gt;xoxp&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1650112&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;jgc2asDae&lt;/span&gt;

&lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="n"&gt;C01234&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  API de Conversação do Slack
&lt;/h1&gt;

&lt;p&gt;Diferente do REST, onde o &lt;strong&gt;verbo&lt;/strong&gt; é passado no argumento do método HTTP, no RPC o verbo é explícito dentro da URI.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Método&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Descrição&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;conversations.archive&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Archives a conversation.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;conversations.close&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Closes a direct message or multi-person direct message.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;conversations.create&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Initiates a public or private channel-based conversation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;conversations.history&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fetches a conversation's history of messages and events.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;conversations.info&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Retrieve information about a conversation.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;conversations.invite&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Invites users to a channel.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;conversations.join&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Joins an existing conversation.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;conversations.kick&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Removes a user from a conversation.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;conversations.leave&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Leaves a conversation.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;conversations.list&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Lists all channels in a Slack team.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;conversations.members&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Retrieve members of a conversation.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;conversations.open&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Opens or resumes a direct message or multi-person direct message.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>api</category>
      <category>architecture</category>
      <category>backend</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Descomplicando o REST</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sat, 09 May 2026 14:35:16 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/descomplicando-o-rest-5fb4</link>
      <guid>https://dev.to/yuripeixinho/descomplicando-o-rest-5fb4</guid>
      <description>&lt;h2&gt;
  
  
  O paradigma REST
&lt;/h2&gt;

&lt;p&gt;A transferência de Estado Representacional (REST) é a escolha mais popular para o desenvolvimento da API nos últimos anos.&lt;/p&gt;

&lt;p&gt;Baseado no conceito central de recursos. Um recurso é uma entidade que pode ser identificada, nomeada, endereçada ou tratada na web.&lt;/p&gt;

&lt;p&gt;As APIs REST expõem dados como recursos e usam métodos HTTP padrão para representar transações Criar, Ler, Atualizar e Excluir (CRUD) contra esses recursos. &lt;br&gt;
Por exemplo, a API da Stripe representa clientes, encargos, saldos, reembolsos, eventos, arquivos e pagamentos como recursos.&lt;/p&gt;
&lt;h2&gt;
  
  
  Exemplo na API  do Sripe
&lt;/h2&gt;

&lt;p&gt;Requisição HTTP para recuperar uma cobrança da API Stripe&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="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;**&lt;/span&gt;
&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;charges&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ch_CWyut1Xs9pZyfD&lt;/span&gt;
&lt;span class="n"&gt;HOST&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stripe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="n"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Bearer&lt;/span&gt; &lt;span class="n"&gt;YNoJlYq64iCBhzfL9HNO00fzVrsEjtV&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Requisição HTTP para enviar uma cobrança na API Stripe&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;POST&lt;/span&gt; 
&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;charges&lt;/span&gt;
&lt;span class="n"&gt;HOST&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stripe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;urlencoded&lt;/span&gt;
&lt;span class="n"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Bea&lt;/span&gt;
&lt;span class="n"&gt;rer&lt;/span&gt;
&lt;span class="n"&gt;YNoJlYq64iCBhzfL9HNO00fzVrsEjtVl&lt;/span&gt;

&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="n"&gt;usd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Uso de métodos HTTP
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Métodos HTTP como GET, POST, UPDATE e DELETE informam o servidor sobre a ação a ser realizada.&lt;/li&gt;
&lt;li&gt;Diferentes métodos HTTP invocados na mesma URL fornecem funcionalidades diferentes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Criar:&lt;/strong&gt; Use o POST, na maioria dos casos, para criar novos recursos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ler:&lt;/strong&gt; Use o GET para ler recursos. Requisições GET nunca mudam o estado do recurso. Elas não têm efeitos colaterais. O GET é idempotente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Atualização:&lt;/strong&gt; Use o PUT para substituir um recurso e PATCH para atualizações parciais para os recursos existentes. o PUT também é idempotente&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Excluir:&lt;/strong&gt; Use o DELETE para excluir recursos existentes. O DELETE também é idempotente&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Nomenclatura
&lt;/h1&gt;

&lt;p&gt;Os recursos fazem parte de URLs, como &lt;code&gt;/usuarios&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Para cada recurso, duas URLs são geralmente implementadas: uma para a coleção, como &lt;code&gt;/usuarios&lt;/code&gt;, e uma para elemento específico, como &lt;code&gt;/usuarios/U123&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Nomes são usados em vez de verbos para definir recursos. Por exemplo, em vez de &lt;code&gt;/lerInformacaoUsuario/U123&lt;/code&gt;, use &lt;code&gt;/usuario/U123&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Códigos de Resposta
&lt;/h1&gt;

&lt;p&gt;Imagine que você envia uma &lt;strong&gt;carta&lt;/strong&gt; para alguém. A resposta que você recebe de volta pode ser:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ "Entregue com sucesso!"&lt;/li&gt;
&lt;li&gt;🔄 "O destinatário se mudou, tente outro endereço"&lt;/li&gt;
&lt;li&gt;❌ "Carta com endereço errado"&lt;/li&gt;
&lt;li&gt;💥 "O correio teve um problema interno"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;É exatamente assim que funcionam os códigos HTTP — são &lt;strong&gt;respostas do servidor&lt;/strong&gt; ao seu navegador/aplicação.&lt;/p&gt;

&lt;p&gt;Geralmente, os códigos na faixa 2XX indicam sucesso, 3XX indicam que um recurso de moveu e códigos na faixa 4XX indicam um erro do lado do cliente (como um parâmetro necessário ausente ou muitas solicitações).&lt;/p&gt;

&lt;p&gt;Códigos na faixa 5XX indicam erros do lado do servidor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Descomplicando Tabela de Códigos
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🟢 2XX — Sucesso
&lt;/h3&gt;

&lt;p&gt;O servidor recebeu, entendeu e processou sua requisição.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Código&lt;/th&gt;
&lt;th&gt;Nome&lt;/th&gt;
&lt;th&gt;Significado&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;200&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;OK&lt;/td&gt;
&lt;td&gt;Tudo certo! Resposta padrão de sucesso&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;201&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Created&lt;/td&gt;
&lt;td&gt;Um recurso foi criado (ex: cadastro feito)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;204&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No Content&lt;/td&gt;
&lt;td&gt;Sucesso, mas sem nada para retornar&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  🔵 3XX — Redirecionamento
&lt;/h3&gt;

&lt;p&gt;O recurso que você pediu &lt;strong&gt;está em outro lugar&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Código&lt;/th&gt;
&lt;th&gt;Nome&lt;/th&gt;
&lt;th&gt;Significado&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;301&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Moved Permanently&lt;/td&gt;
&lt;td&gt;Mudou de endereço para sempre&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;302&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Found&lt;/td&gt;
&lt;td&gt;Redirecionamento temporário&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;304&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not Modified&lt;/td&gt;
&lt;td&gt;Use o cache, nada mudou&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  🟡 4XX — Erro do Cliente
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Você&lt;/strong&gt; fez algo errado na requisição.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Código&lt;/th&gt;
&lt;th&gt;Nome&lt;/th&gt;
&lt;th&gt;Significado&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;400&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Bad Request&lt;/td&gt;
&lt;td&gt;Requisição mal formada&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;401&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Unauthorized&lt;/td&gt;
&lt;td&gt;Precisa estar autenticado (fazer login)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;403&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Forbidden&lt;/td&gt;
&lt;td&gt;Autenticado, mas sem permissão&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;404&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not Found&lt;/td&gt;
&lt;td&gt;O recurso não existe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;429&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Too Many Requests&lt;/td&gt;
&lt;td&gt;Você fez requisições demais (rate limit)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  🔴 5XX — Erro do Servidor
&lt;/h3&gt;

&lt;p&gt;O &lt;strong&gt;servidor&lt;/strong&gt; que teve um problema, não você.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Código&lt;/th&gt;
&lt;th&gt;Nome&lt;/th&gt;
&lt;th&gt;Significado&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;500&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Internal Server Error&lt;/td&gt;
&lt;td&gt;Erro genérico no servidor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;502&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Bad Gateway&lt;/td&gt;
&lt;td&gt;Servidor intermediário recebeu resposta inválida&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;503&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Service Unavailable&lt;/td&gt;
&lt;td&gt;Servidor fora do ar ou sobrecarregado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;504&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Gateway Timeout&lt;/td&gt;
&lt;td&gt;O servidor demorou demais para responder&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;
  
  
  Formatos de resposta
&lt;/h1&gt;

&lt;p&gt;As APIs REST podem devolver respostas JSON ou XML. E devido à sua simplicidade e facilidade de uso com Javascript, o JSON tornou-se o padrão para APIs modernas.&lt;/p&gt;

&lt;p&gt;O XML e outros formatos ainda podem ser suportados para facilitar a adoção para clientes que ainda estão trabalhando nesse formatos usando APIs semelhantes.&lt;/p&gt;

&lt;p&gt;No Brasil, o XML é comum em APIs do governo para facilitar a governança dos dados, como NF-E ou E-Social&lt;/p&gt;

&lt;h1&gt;
  
  
  Convenções para um CRUD com REST
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operação&lt;/th&gt;
&lt;th&gt;Verbo HTTP&lt;/th&gt;
&lt;th&gt;URL: /usuarios&lt;/th&gt;
&lt;th&gt;URL: /usuários/123&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Criar&lt;/td&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;Cria um novo usuário&lt;/td&gt;
&lt;td&gt;Não é aplicável&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ler&lt;/td&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;Lista todos os usuários&lt;/td&gt;
&lt;td&gt;Recupera o usuário 123&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Atualizar&lt;/td&gt;
&lt;td&gt;PUT ou PATCH&lt;/td&gt;
&lt;td&gt;Atualiza em lote os usuários&lt;/td&gt;
&lt;td&gt;Atualiza o usuário 123&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remover&lt;/td&gt;
&lt;td&gt;DELETE&lt;/td&gt;
&lt;td&gt;Apaga todos os usuários&lt;/td&gt;
&lt;td&gt;Apaga o usuário 123&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Verbo HTTP&lt;/th&gt;
&lt;th&gt;URI Exemplo&lt;/th&gt;
&lt;th&gt;Semântica&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;/livros/123/autores&lt;/td&gt;
&lt;td&gt;Criar os autores para o livro 123&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;/livros/123/autores/1&lt;/td&gt;
&lt;td&gt;Recupera o autor 1 do livro 123&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PUT ou PATCH&lt;/td&gt;
&lt;td&gt;/livros/123/autores/1&lt;/td&gt;
&lt;td&gt;Atualiza os dados do autor 1 do livro 123&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DELETE&lt;/td&gt;
&lt;td&gt;/livros/123/autores&lt;/td&gt;
&lt;td&gt;Apaga todos os autores do livro 123&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;
  
  
  Operações não CRUD
&lt;/h1&gt;

&lt;p&gt;Além das operações típicas da CRUD que acabamos de olhar, as APIs REST às vezes precisam representar operações não-CRUD.&lt;/p&gt;

&lt;p&gt;As seguintes abordagens são comumente usadas nesse caso:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Crie uma ação como um subrecurso.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="n"&gt;livros&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;empromocao&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Crie uma ação através de parâmetros de entrada
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="n"&gt;livros&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="n"&gt;tipo&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="n"&gt;empromocao&lt;/span&gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;categoria&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="n"&gt;autoajuda&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>api</category>
      <category>backend</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>APIs (Application Interface Programming)</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sat, 09 May 2026 01:55:35 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/apis-application-interface-programming-3fdf</link>
      <guid>https://dev.to/yuripeixinho/apis-application-interface-programming-3fdf</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Uma API é a interface que uma aplicação de software apresenta a outras aplicações.&lt;/p&gt;

&lt;p&gt;As APIs são os blocos de construção que permitem a interoperabilidade para as principais plataformas de negócios na web.&lt;/p&gt;

&lt;p&gt;As APIs permitem que identidades sejam criadas e mantidas em contas de software em nuvem, desde seu endereço de e-mail corporativo, a software de design colaborativo. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Habilitam os compartilhamento de dados de previsão do tempo para aplicações&lt;/li&gt;
&lt;li&gt;Processam seus cartões de créditos e permitem que as empresas recebem seus dinheiro sem preocupações regulatórias&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  APIs simplificam o uso de outro softwares
&lt;/h1&gt;

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

&lt;p&gt;bd3a18c-8cfd-4e32-80bd-65306503eb1d:image.png)&lt;/p&gt;

&lt;p&gt;Para enviar uma mensagem de WhatsApp via código, por exemplo, o desenvolvedor não precisa entender como os servidores da Meta funcionam, nem como a criptografia de ponta a ponta é processada matematicamente. Ele só precisa se comunicar com a API do serviço de mensagens.&lt;/p&gt;

&lt;p&gt;Isso garante duas grandes vantagens:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Foco no Produto:&lt;/strong&gt; Empresas ganham agilidade ao integrar soluções já prontas (como mapas, pagamentos e envios de e-mail) em vez de "reinventar a roda".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Independência de Linguagem:&lt;/strong&gt; Uma API bem construída não se importa se o seu aplicativo foi programado em Python, Java, PHP ou Node.js. Desde que a mensagem seja enviada no padrão correto, a comunicação acontece.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Tipos de APIs
&lt;/h1&gt;

&lt;p&gt;Nem toda API tem a mesma funcionalidade e propósito. O desenvolvedor deve saber qual o propósito ao construir e resusar a API.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  APIs para Soluções Móveis
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;O número de dispositivos móveis e tablets superou o número de computadores. Os aplicativos para celular são diferentes dos aplicativos de desktop tradicion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ais, já que a maioria dos aplicativos móveis não é autônoma nem autossuficiente.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Os aplicativos precisam se conectar aos servidores na Internet para serem utilizáveis ou, pelo menos, serem utilizáveis em todo o seu potencial.&lt;/li&gt;
&lt;li&gt;Os dados entregues pelas APIs precisam ser leves e particionados. Isso garante que a API possa ser consumida por dispositivos com capacidade de processamento limitada e largura de banda limitada de conexão à Internet.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  APIs para Soluções de Nuvem
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;As soluções em nuvem SaaS normalmente consistem em um aplicativo da Web e APIs. O aplicativo da web é visível para os consumidores.&lt;/li&gt;
&lt;li&gt;Embaixo do capô, as soluções em nuvem geralmente oferecem uma API também, no entanto, a API normalmente permanece sob a superfície. Essa API pode ser usada para conectar o aplicativo de nuvem a outros aplicativos de nuvem para realizar a automação ou para conectar a solução de nuvem a aplicativos móveis e software de desktop.&lt;/li&gt;
&lt;li&gt;O Dropbox é um exemplo para esse tipo de solução em nuvem. A API desta solução de nuvem permite que muitos aplicativos de terceiros se conectem ao Dropbox, incluindo ferramentas de sincronização para dispositivos móveis e desktop.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  APIs para Soluções de Integração
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;APIs fornecem os recursos, que são essenciais para conectar, estender e integrar software. Ao integrar software, as APIs conectam empresas a outras empresas. Eles são usados em soluções de integração de negócios para empresas.&lt;/li&gt;
&lt;li&gt;O negócio de uma empresa pode ser expandido conectando-se os negócios aos parceiros para cima e para baixo na cadeia de valor.&lt;/li&gt;
&lt;li&gt;Como os negócios são executados pela TI, os negócios podem ser mais bem vinculados, integrando os sistemas de TI de um negócio em toda a cadeia de valor aos sistemas de TI de outras empresas, parceiros, funcionários e, é claro, aos clientes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  APIs para Soluções Multi-Canal
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Sistemas diversos oferecem aos clientes a possibilidade de fazer compras em várias plataformas: no celular, na Web ou no tablet.&lt;/li&gt;
&lt;li&gt;Para melhorar a experiência de uso, os mesmos dados e ações do usuário precisam estar disponíveis em todos os dispositivos do usuário, mesmo que sejam construídos em hardware diferente, executem sistemas operacionais diferentes e aplicativos diferentes.&lt;/li&gt;
&lt;li&gt;Soluções Omni-Canal ou soluções multicanais fornecem exatamente isso. Independentemente do canal usado pelos clientes, eles obtêm uma experiência consistente em todos os dispositivos e podem alternar facilmente entre os dispositivos.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;APIs para Soluções IoT&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A internet das coisas é composta de dispositivos físicos com uma conexão à internet.&lt;/li&gt;
&lt;li&gt;Os dispositivos são controlados por software por meio de seus atores ou os dispositivos podem coletar dados por meio de seus sensores.&lt;/li&gt;
&lt;li&gt;Assim, o dispositivo em si não precisa ser "inteligente", no entanto, ele pode se comportar como um dispositivo inteligente.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  A Agenda do arquiteto para APIs
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Como identificar, escolher e desenhar APIs?&lt;/li&gt;
&lt;li&gt;Como implementar e testar APIs?&lt;/li&gt;
&lt;li&gt;Como documentar e comunicar APIs?&lt;/li&gt;
&lt;li&gt;Como definir tecnologias de APIs?&lt;/li&gt;
&lt;li&gt;Como gerenciar APIs?&lt;/li&gt;
&lt;li&gt;Como descobrir e reusar APIs?&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  O processo de construção de APIs
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Descobrimos como a maioria dos consumidores gostaria de usar a nova API.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Projetamos a API&lt;/strong&gt; para que ela se encaixe no portfólio de diferentes APIs que nossa empresa oferece.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escolhemos o estilo arquitetônico&lt;/strong&gt;, ou seja, se a API aplica um estilo REST, RPC, SOAP, WebSocket, entre outros.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Projetamos um protótipo da API&lt;/strong&gt; usando uma linguagem de descrição da API, como RAML ou Open API (Swagger).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Simulamos a API e criamos um protótipo da API.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Selecionamos a plataforma da API, que fornece os blocos de construção reutilizáveis para as APIs.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Implementamos e testamos a API, uma pedaço por vez.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Implantamos e gerenciamos a API em ambiente de produção&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Aumentamos o engajamento para descoberta e uso das APIs criadas.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Ciclo de Vida de APIs com Plataformas
&lt;/h1&gt;

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

</description>
      <category>api</category>
      <category>backend</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>ISP — Interface Segregation Principle (Princípio da Segregação de Interface)</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Thu, 29 Jan 2026 21:42:18 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/isp-interface-segregation-principle-principio-da-segregacao-de-interface-3om7</link>
      <guid>https://dev.to/yuripeixinho/isp-interface-segregation-principle-principio-da-segregacao-de-interface-3om7</guid>
      <description>&lt;h1&gt;
  
  
  Interface Segregation Principle
&lt;/h1&gt;

&lt;p&gt;O ISP afirma que uma interface não deve forçar a classe a implementar métodos que elas não utilizam.  A ideia é quebras grandes interfaces em menores e mais específicas, ou seja, em vez de interfaces gigantes e genéricas (”interfaces gordas”),  devemos ter “interfaces magras”, quebradas e mais específicas.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Clientes não devem ser forçados a depender de métodos que não usam.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pense nisso como um menu de restaurante:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Violação do ISP:&lt;/strong&gt; O restaurante obriga você a comprar o combo com hambúrguer, batata, refrigerante, sorvete e café, mesmo que você só queira o hambúrguer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aplicação do ISP:&lt;/strong&gt; O menu é segregado. Você pode pedir itens individuais ou combos menores que façam sentido para o seu "apetite" (necessidade)&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Exemplo didático do problema
&lt;/h1&gt;

&lt;p&gt;Imagine que temos a Interface chamada &lt;code&gt;ITrabalhador&lt;/code&gt;, ela possui métodos como &lt;code&gt;Codificar()&lt;/code&gt;, &lt;code&gt;Testar()&lt;/code&gt; e &lt;code&gt;GerenciarProjetos()&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Você vai criar uma classe chamada &lt;code&gt;Programador&lt;/code&gt; que implementa essa interface. Até esse cenário tudo ocorre como o esperado.&lt;/li&gt;
&lt;li&gt;O problema é que se você criar uma classe &lt;code&gt;Gerente&lt;/code&gt;, e implementar a mesma interface ela será obrigada a implementar &lt;code&gt;Codificar()&lt;/code&gt;, mesmo que o gerente não escreva código.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Essa prática cria um acoplamento desnecessário e “polui” o código com métodos vazios ou que lançam exceções como &lt;code&gt;throw new NotImplementedException&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Exemplo técnico do problema
&lt;/h1&gt;

&lt;p&gt;Vamos retomar o exemplo acima e desenvolver com o código com C# de duas formas, uma que viola o ISP e outra que não viola.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Violação estrutural
&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;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Uma "Interface Gorda" que tenta fazer tudo&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ITrabalhador&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;Codificar&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;Testar&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;GerenciarProjeto&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;Programador&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ITrabalhador&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;Codificar&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;"Escrevendo código C#..."&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;Testar&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;"Testando bugs..."&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;GerenciarProjeto&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;"Atualizando o JIRA..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
    &lt;span class="c1"&gt;// Ok, talvez o programador faça um pouco de tudo.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Gerente&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ITrabalhador&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;Codificar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Oxente! O Gerente não deveria ser obrigado a ter este método.&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;NotImplementedException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Gerentes não codificam!"&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;Testar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;NotImplementedException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Gerentes não testam!"&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;GerenciarProjeto&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;"Gerenciando o time..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. O Jeito Correto
&lt;/h2&gt;

&lt;p&gt;Agora, vamos segregar (separar) as interfaces. Assim, cada classe só assina o "contrato" que realmente consegue cumprir.&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;// Interfaces segregadas e específicas (Interfaces Magras)&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ICodificador&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;Codificar&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;interface&lt;/span&gt; &lt;span class="nc"&gt;ITestador&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;Testar&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;interface&lt;/span&gt; &lt;span class="nc"&gt;IGerente&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;GerenciarProjeto&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// O Programador implementa apenas o que faz sentido para ele&lt;/span&gt;
&lt;span class="c1"&gt;// Ele pode implementar múltiplas interfaces se necessário!&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;Programador&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ICodificador&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ITestador&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;Codificar&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;"Escrevendo código C#..."&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;Testar&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;"Testando bugs..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// O Gerente agora está limpo e focado&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Gerente&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IGerente&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;GerenciarProjeto&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;"Gerenciando o time..."&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;



</description>
      <category>architecture</category>
      <category>codequality</category>
      <category>programming</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>LSP - Liskov Substitution Principle (Princípio da Substituição de Liskov)</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Tue, 27 Jan 2026 01:41:36 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/lsp-liskov-substitution-principle-principio-da-substituicao-de-liskov-37o6</link>
      <guid>https://dev.to/yuripeixinho/lsp-liskov-substitution-principle-principio-da-substituicao-de-liskov-37o6</guid>
      <description>&lt;p&gt;O terceiro princípio é o Liskov Substituition Principle. Ele foi definido por Barbara Liskov em 1987 e, embora que por definição academia pareça ser um “bicho de setes cabeças”, na prática é bem simples e ideal para criar sistemas robustos.&lt;/p&gt;

&lt;p&gt;O princípio diz que: Uma classe derivada deve poder ser substituída por sua classe base sem que o comportamento do programa seja alterado ou quebrado.&lt;/p&gt;

&lt;p&gt;Para cumprir  o príncpio pense assim: “O filho (classe que herda) deve conseguir fazer tudo que o pai (classe pai) prometeu que faria”. Se o pai diz "eu sei somar dois números", o filho não pode dizer "eu só sei somar se os números forem positivos". Isso seria uma surpresa desagradável para quem usa o código.&lt;/p&gt;

&lt;h2&gt;
  
  
  Analogia com Pássaros
&lt;/h2&gt;

&lt;p&gt;Imagine que você tem um sistema para um zoológico. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Você cria a Entidade &lt;code&gt;Passaro&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Você define que todo &lt;code&gt;Passaro&lt;/code&gt; tem a habilidade de voar.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Até aqui, tudo bem. Aí você cria os tipos específicos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pardal&lt;/strong&gt; (É um Pássaro): Voa? Sim. ✅ (Tudo certo, segue o princípio).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Águia&lt;/strong&gt; (É um Pássaro): Voa? Sim. ✅ (Tudo certo).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agora vem o problema. Você precisa adicionar um &lt;strong&gt;Pinguim&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pinguim&lt;/strong&gt; (É um Pássaro): Voa? &lt;strong&gt;Não.&lt;/strong&gt; ❌&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Onde o princípio quebra?
&lt;/h3&gt;

&lt;p&gt;Se você tem uma parte do seu código que diz: “Pegue todos os pássaros e faça-os voar”, quando chegar a vez do Pinguim o programa vai travar ou dar erro, porque pinguins não voam. Na aplicação promete que &lt;strong&gt;todo&lt;/strong&gt; pássaro voa, mas o pinguim não cumpre essa promessa.&lt;/p&gt;

&lt;h3&gt;
  
  
  Como consertar o exemplo do Pinguim?
&lt;/h3&gt;

&lt;p&gt;Em vez de colocar "Voar" na categoria principal &lt;strong&gt;&lt;code&gt;Passaro&lt;/code&gt;&lt;/strong&gt;, você deve criar uma categoria mais específica ou separar as habilidades:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Classe &lt;strong&gt;`Passaro&lt;/strong&gt;` (Tem bico, bota ovos).&lt;/li&gt;
&lt;li&gt;Classe &lt;strong&gt;&lt;code&gt;PassaroQueVoa&lt;/code&gt;&lt;/strong&gt; (Herda de Pássaro + sabe voar).&lt;/li&gt;
&lt;li&gt;Classe &lt;strong&gt;&lt;code&gt;PassaroQueNada&lt;/code&gt;&lt;/strong&gt; Herda de Pássaro + sabe nadar).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Dessa forma o Pardal entra em &lt;strong&gt;&lt;code&gt;PassaroQueVoa&lt;/code&gt;&lt;/strong&gt; e o Peguim em &lt;strong&gt;&lt;code&gt;PassaroQueNada&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;E o melhor: ninguém promete o que não pode cumprir, e o código não quebra.&lt;/p&gt;

&lt;h1&gt;
  
  
  Exemplo aplicado ao código
&lt;/h1&gt;

&lt;p&gt;Vamos retomar o exemplo acima e desenvolver com o código com C# de duas formas, uma que viola o LSP e outra que não viola.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Violação Estrutural
&lt;/h2&gt;

&lt;p&gt;Imagine que você tem uma classe abstrata &lt;code&gt;Passaro&lt;/code&gt;. Em C#, é comum usarmos classes abstratas ou interfaces para definir contratos.&lt;/p&gt;

&lt;p&gt;O exemplo abaixo viola o LSP porque o &lt;code&gt;Pinguim&lt;/code&gt; não pode substituir &lt;code&gt;Passaro&lt;/code&gt; sem causar efeitos colaterais (a exceção).&lt;/p&gt;

&lt;h3&gt;
  
  
  Classe Base
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Passaro&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;Voar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Implementação Concreta
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pardal&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Passaro&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;Voar&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;"Pardal voando alto!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Implementação que viola o LSP
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pinguim&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Passaro&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;Voar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// O compilador obriga a implementar Voar(),&lt;/span&gt;
        &lt;span class="c1"&gt;// mas a lógica não permite. O dev lança uma exceção.&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;NotImplementedException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Pinguins não voam!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. O Jeito Correto
&lt;/h2&gt;

&lt;p&gt;Em C#, a melhor forma de resolver isso é segregando as capacidades através de &lt;strong&gt;Interfaces&lt;/strong&gt;. Nem todo pássaro é um &lt;code&gt;IVoador&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Essa implementação abaixo torna impossível passar um Pinguim para um método que espera &lt;code&gt;IVoador&lt;/code&gt;. O compilador do C# vai te impedir antes mesmo de você rodar o programa.&lt;/p&gt;

&lt;h3&gt;
  
  
  Definição de abstração (interface e classe abstrata)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Define apenas o que é comum a TODOS&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Ave&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;Comer&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;"Comendo..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Interface (Capacidade) separada&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IVoador&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;Voar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Implementações
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Pardal é uma Ave E sabe voar&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;Pardal&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Ave&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IVoador&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;Voar&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;"Pardal 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="c1"&gt;// Pinguim é apenas uma Ave (não implementa IVoador)&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;Pinguim&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Ave&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Pode ter métodos de nadar aqui&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>architecture</category>
      <category>beginners</category>
      <category>codequality</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>OCP — Open/Closed Principle (Princípio Aberto/Fechado)</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Mon, 26 Jan 2026 23:58:55 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/ocp-openclosed-principle-principio-abertofechado-1n31</link>
      <guid>https://dev.to/yuripeixinho/ocp-openclosed-principle-principio-abertofechado-1n31</guid>
      <description>&lt;h1&gt;
  
  
  Princípio Aberto/Fechado
&lt;/h1&gt;

&lt;p&gt;Esse é o segunda pilar do SOLID. Sua fundamentação existe para que os softwares criados sejam fáceis de manter e evoluir sem quebrar o que já funciona.&lt;/p&gt;

&lt;p&gt;Certo! Mas o que diabos isso significa?  Os sistemas não são estáticos, eles tendem a evoluír. O cenário comum no mercado, portanto, é: com novas definições de funcionalidades os desenvolvedores geralmente alteram o código-fonte existente, código este, que já foi testado e homologado. Resultando em um sistema difícil de manter e “sustentar”.&lt;/p&gt;

&lt;p&gt;O OCP surge para mitigar esse problema e a definição foi criada por Bertrand Meyer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Entidades de software (classes, módulos, funções, etc.) devem estar abertas para extensão, mas fechadas para modificação."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Aberto pra Extensão:&lt;/strong&gt; Você é deve ser capaz de adicionar novos comportamentos e funcionalidades ao sistema à medida que os requisitos mudam.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fechada para Modificações:&lt;/strong&gt; Ao adicionar essa nova funcionalidade, você não deve alterar o código-fonte existente que já foi estado e está funcionando&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Metáfora da Tomada
&lt;/h1&gt;

&lt;p&gt;Tenho um professor que comparou esse princípio com uma tomada. elétrica de parede.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ela é &lt;strong&gt;fechada pra modificação&lt;/strong&gt;, já que você não precisa quebrar a parede e refazer a fiação elétrica da casa toda vez que compra um novo eletrodoméstico&lt;/li&gt;
&lt;li&gt;Ela é &lt;strong&gt;abertura para extensão&lt;/strong&gt;, você pode instalar uma TV, ventilador ou carregador estendendo a utilidade daquela rede relétrica, apenas plugando algo novo. A interface (os buracos da tomada) permitee isso.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Exemplo prático
&lt;/h1&gt;

&lt;p&gt;Vamos desenvolver um cálculo de Bônus Anual. Imagine uma classe &lt;code&gt;CalculadoraDeBonus&lt;/code&gt;. Inicialmente, a empresa só tem "Desenvolvedores" e "Gerentes". &lt;/p&gt;

&lt;h2&gt;
  
  
  Exemplo Ruim (Violando OCP)
&lt;/h2&gt;

&lt;p&gt;Nesta abordagem comum (mas ruim), usamos um &lt;code&gt;switch&lt;/code&gt; ou &lt;code&gt;if/else&lt;/code&gt; para verificar o cargo. O problema: quero adicionar dois novos cargos, diretor e estagiário. Para isso eu preciso abrir a classe e modificá-la diretamente! Isso viola o OCP&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;CalculadoraDeBonus&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;Calcular&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;cargo&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;salario&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;cargo&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Gerente"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;salario&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;0.2m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cargo&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Desenvolvedor"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;salario&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;0.1m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Se a empresa criar o cargo "Diretor" amanhã, &lt;/span&gt;
        &lt;span class="c1"&gt;// VOU TER QUE ALTERAR ESTE ARQUIVO.&lt;/span&gt;
        &lt;span class="k"&gt;return&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;O Risco:&lt;/strong&gt; Ao editar esse arquivo para adicionar o "Diretor", você pode sem querer apagar uma linha ou mudar a lógica do "Gerente", causando bugs em algo que já estava testado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solução (Aplicando OCP)
&lt;/h2&gt;

&lt;p&gt;Vou trazer duas abordagens para fechar a classe para modificação e abri-las para extensão. Ambas abordagens resolvem o OCP, mas elas comunicam intenções diferentes sobre o seu sistema.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Abordagem com Classe Abstrata&lt;/li&gt;
&lt;li&gt;Abordagem com Interfaces&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. Abordagem com Classe Abstrata
&lt;/h2&gt;

&lt;p&gt;Use essa abrodagem quando existe uma relação forte de herança e você quer reaproveitar propriedades ou métodos&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cenário:&lt;/strong&gt; Todo funcionário tem &lt;code&gt;Nome&lt;/code&gt; e &lt;code&gt;Salario&lt;/code&gt; (código compartilhado), mas o cálculo do bônus muda.&lt;/p&gt;

&lt;h3&gt;
  
  
  Contrato
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FuncionarioBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Código compartilhado (Reuso)&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;public&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;Salario&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="c1"&gt;// Obriga as classes filhas a implementarem a lógica específica&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;CalcularBonus&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Método comum que já funciona para todos (não precisa sobrescrever)&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;ObterCracha&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;$"Funcionário: &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;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Aberto para extensões:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Gerente&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FuncionarioBase&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;CalcularBonus&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Salario&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;0.2m&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;Desenvolvedor&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FuncionarioBase&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;CalcularBonus&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Salario&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;0.1m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Uso
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Processar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FuncionarioBase&lt;/span&gt; &lt;span class="n"&gt;funcionario&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="n"&gt;funcionario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CalcularBonus&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Abordagem com Interface
&lt;/h2&gt;

&lt;p&gt;Use esta abordagem quando o foco é o &lt;strong&gt;"O QUE FAZ"&lt;/strong&gt; (Comportamento). Interfaces são contratos puros. Elas não carregam "bagagem" (estado ou variáveis) e permitem maior flexibilidade, pois uma classe pode implementar múltiplas interfaces.&lt;br&gt;
&lt;strong&gt;Cenário:&lt;/strong&gt; Aqui não nos importamos se é um funcionário, um prestador de serviço ou um robô. Só nos importamos se ele tem uma regra de bônus. Isso é frequentemente chamado de &lt;strong&gt;Strategy Pattern&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Contrato
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// --- O Contrato (Interface) ---&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IRegraDeBonus&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;Calcular&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="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BonusParaDesenvolvedor&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IRegraDeBonus&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;Calcular&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;salarioBase&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;0.1m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Aberto para extensões:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// Note que não herdamos de ninguém, apenas assinamos o contrato&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;BonusParaGerente&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IRegraDeBonus&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;Calcular&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;salarioBase&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;0.2m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Uso
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculadoraServico&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Recebemos a INTERFACE. Baixíssimo acoplamento.&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;ExecutarCalculo&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;salario&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IRegraDeBonus&lt;/span&gt; &lt;span class="n"&gt;regra&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;regra&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Calcular&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;salario&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Comparação entre abordagens: Abstract Class vs. Interface
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Característica&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Abstract Class&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Interface&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Relacionamento&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;"É um"&lt;/strong&gt; (Hierarquia estrita). Um Gerente &lt;em&gt;é um&lt;/em&gt; Funcionário.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;"Faz isso"&lt;/strong&gt; (Capacidade). Essa classe &lt;em&gt;sabe calcular&lt;/em&gt; bônus.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reuso de Código&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Alto.&lt;/strong&gt; Permite compartilhar propriedades (&lt;code&gt;Nome&lt;/code&gt;, &lt;code&gt;ID&lt;/code&gt;) e métodos concretos.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Baixo/Nenhum.&lt;/strong&gt; Apenas define as assinaturas dos métodos.*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Herança&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Limitada.&lt;/strong&gt; C# só permite herdar de 1 classe. Se usar Abstract, você "gasta" essa cartada.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Múltipla.&lt;/strong&gt; Uma classe pode implementar 5 interfaces diferentes (&lt;code&gt;IBonificavel&lt;/code&gt;, &lt;code&gt;IAutenticavel&lt;/code&gt;, etc).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Acoplamento&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Médio. As filhas dependem da classe pai.&lt;/td&gt;
&lt;td&gt;Baixíssimo. As classes só dependem do contrato.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Quando usar no OCP?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Quando você tem uma família de objetos intimamente relacionados que compartilham estrutura.&lt;/td&gt;
&lt;td&gt;Quando você quer plugar comportamentos diferentes (Strategy Pattern) ou testabilidade máxima (Mocks).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;No desenvolvimento moderno de C# (.NET Core/Dependency Injection), &lt;strong&gt;Interfaces são usadas em 90% dos casos&lt;/strong&gt; para garantir o OCP, pois facilitam muito os testes unitários (Mocking).&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>codequality</category>
      <category>programming</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>SRP — Single Responsibility Principle (Princípio da Responsabilidade Única)</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Mon, 26 Jan 2026 23:36:18 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/srp-single-responsibility-principle-principio-da-responsabilidade-unica-4e1a</link>
      <guid>https://dev.to/yuripeixinho/srp-single-responsibility-principle-principio-da-responsabilidade-unica-4e1a</guid>
      <description>&lt;h1&gt;
  
  
  Single Responsability Principle
&lt;/h1&gt;

&lt;p&gt;Esse é o primeiro pilar do SOLID. A definição clássica é “Uma classse deve ter um, e apenas um motivo pra mudar.”.&lt;/p&gt;

&lt;p&gt;Na prática, isso quer dizer que uma classe deve ser responsável por uma funcionalidade/parte específica do software. Em sistemas “blocos de cimentos”, é comum encontrarmos as chamadas “God Objects” (Objeto Deus), uma classe gigantesca que sabem e fazem tudo. O que contradiz o princípio da responsabilidade única.&lt;/p&gt;

&lt;h2&gt;
  
  
  Analogia
&lt;/h2&gt;

&lt;p&gt;Imagine um funcionário de um restaurante que é, ao mesmo tempo, o cozinheiro, o garçom e o faxineiro . Se ele precisar mudar a forma como limpa o chão, o serviço de cozinha e o atendimento podem ser afetados ou interrompidos. No SRP, dividimos essas tarefas entre especialistas para que um não atrapalhe a evolução do outro.&lt;/p&gt;

&lt;h1&gt;
  
  
  Exemplo
&lt;/h1&gt;

&lt;p&gt;Vamos imaginar um cenário em que o princípio não foi aplicado e após isso vamos transformá-lo em um código modular. Imagine um sistema que gerencia pedidos de e-commerce.&lt;/p&gt;

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

&lt;p&gt;Na classe &lt;code&gt;Pedido&lt;/code&gt; abaixo, temos três motivos diferentes para serem alterados. Se a regra de calculo, banco e e-mail mudar. Cada método representa uma responsabilidade diferente para a classe &lt;code&gt;Pedido&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="n"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calcular_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="n"&gt;gica&lt;/span&gt; &lt;span class="n"&gt;de&lt;/span&gt; &lt;span class="n"&gt;neg&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="nf"&gt;cio&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pre&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;impostos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;descontos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;pass&lt;/span&gt;

    &lt;span class="n"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;salvar_no_banco&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="n"&gt;gica&lt;/span&gt; &lt;span class="n"&gt;de&lt;/span&gt; &lt;span class="nf"&gt;infraestrutura&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Conex&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;SQL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tabelas&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;pass&lt;/span&gt;

    &lt;span class="n"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;enviar_email_confirmacao&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="n"&gt;gica&lt;/span&gt; &lt;span class="n"&gt;de&lt;/span&gt; &lt;span class="n"&gt;comunica&lt;/span&gt;&lt;span class="err"&gt;çã&lt;/span&gt;&lt;span class="nf"&gt;o&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Servidor&lt;/span&gt; &lt;span class="n"&gt;SMTP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Exemplo Solução
&lt;/h2&gt;

&lt;p&gt;Para aplicar o SRP, separamos as tarefas em “especialistas”. Cada classe agora tem apenas uma razão para existir e mudar. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;Pedido&lt;/code&gt; vai conter apenas a lógica de cálculo &lt;code&gt;calcular_total&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;salvar_no_banco&lt;/code&gt; vai ser uma nova classe chamada &lt;code&gt;PedidoRepository&lt;/code&gt;, que vai implementar o &lt;a href="https://www.notion.so/Repository-1b2671b57a3e8165ae03fa63305dccce?pvs=21" rel="noopener noreferrer"&gt;Padrão Repository&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;enviar_email_confirmacao&lt;/code&gt; vai ser um serviço separado apenas por enviar comunicações&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Desse modo, se você decidir trocar o e-mail por uma mensagem no WhatsApp, você altera apenas o serviço respectivo. A regra de cálculo do &lt;code&gt;Pedido&lt;/code&gt; então permanece segura e intocada, como uma peça LEGO independente&lt;/p&gt;

&lt;h2&gt;
  
  
  Exemplo aplicado a contexto: Clean Architecture, Mediator, CQRS e DDD
&lt;/h2&gt;

&lt;p&gt;Veja como o SRP se manifesta em um &lt;strong&gt;CommandHandler&lt;/strong&gt; usando Mediator:&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;// Este Handler tem UMA única razão para mudar: &lt;/span&gt;
&lt;span class="c1"&gt;// Se o fluxo de "Criação de Pedido" for alterado.&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;CriarPedidoHandler&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IRequestHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CriarPedidoCommand&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IPedidoRepository&lt;/span&gt; &lt;span class="n"&gt;_repository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Interface (DIP)&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IMediator&lt;/span&gt; &lt;span class="n"&gt;_mediator&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;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CriarPedidoCommand&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// 1. Regra de Negócio (DDD: Entidade decide se pode ser criada)&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pedido&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;Pedido&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClienteId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&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;// 2. Persistência (Clean Arch: O Handler não sabe se é SQL ou NoSQL)&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_repository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SalvarAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pedido&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// 3. Comunicação (Mediator: Dispara um evento para quem interessar)&lt;/span&gt;
        &lt;span class="c1"&gt;// Isso separa a criação do pedido do envio de e-mail (SRP puro!)&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_mediator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Publish&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;PedidoCriadoEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pedido&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;pedido&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://dev.to/yuripeixinho/principios-solid-3ahm"&gt;Veja o conteúdo completo aqui!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>beginners</category>
      <category>programming</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Princípios SOLID</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Fri, 23 Jan 2026 01:57:50 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/principios-solid-3ahm</link>
      <guid>https://dev.to/yuripeixinho/principios-solid-3ahm</guid>
      <description>&lt;h1&gt;
  
  
  Contexto do SOLID
&lt;/h1&gt;

&lt;p&gt;Antigamente os sistemas eram desenvolvidos com um único objetivo: fazer o software funcionar. Os padrões utilizados eram monolíticos e rígidos, com forte acoplamento e com tudo interligado. Atualmente sistemas conhecidos como “Código espaguete” ou “Grande Bola de Lama”. Como tudo estava interligado, corrigir um erro em uma ponta do sistema geralmente causava erros em outras partes do sistema.&lt;/p&gt;

&lt;h2&gt;
  
  
  Crise do Software
&lt;/h2&gt;

&lt;p&gt;Na década de 70 e 80 o desenvolvimento de software enfrentava uma crise. O hardware estava ficando incrivelmente potente e barato, mas o software estava se tornando tão complexo que as equipes não conseguiam mantê-los de forma eficiente.&lt;/p&gt;

&lt;h1&gt;
  
  
  Introdução ao SOLID
&lt;/h1&gt;

&lt;p&gt;O SOLID veio pra transformar o desenvolvimento de software em uma tarefa artesanal em uma engenharia, focada em criar peças que se encaixam sem estarem “soldadas” umas nas outras. Ele é um conjunto de cinco princípios de design de software para a programação orientada a objetos (POO).&lt;/p&gt;

&lt;p&gt;Em resumo, podemos dizer que os princípios funcionam como uma base/guia para os desenvolvedores arquitetarem soluções fáceis de manter, testar e evoluír ao longo do tempo.&lt;/p&gt;

&lt;p&gt;Ao invés de desenvolvermos sistemas como “um grande bloco de cimento”, o SOLID nos ensina a construir softwares como peças “LEGO”, que se encaixam de forma inteligente.&lt;/p&gt;

&lt;h1&gt;
  
  
  1. Princípio da Responsabilidade Única
&lt;/h1&gt;

&lt;p&gt;Esse é o primeiro pilar do SOLID. A definição clássica é “Uma classse deve ter um, e apenas um motivo pra mudar.”.&lt;/p&gt;

&lt;p&gt;Na prática, isso quer dizer que uma classe deve ser responsável por uma funcionalidade/parte específica do software. Em sistemas “blocos de cimentos”, é comum encontrarmos as chamadas “God Objects” (Objeto Deus), uma classe gigantesca que sabem e fazem tudo. O que contradiz o princípio da responsabilidade única.&lt;/p&gt;

&lt;h2&gt;
  
  
  Analogia
&lt;/h2&gt;

&lt;p&gt;Imagine um funcionário de um restaurante que é, ao mesmo tempo, o cozinheiro, o garçom e o faxineiro . Se ele precisar mudar a forma como limpa o chão, o serviço de cozinha e o atendimento podem ser afetados ou interrompidos. No SRP, dividimos essas tarefas entre especialistas para que um não atrapalhe a evolução do outro.&lt;/p&gt;

&lt;h1&gt;
  
  
  Exemplo
&lt;/h1&gt;

&lt;p&gt;Vamos imaginar um cenário em que o princípio não foi aplicado e após isso vamos transformá-lo em um código modular. Imagine um sistema que gerencia pedidos de e-commerce.&lt;/p&gt;

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

&lt;p&gt;Na classe &lt;code&gt;Pedido&lt;/code&gt; abaixo, temos três motivos diferentes para serem alterados. Se a regra de calculo, banco e e-mail mudar. Cada método representa uma responsabilidade diferente para a classe &lt;code&gt;Pedido&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="n"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calcular_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="n"&gt;gica&lt;/span&gt; &lt;span class="n"&gt;de&lt;/span&gt; &lt;span class="n"&gt;neg&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="nf"&gt;cio&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pre&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;impostos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;descontos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;pass&lt;/span&gt;

    &lt;span class="n"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;salvar_no_banco&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="n"&gt;gica&lt;/span&gt; &lt;span class="n"&gt;de&lt;/span&gt; &lt;span class="nf"&gt;infraestrutura&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Conex&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;SQL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tabelas&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;pass&lt;/span&gt;

    &lt;span class="n"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;enviar_email_confirmacao&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="n"&gt;gica&lt;/span&gt; &lt;span class="n"&gt;de&lt;/span&gt; &lt;span class="n"&gt;comunica&lt;/span&gt;&lt;span class="err"&gt;çã&lt;/span&gt;&lt;span class="nf"&gt;o&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Servidor&lt;/span&gt; &lt;span class="n"&gt;SMTP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Exemplo Solução
&lt;/h2&gt;

&lt;p&gt;Para aplicar o SRP, separamos as tarefas em “especialistas”. Cada classe agora tem apenas uma razão para existir e mudar. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;Pedido&lt;/code&gt; vai conter apenas a lógica de cálculo &lt;code&gt;calcular_total&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;salvar_no_banco&lt;/code&gt; vai ser uma nova classe chamada &lt;code&gt;PedidoRepository&lt;/code&gt;, que vai implementar o &lt;a href="https://www.notion.so/Repository-1b2671b57a3e8165ae03fa63305dccce?pvs=21" rel="noopener noreferrer"&gt;Padrão Repository&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;enviar_email_confirmacao&lt;/code&gt; vai ser um serviço separado apenas por enviar comunicações&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Desse modo, se você decidir trocar o e-mail por uma mensagem no WhatsApp, você altera apenas o serviço respectivo. A regra de cálculo do &lt;code&gt;Pedido&lt;/code&gt; então permanece segura e intocada, como uma peça LEGO independente&lt;/p&gt;

&lt;h2&gt;
  
  
  Exemplo aplicado a contexto: Clean Architecture, Mediator, CQRS e DDD
&lt;/h2&gt;

&lt;p&gt;Veja como o SRP se manifesta em um &lt;strong&gt;CommandHandler&lt;/strong&gt; usando Mediator:&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;// Este Handler tem UMA única razão para mudar: &lt;/span&gt;
&lt;span class="c1"&gt;// Se o fluxo de "Criação de Pedido" for alterado.&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;CriarPedidoHandler&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IRequestHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CriarPedidoCommand&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IPedidoRepository&lt;/span&gt; &lt;span class="n"&gt;_repository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Interface (DIP)&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IMediator&lt;/span&gt; &lt;span class="n"&gt;_mediator&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;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CriarPedidoCommand&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// 1. Regra de Negócio (DDD: Entidade decide se pode ser criada)&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pedido&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;Pedido&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClienteId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&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;// 2. Persistência (Clean Arch: O Handler não sabe se é SQL ou NoSQL)&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_repository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SalvarAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pedido&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// 3. Comunicação (Mediator: Dispara um evento para quem interessar)&lt;/span&gt;
        &lt;span class="c1"&gt;// Isso separa a criação do pedido do envio de e-mail (SRP puro!)&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_mediator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Publish&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;PedidoCriadoEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pedido&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;pedido&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;h1&gt;
  
  
  2. Princípio Aberto/Fechado
&lt;/h1&gt;

&lt;p&gt;Esse é o segunda pilar do SOLID. Sua fundamentação existe para que os softwares criados sejam fáceis de manter e evoluir sem quebrar o que já funciona.&lt;/p&gt;

&lt;p&gt;Certo! Mas o que diabos isso significa?  Os sistemas não são estáticos, eles tendem a evoluír. O cenário comum no mercado, portanto, é: com novas definições de funcionalidades os desenvolvedores geralmente alteram o código-fonte existente, código este, que já foi testado e homologado. Resultando em um sistema difícil de manter e “sustentar”.&lt;/p&gt;

&lt;p&gt;O OCP surge para mitigar esse problema e a definição foi criada por Bertrand Meyer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Entidades de software (classes, módulos, funções, etc.) devem estar abertas para extensão, mas fechadas para modificação."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Aberto pra Extensão:&lt;/strong&gt; Você é deve ser capaz de adicionar novos comportamentos e funcionalidades ao sistema à medida que os requisitos mudam.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fechada para Modificações:&lt;/strong&gt; Ao adicionar essa nova funcionalidade, você não deve alterar o código-fonte existente que já foi estado e está funcionando&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Metáfora da Tomada
&lt;/h1&gt;

&lt;p&gt;Tenho um professor que comparou esse princípio com uma tomada. elétrica de parede.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ela é &lt;strong&gt;fechada pra modificação&lt;/strong&gt;, já que você não precisa quebrar a parede e refazer a fiação elétrica da casa toda vez que compra um novo eletrodoméstico&lt;/li&gt;
&lt;li&gt;Ela é &lt;strong&gt;abertura para extensão&lt;/strong&gt;, você pode instalar uma TV, ventilador ou carregador estendendo a utilidade daquela rede relétrica, apenas plugando algo novo. A interface (os buracos da tomada) permitee isso.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Exemplo prático
&lt;/h1&gt;

&lt;p&gt;Vamos desenvolver um cálculo de Bônus Anual. Imagine uma classe &lt;code&gt;CalculadoraDeBonus&lt;/code&gt;. Inicialmente, a empresa só tem "Desenvolvedores" e "Gerentes". &lt;/p&gt;

&lt;h2&gt;
  
  
  Exemplo Ruim (Violando OCP)
&lt;/h2&gt;

&lt;p&gt;Nesta abordagem comum (mas ruim), usamos um &lt;code&gt;switch&lt;/code&gt; ou &lt;code&gt;if/else&lt;/code&gt; para verificar o cargo. O problema: quero adicionar dois novos cargos, diretor e estagiário. Para isso eu preciso abrir a classe e modificá-la diretamente! Isso viola o OCP&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;CalculadoraDeBonus&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;Calcular&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;cargo&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;salario&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;cargo&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Gerente"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;salario&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;0.2m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cargo&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Desenvolvedor"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;salario&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;0.1m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Se a empresa criar o cargo "Diretor" amanhã, &lt;/span&gt;
        &lt;span class="c1"&gt;// VOU TER QUE ALTERAR ESTE ARQUIVO.&lt;/span&gt;
        &lt;span class="k"&gt;return&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;O Risco:&lt;/strong&gt; Ao editar esse arquivo para adicionar o "Diretor", você pode sem querer apagar uma linha ou mudar a lógica do "Gerente", causando bugs em algo que já estava testado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solução (Aplicando OCP)
&lt;/h2&gt;

&lt;p&gt;Vou trazer duas abordagens para fechar a classe para modificação e abri-las para extensão. Ambas abordagens resolvem o OCP, mas elas comunicam intenções diferentes sobre o seu sistema.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Abordagem com Classe Abstrata&lt;/li&gt;
&lt;li&gt;Abordagem com Interfaces&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Abordagem com Classe Abstrata
&lt;/h2&gt;

&lt;p&gt;Use essa abrodagem quando existe uma relação forte de herança e você quer reaproveitar propriedades ou métodos&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cenário:&lt;/strong&gt; Todo funcionário tem &lt;code&gt;Nome&lt;/code&gt; e &lt;code&gt;Salario&lt;/code&gt; (código compartilhado), mas o cálculo do bônus muda.&lt;/p&gt;

&lt;h3&gt;
  
  
  Contrato
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FuncionarioBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Código compartilhado (Reuso)&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;public&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;Salario&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="c1"&gt;// Obriga as classes filhas a implementarem a lógica específica&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;CalcularBonus&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Método comum que já funciona para todos (não precisa sobrescrever)&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;ObterCracha&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;$"Funcionário: &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;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Aberto para extensões:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Gerente&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FuncionarioBase&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;CalcularBonus&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Salario&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;0.2m&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;Desenvolvedor&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FuncionarioBase&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;CalcularBonus&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Salario&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;0.1m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Uso
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Processar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FuncionarioBase&lt;/span&gt; &lt;span class="n"&gt;funcionario&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="n"&gt;funcionario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CalcularBonus&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Abordagem com Interface
&lt;/h2&gt;

&lt;p&gt;Use esta abordagem quando o foco é o &lt;strong&gt;"O QUE FAZ"&lt;/strong&gt; (Comportamento). Interfaces são contratos puros. Elas não carregam "bagagem" (estado ou variáveis) e permitem maior flexibilidade, pois uma classe pode implementar múltiplas interfaces.&lt;br&gt;
&lt;strong&gt;Cenário:&lt;/strong&gt; Aqui não nos importamos se é um funcionário, um prestador de serviço ou um robô. Só nos importamos se ele tem uma regra de bônus. Isso é frequentemente chamado de &lt;strong&gt;Strategy Pattern&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Contrato
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// --- O Contrato (Interface) ---&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IRegraDeBonus&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;Calcular&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="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BonusParaDesenvolvedor&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IRegraDeBonus&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;Calcular&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;salarioBase&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;0.1m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;

&lt;h3&gt;
  
  
  Aberto para extensões:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// Note que não herdamos de ninguém, apenas assinamos o contrato&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;BonusParaGerente&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IRegraDeBonus&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;Calcular&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;salarioBase&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;0.2m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Uso
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculadoraServico&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Recebemos a INTERFACE. Baixíssimo acoplamento.&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;ExecutarCalculo&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;salario&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IRegraDeBonus&lt;/span&gt; &lt;span class="n"&gt;regra&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;regra&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Calcular&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;salario&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Comparação entre abordagens: Abstract Class vs. Interface
&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;Característica&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Abstract Class&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Interface&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Relacionamento&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;"É um"&lt;/strong&gt; (Hierarquia estrita). Um Gerente &lt;em&gt;é um&lt;/em&gt; Funcionário.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;"Faz isso"&lt;/strong&gt; (Capacidade). Essa classe &lt;em&gt;sabe calcular&lt;/em&gt; bônus.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reuso de Código&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Alto.&lt;/strong&gt; Permite compartilhar propriedades (&lt;code&gt;Nome&lt;/code&gt;, &lt;code&gt;ID&lt;/code&gt;) e métodos concretos.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Baixo/Nenhum.&lt;/strong&gt; Apenas define as assinaturas dos métodos.*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Herança&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Limitada.&lt;/strong&gt; C# só permite herdar de 1 classe. Se usar Abstract, você "gasta" essa cartada.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Múltipla.&lt;/strong&gt; Uma classe pode implementar 5 interfaces diferentes (&lt;code&gt;IBonificavel&lt;/code&gt;, &lt;code&gt;IAutenticavel&lt;/code&gt;, etc).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Acoplamento&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Médio. As filhas dependem da classe pai.&lt;/td&gt;
&lt;td&gt;Baixíssimo. As classes só dependem do contrato.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Quando usar no OCP?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Quando você tem uma família de objetos intimamente relacionados que compartilham estrutura.&lt;/td&gt;
&lt;td&gt;Quando você quer plugar comportamentos diferentes (Strategy Pattern) ou testabilidade máxima (Mocks).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;No desenvolvimento moderno de C# (.NET Core/Dependency Injection), &lt;strong&gt;Interfaces são usadas em 90% dos casos&lt;/strong&gt; para garantir o OCP, pois facilitam muito os testes unitários (Mocking).&lt;/p&gt;
&lt;h1&gt;
  
  
  3. Princípio da Substituição de Liskov
&lt;/h1&gt;

&lt;p&gt;O terceiro princípio é o Liskov Substituition Principle. Ele foi definido por Barbara Liskov em 1987 e, embora que por definição academia pareça ser um “bicho de setes cabeças”, na prática é bem simples e ideal para criar sistemas robustos.&lt;/p&gt;

&lt;p&gt;O princípio estabelece que uma classe derivada deve poder substituir sua classe base sem alterar ou comprometer o comportamento esperado do programa. Em outras palavras, ao herdar a classe &lt;strong&gt;B&lt;/strong&gt; a partir da classe &lt;strong&gt;A&lt;/strong&gt;, o desenvolvedor deve conseguir realizar tudo o que era possível com &lt;strong&gt;A&lt;/strong&gt; utilizando &lt;strong&gt;B&lt;/strong&gt;, mantendo as mesmas garantias de funcionamento e, se necessário, acrescentando novos comportamentos, mas nunca removendo ou quebrando os existentes.&lt;/p&gt;

&lt;p&gt;Para cumprir  o príncpio pense assim: “O filho (classe que herda) deve conseguir fazer tudo que o pai (classe pai) prometeu que faria”. Se o pai diz "eu sei somar dois números", o filho não pode dizer "eu só sei somar se os números forem positivos". Isso seria uma surpresa desagradável para quem usa o código.&lt;/p&gt;
&lt;h2&gt;
  
  
  Analogia com Pássaros
&lt;/h2&gt;

&lt;p&gt;Imagine que você tem um sistema para um zoológico. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Você cria a Entidade &lt;code&gt;Passaro&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Você define que todo &lt;code&gt;Passaro&lt;/code&gt; tem a habilidade de voar.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Até aqui, tudo bem. Aí você cria os tipos específicos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pardal&lt;/strong&gt; (É um Pássaro): Voa? Sim. ✅ (Tudo certo, segue o princípio).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Águia&lt;/strong&gt; (É um Pássaro): Voa? Sim. ✅ (Tudo certo).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agora vem o problema. Você precisa adicionar um &lt;strong&gt;Pinguim&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pinguim&lt;/strong&gt; (É um Pássaro): Voa? &lt;strong&gt;Não.&lt;/strong&gt; ❌&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Onde o princípio quebra?
&lt;/h3&gt;

&lt;p&gt;Se você tem uma parte do seu código que diz: “Pegue todos os pássaros e faça-os voar”, quando chegar a vez do Pinguim o programa vai travar ou dar erro, porque pinguins não voam. Na aplicação promete que &lt;strong&gt;todo&lt;/strong&gt; pássaro voa, mas o pinguim não cumpre essa promessa.&lt;/p&gt;
&lt;h3&gt;
  
  
  Como consertar o exemplo do Pinguim?
&lt;/h3&gt;

&lt;p&gt;Em vez de colocar "Voar" na categoria principal &lt;strong&gt;&lt;code&gt;Passaro&lt;/code&gt;&lt;/strong&gt;, você deve criar uma categoria mais específica ou separar as habilidades:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Classe &lt;strong&gt;`Passaro&lt;/strong&gt;` (Tem bico, bota ovos).&lt;/li&gt;
&lt;li&gt;Classe &lt;strong&gt;&lt;code&gt;PassaroQueVoa&lt;/code&gt;&lt;/strong&gt; (Herda de Pássaro + sabe voar).&lt;/li&gt;
&lt;li&gt;Classe &lt;strong&gt;&lt;code&gt;PassaroQueNada&lt;/code&gt;&lt;/strong&gt; Herda de Pássaro + sabe nadar).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Dessa forma o Pardal entra em &lt;strong&gt;&lt;code&gt;PassaroQueVoa&lt;/code&gt;&lt;/strong&gt; e o Peguim em &lt;strong&gt;&lt;code&gt;PassaroQueNada&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;E o melhor: ninguém promete o que não pode cumprir, e o código não quebra.&lt;/p&gt;
&lt;h1&gt;
  
  
  Exemplo aplicado ao código
&lt;/h1&gt;

&lt;p&gt;Vamos retomar o exemplo acima e desenvolver com o código com C# de duas formas, uma que viola o LSP e outra que não viola.&lt;/p&gt;
&lt;h2&gt;
  
  
  Violação Estrutural
&lt;/h2&gt;

&lt;p&gt;Imagine que você tem uma classe abstrata &lt;code&gt;Passaro&lt;/code&gt;. Em C#, é comum usarmos classes abstratas ou interfaces para definir contratos.&lt;/p&gt;

&lt;p&gt;O exemplo abaixo viola o LSP porque o &lt;code&gt;Pinguim&lt;/code&gt; não pode substituir &lt;code&gt;Passaro&lt;/code&gt; sem causar efeitos colaterais (a exceção).&lt;/p&gt;
&lt;h3&gt;
  
  
  Classe Base
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Passaro&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;Voar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Implementação Concreta
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pardal&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Passaro&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;Voar&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;"Pardal voando alto!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Implementação que viola o LSP
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pinguim&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Passaro&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;Voar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// O compilador obriga a implementar Voar(),&lt;/span&gt;
        &lt;span class="c1"&gt;// mas a lógica não permite. O dev lança uma exceção.&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;NotImplementedException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Pinguins não voam!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  O Jeito Correto
&lt;/h2&gt;

&lt;p&gt;Em C#, a melhor forma de resolver isso é segregando as capacidades através de &lt;strong&gt;Interfaces&lt;/strong&gt;. Nem todo pássaro é um &lt;code&gt;IVoador&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Essa implementação abaixo torna impossível passar um Pinguim para um método que espera &lt;code&gt;IVoador&lt;/code&gt;. O compilador do C# vai te impedir antes mesmo de você rodar o programa.&lt;/p&gt;
&lt;h3&gt;
  
  
  Definição de abstração (interface e classe abstrata)
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Define apenas o que é comum a TODOS&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Ave&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;Comer&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;"Comendo..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Interface (Capacidade) separada&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IVoador&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;Voar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Implementações
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Pardal é uma Ave E sabe voar&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;Pardal&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Ave&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IVoador&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;Voar&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;"Pardal 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="c1"&gt;// Pinguim é apenas uma Ave (não implementa IVoador)&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;Pinguim&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Ave&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Pode ter métodos de nadar aqui&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h1&gt;
  
  
  4. Principio da Segragação de Interface
&lt;/h1&gt;

&lt;p&gt;O ISP afirma que uma interface não deve forçar a classe a implementar métodos que elas não utilizam.  A ideia é quebras grandes interfaces em menores e mais específicas, ou seja, em vez de interfaces gigantes e genéricas (”interfaces gordas”),  devemos ter “interfaces magras”, quebradas e mais específicas.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Clientes não devem ser forçados a depender de métodos que não usam.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pense nisso como um menu de restaurante:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Violação do ISP:&lt;/strong&gt; O restaurante obriga você a comprar o combo com hambúrguer, batata, refrigerante, sorvete e café, mesmo que você só queira o hambúrguer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aplicação do ISP:&lt;/strong&gt; O menu é segregado. Você pode pedir itens individuais ou combos menores que façam sentido para o seu "apetite" (necessidade)&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;
  
  
  Exemplo didático do problema
&lt;/h1&gt;

&lt;p&gt;Imagine que temos a Interface chamada &lt;code&gt;ITrabalhador&lt;/code&gt;, ela possui métodos como &lt;code&gt;Codificar()&lt;/code&gt;, &lt;code&gt;Testar()&lt;/code&gt; e &lt;code&gt;GerenciarProjetos()&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Você vai criar uma classe chamada &lt;code&gt;Programador&lt;/code&gt; que implementa essa interface. Até esse cenário tudo ocorre como o esperado.&lt;/li&gt;
&lt;li&gt;O problema é que se você criar uma classe &lt;code&gt;Gerente&lt;/code&gt;, e implementar a mesma interface ela será obrigada a implementar &lt;code&gt;Codificar()&lt;/code&gt;, mesmo que o gerente não escreva código.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Essa prática cria um acoplamento desnecessário e “polui” o código com métodos vazios ou que lançam exceções como &lt;code&gt;throw new NotImplementedException&lt;/code&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  Exemplo técnico do problema
&lt;/h1&gt;

&lt;p&gt;Vamos retomar o exemplo acima e desenvolver com o código com C# de duas formas, uma que viola o ISP e outra que não viola.&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Violação estrutural
&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;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Uma "Interface Gorda" que tenta fazer tudo&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ITrabalhador&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;Codificar&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;Testar&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;GerenciarProjeto&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;Programador&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ITrabalhador&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;Codificar&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;"Escrevendo código C#..."&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;Testar&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;"Testando bugs..."&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;GerenciarProjeto&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;"Atualizando o JIRA..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
    &lt;span class="c1"&gt;// Ok, talvez o programador faça um pouco de tudo.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Gerente&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ITrabalhador&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;Codificar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Oxente! O Gerente não deveria ser obrigado a ter este método.&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;NotImplementedException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Gerentes não codificam!"&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;Testar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;NotImplementedException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Gerentes não testam!"&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;GerenciarProjeto&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;"Gerenciando o time..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  2. O Jeito Correto
&lt;/h2&gt;

&lt;p&gt;Agora, vamos segregar (separar) as interfaces. Assim, cada classe só assina o "contrato" que realmente consegue cumprir.&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;// Interfaces segregadas e específicas (Interfaces Magras)&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ICodificador&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;Codificar&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;interface&lt;/span&gt; &lt;span class="nc"&gt;ITestador&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;Testar&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;interface&lt;/span&gt; &lt;span class="nc"&gt;IGerente&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;GerenciarProjeto&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// O Programador implementa apenas o que faz sentido para ele&lt;/span&gt;
&lt;span class="c1"&gt;// Ele pode implementar múltiplas interfaces se necessário!&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;Programador&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ICodificador&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ITestador&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;Codificar&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;"Escrevendo código C#..."&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;Testar&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;"Testando bugs..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// O Gerente agora está limpo e focado&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Gerente&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IGerente&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;GerenciarProjeto&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;"Gerenciando o time..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  5. Princípio da Inversão de Dependência
&lt;/h1&gt;

&lt;p&gt;A definição formal do quinto princípio parece um pouco técnica:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Módulos de alto nível não devem depender de módulos de baixo nível. Ambos devem depender de abstraçãoes”.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O conceito de Dependency Inversion (DI) pode deixar desenvolvedores imaturos confuso, isso porque esse conceito geralmente surge de uma necessidade prática e real e as explicações geralmente possuem níveis de abstrações que exiga a compreensão por completo do fluxo de um sistema. Antes de entendermos sobre o assunto temos que entender o que são os módulos de baixo e alto nível de um sistema&lt;/p&gt;

&lt;h1&gt;
  
  
  Módulos de alto e baixo nível
&lt;/h1&gt;

&lt;p&gt;Entender como o sistema de comporta em níveis de módulos e a relação entre eles é de extrema importância para a compreensão do conceito de DI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Alto nível
&lt;/h2&gt;

&lt;p&gt;O foco aqui é a regra de negócio, lógica central, é aqui que existe o “valor” do que é o sistema. Deve ser algo estável e mudar pouco. Por exemplo: calcular o frete de um pedido, gerar uma fatura ou processar um pagamento.&lt;/p&gt;

&lt;h2&gt;
  
  
  Baixo nível
&lt;/h2&gt;

&lt;p&gt;O foco é os detalhes de implementação, mecanismos concretos. São os braços e as pernas que executam o que é demandado pelo módulo de alto nível, mas não definem as regras. Isto posto, está mais sujeito a mudanças e alguns exemplos são: bancos de dados específicos, frameworks de interfaces, etc…&lt;/p&gt;

&lt;h2&gt;
  
  
  Relação entre alto e baixo nível
&lt;/h2&gt;

&lt;p&gt;De forma resumida, podemos dizer que:&lt;/p&gt;

&lt;p&gt;Alto nível = o que o sistema faz (regras de negócio).&lt;/p&gt;

&lt;p&gt;Baixo nível = como o sistema faz (detalhes técnicos).&lt;/p&gt;

&lt;p&gt;Abstração = a ponte que une os dois, mantendo o alto nível protegido dos detalhes.&lt;/p&gt;

&lt;p&gt;Didaticamente explicando o conceito:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O &lt;strong&gt;alto nível&lt;/strong&gt; diz: “Preciso calculas fretes”&lt;/li&gt;
&lt;li&gt;O &lt;strong&gt;baixo nível&lt;/strong&gt; responde: “Ok, sei falar com os Correios e calcular o valor”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se o alto nível depender diretamente dos detalhes (Correios), ele fica preso apenas a um serviço, então se amanhã mudar para FedEx, a alteração deverá ser feita na alta escala do sistema (alto nível), o que é uma péssima prática.&lt;/p&gt;

&lt;p&gt;Para resolver a problemática acima, podemos utilizar a seguinte abordagem:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O alto nível só conhece a regra “alguém que calcule frete”&lt;/li&gt;
&lt;li&gt;O desenvolvedor cria a abstração &lt;code&gt;ICalculadoraFrete&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;O baixo nível (Correios ou FedEx) implementa essa abstração&lt;/li&gt;
&lt;li&gt;O alto nível não precisa mudar quando trocarmos serviço postal&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Inversão de dependência
&lt;/h1&gt;

&lt;p&gt;A ideia central da inversão de dependência é “desamarrar” as regras de negócios a um detalhe específico de implementação. Já que essa prática deixa o sistema rígido e difícil de mudar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Analogia do dia a dia
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sem&lt;/strong&gt; &lt;strong&gt;DI:&lt;/strong&gt; Um carro que só funciona se você abastecer com a gasolina da “Bandeira X”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Com DI:&lt;/strong&gt; O carro depende apenas da abstação (interface) “combustível líquido inflamável”

&lt;ul&gt;
&lt;li&gt;Pode ser gasolina comum, aditivada, etanol ou até biocombustível&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Com base na analogia acima, a gente é capaz de perceber que com a Inversão de dependência o carro não se prende aos detalhe da gasolina (baixo nível), ele só depende da abstração de um combustível &lt;/p&gt;

&lt;h1&gt;
  
  
  Aplicando o princípio da Inversão de Dependência
&lt;/h1&gt;

&lt;p&gt;Para utilizar a inversão de dependência vamos aplicar a Inversão de Controle (IoC) e Injeção de Dependência (DI) &lt;/p&gt;

&lt;h3&gt;
  
  
  1. Criamos uma interface (um contrato)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;INotificacaoService&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui estamos dizendo: "Eu não me importo &lt;em&gt;como&lt;/em&gt; a mensagem será enviada. Só quero que exista alguém capaz de executar o método &lt;code&gt;Enviar()&lt;/code&gt;." Isso é lindo. Porque o PedidoService não quer saber de e-mail, SMS, WhatsApp, sinal de fumaça... ele só quer &lt;em&gt;enviar&lt;/em&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  2. Criamos implementações dessa interface
&lt;/h3&gt;

&lt;p&gt;Enviar por E-mail:&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;EmailService&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;INotificacaoService&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="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;"Enviando Email: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;mensagem&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. PedidoService não se importa mais com o &lt;em&gt;como&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Agora ele só recebe a dependência via construtor:&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;PedidoService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;INotificacaoService&lt;/span&gt; &lt;span class="n"&gt;_notificacaoService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// INJEÇÃO DE DEPENDÊNCIA VIA CONSTRUTOR&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;PedidoService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;INotificacaoService&lt;/span&gt; &lt;span class="n"&gt;notificacaoService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_notificacaoService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;notificacaoService&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;FinalizarPedido&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_notificacaoService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Enviar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Pedido finalizado!"&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;



</description>
      <category>architecture</category>
      <category>codequality</category>
      <category>design</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Deploy: Cenário: Azure App Service + Github + SQL Server</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Thu, 08 Jan 2026 23:07:31 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/deploy-cenario-azure-app-service-github-sql-server-2b0d</link>
      <guid>https://dev.to/yuripeixinho/deploy-cenario-azure-app-service-github-sql-server-2b0d</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Deploy não é um botão. É um &lt;strong&gt;processo consciente&lt;/strong&gt; de levar software para o mundo real. Geralmente quando não temos conhecimento sobre os processos de deploy ficamos com algumas questões pendentes em nossa mente:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Onde o código roda?&lt;/li&gt;
&lt;li&gt;Como ele chega lá?&lt;/li&gt;
&lt;li&gt;Como ele acessa o banco?&lt;/li&gt;
&lt;li&gt;Como configuro sem expor segredo (secret)?&lt;/li&gt;
&lt;li&gt;Como atualizo sem quebrar tudo?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vamos passar por todo esse processo com aplicação em um cenário real.&lt;/p&gt;

&lt;h1&gt;
  
  
  As peças do cenário que vamos montar
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Azure App Service:&lt;/strong&gt; onde a aplicação roda&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Github:&lt;/strong&gt; onde seu código vive&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Github Actions (opcional, mas recomendado)&lt;/strong&gt;: automação de build e deploy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Azure SQL Database (SQL Server):&lt;/strong&gt; onde seus dados ficam
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="nf"&gt;GitHub&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="n"&gt;digo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;↓&lt;/span&gt;
&lt;span class="nf"&gt;Pipeline&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="n"&gt;deploy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;↓&lt;/span&gt;
&lt;span class="n"&gt;Azure&lt;/span&gt; &lt;span class="n"&gt;App&lt;/span&gt; &lt;span class="nf"&gt;Service&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;API&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="n"&gt;App&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;↓&lt;/span&gt;
&lt;span class="n"&gt;Azure&lt;/span&gt; &lt;span class="n"&gt;SQL&lt;/span&gt; &lt;span class="nf"&gt;Database&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dados&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  1. O que é o Azure App Service?
&lt;/h1&gt;

&lt;p&gt;Como já vimos nos tipos de servidores, podemos dizer que o Azure Service é um serviço gerenciado. Isso significa que você:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Não cria servidor&lt;/li&gt;
&lt;li&gt;Não instala Windows/Linux&lt;/li&gt;
&lt;li&gt;Configura IIS, Kestrel, Nginx manualmente&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1.1 App Service
&lt;/h2&gt;

&lt;p&gt;A plataforma Azure cuida de todas essas questões pra você e quando você cria um App Service, você está definindo&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Runtime (ex: .NET 8)&lt;/li&gt;
&lt;li&gt;Plano de hospedagem (CPU / memória / custo)&lt;/li&gt;
&lt;li&gt;Região (onde o servidor fica)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Que resulta em uma URL pública e um ambiente pronto pra a execução do seu código:&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;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//minha-api.azurewebsites.net&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse momento, &lt;strong&gt;não tem código nenhum rodando ainda&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.2 Como o código chega na Azure? (Github Actions)
&lt;/h2&gt;

&lt;p&gt;Após a configuração do Azure App Service ser concluída precisamos efetivamente subir o nosso código de um determinado repositório para o Azure. Em nossa abordagem vamos utilizar o Github Actions e entender o problema que ele resolve.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.1.1 Processo manual
&lt;/h3&gt;

&lt;p&gt;Antes do Github Actions, o deploy normalmente era assim:&lt;/p&gt;

&lt;p&gt;O desenvolvedor faz o seguinte processo:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Compila local&lt;/li&gt;
&lt;li&gt;Publica manualmente&lt;/li&gt;
&lt;li&gt;Sobre arquivo por FTP&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Esse processo gera problemas como inconsistência, erro humano, falta de histórico e deploys imprevisíveis&lt;/p&gt;

&lt;h3&gt;
  
  
  1.1.2 Github Actions
&lt;/h3&gt;

&lt;p&gt;Podemos dizer que o GitHub Actions é um robô configurável que roda dentro do GitHub sempre que algo acontece no repositório.&lt;/p&gt;

&lt;p&gt;Esse “algo” pode ser:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;push&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pull request&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;criação de tag&lt;/li&gt;
&lt;li&gt;horário agendado&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esse robô pode compilar código, rodar testes, gerar build, fazer deploy, enviar notificações, etc. Isso tudo só acontece porque um workflow é configurado.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;1.3 O que é um workflow e o que ele tem a ver com tudo isso?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Um workflow é um arquivo &lt;code&gt;.yml&lt;/code&gt; que diz sugere: “Quando X acontecer, execute Y passos nessa ordem”, então, por exemplo:&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;SE&lt;/span&gt; &lt;span class="n"&gt;algu&lt;/span&gt;&lt;span class="err"&gt;é&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="n"&gt;fizer&lt;/span&gt; &lt;span class="n"&gt;push&lt;/span&gt; &lt;span class="n"&gt;na&lt;/span&gt; &lt;span class="n"&gt;branch&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;
&lt;span class="n"&gt;ENT&lt;/span&gt;&lt;span class="err"&gt;Ã&lt;/span&gt;&lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;compile&lt;/span&gt;
  &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;teste&lt;/span&gt;
  &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;publique&lt;/span&gt;
  &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;deploy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E esse arquivo fica em:&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="n"&gt;github&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;workflows&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;deploy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;yml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse arquivo é código, portanto, o Deploy passa a ser &lt;strong&gt;versionado&lt;/strong&gt;, auditável e repetível.&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Criando o SQL Server no Azure
&lt;/h1&gt;

&lt;p&gt;Ao criar um banco de dados no Azure, você já vai ter backup automático, alta disponibilidade e sem precisar instalar nada.&lt;/p&gt;

&lt;p&gt;Ao final do processo você vai ter o nome do servidor, nome do banco, usuário e senha. Essas informações nunca deve ir no código.&lt;/p&gt;

&lt;p&gt;Quando você cria o &lt;strong&gt;Azure SQL Database&lt;/strong&gt;, o Azure cria duas coisas:&lt;/p&gt;

&lt;h2&gt;
  
  
  2.1 Servidor Lógico (SQL Server)
&lt;/h2&gt;

&lt;p&gt;Não é uma VM (Virtual Machine) e sim um endpoint gerenciado para autenticação e conexões. Esse servidor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pode ter vários bancos&lt;/li&gt;
&lt;li&gt;Centraliza segurança&lt;/li&gt;
&lt;li&gt;Controla firewall&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  No portal do Azure:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Azure SQL → Create&lt;/li&gt;
&lt;li&gt;Você define:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Server name&lt;/strong&gt; → &lt;code&gt;meu-servidor.database.windows.net&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Admin login&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Senha&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  2.2 Banco de dados
&lt;/h2&gt;

&lt;p&gt;Dentro do servidor: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Você cria o banco &lt;code&gt;nomeDoBanco&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Define

&lt;ul&gt;
&lt;li&gt;Camada (Basic / General Purpose / Business Critical)&lt;/li&gt;
&lt;li&gt;DTUs / vCores&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  2.3 Firewall do SQL Server
&lt;/h2&gt;

&lt;p&gt;Por padrão ninguém consegue acessar o banco.&lt;/p&gt;

&lt;p&gt;Você precisa configurar: &lt;strong&gt;Networking → Firewall rules&lt;/strong&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;✔️ Allow Azure services&lt;/li&gt;
&lt;li&gt;✔️ Adicionar IP da sua máquina (para migrations locais)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⚠️ Sem isso:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;App não conecta&lt;/li&gt;
&lt;li&gt;Migration falha&lt;/li&gt;
&lt;li&gt;Erro de timeout&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Em produção real:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ideal é &lt;strong&gt;Private Endpoint&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Mas para início: firewall simples resolve&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  3. Connection String, o elo entre a aplicação e o banco
&lt;/h1&gt;

&lt;p&gt;Essa é uma das partes mais importante de todo deploy. Sem essa conexão, nada conecta com a base de dados.&lt;/p&gt;

&lt;p&gt;Sem ela:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A aplicação sobe ✔️&lt;/li&gt;
&lt;li&gt;O banco existe ✔️&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mas nada se comunica&lt;/strong&gt; ❌&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ou seja: API no ar, mas &lt;strong&gt;toda requisição que depende de dados falha&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3.1 O que você já criou no Azure SQL Database
&lt;/h2&gt;

&lt;p&gt;Ao criar sua base de dados no Azure (SQL Server), você definiu:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Nome do servidor&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nome da base de dados&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Admin Login&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Senha&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tipo de autenticação (SQL Authentication)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Essas informações são a base da sua connection string.&lt;/p&gt;

&lt;h2&gt;
  
  
  3.2 O que é, na prática, uma Connection String?
&lt;/h2&gt;

&lt;p&gt;É um texto que informa à aplicação:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Onde está o banco&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Qual banco acessar&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Como autenticar&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Como se comportar durante a conexão&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Exemplo genérico:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server=...
Database=...
User Id=...
Password=...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3.3 De onde vem o valor da Connection String?
&lt;/h2&gt;

&lt;p&gt;No Azure SQL Database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SQLDatabase
 → Settings
     → Connection strings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Normalmente você verá algo como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server=tcp:meuservidor.database.windows.net,1433;
Initial Catalog=MinhaBase;
PersistSecurityInfo=False;
User ID=adminuser;
Password=********;
MultipleActiveResultSets=False;
Encrypt=True;
TrustServerCertificate=False;
Connection Timeout=30;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Copie exatamente essa string&lt;/strong&gt; e cole no campo &lt;strong&gt;Value&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3.4 Agora vamos ligar &lt;strong&gt;App → Banco&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Essa configuração é feita &lt;strong&gt;diretamente no Azure App Service&lt;/strong&gt;, sem precisar alterar código.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.4.1 Caminho no Azure Portal
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;App Service
 → Settings
 → Configuration
 → Connection strings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa área funciona como um &lt;strong&gt;cofre de segredos&lt;/strong&gt; da aplicação.&lt;/p&gt;

&lt;p&gt;✅ Mais seguro&lt;/p&gt;

&lt;p&gt;✅ Separado do código&lt;/p&gt;

&lt;p&gt;✅ Ideal para ambientes (Dev / Homologação / Produção)&lt;/p&gt;

&lt;h3&gt;
  
  
  3.4.2 Nome da Connection String (Muito Importante)
&lt;/h3&gt;

&lt;p&gt;Se você usa &lt;strong&gt;Entity Framework Core&lt;/strong&gt;, o nome mais comum (e recomendado) é:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DefaultConnection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse nome precisa &lt;strong&gt;bater exatamente&lt;/strong&gt; com o que está no seu &lt;code&gt;Program.cs&lt;/code&gt; ou &lt;code&gt;appsettings.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Exemplo comum no código:&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;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AppDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseSqlServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetConnectionString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DefaultConnection"&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se o nome for diferente no Azure:&lt;/p&gt;

&lt;p&gt;❌ A aplicação sobe&lt;/p&gt;

&lt;p&gt;❌ Mas não encontra o banco&lt;/p&gt;

&lt;p&gt;❌ Erro clássico: &lt;em&gt;The ConnectionString property has not been initialized&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  4. Migrações
&lt;/h1&gt;

&lt;p&gt;Agora vem a parte &lt;strong&gt;mais importante do deploy com banco&lt;/strong&gt;. Vamos separar em três trilhas bem práticas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Migration Manual Local → Azure SQL &lt;/li&gt;
&lt;li&gt;Migration via GithubActions → Azure SQL (Pipeline)&lt;/li&gt;
&lt;li&gt;Migration por script SQL (práticas usadas por empresas)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  4.1. Migration Manual (local → Azure SQL)
&lt;/h2&gt;

&lt;p&gt;Pré-requisitos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Projeto com EF Core&lt;/li&gt;
&lt;li&gt;Migrations já criadas&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Isso não mexe no banco ainda, apenas gera os arquivos C#.&lt;/p&gt;

&lt;h2&gt;
  
  
  4.2. Liberar o acesso ao banco no Azure
&lt;/h2&gt;

&lt;p&gt;Por padrão, o Azure SQL bloqueia tudo e precisamos autorizar nossa máquina local, sem isso nosso sistema dará o erro: Login failed / Timeout expired&lt;/p&gt;

&lt;p&gt;O que isso faz:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Autoriza &lt;strong&gt;sua máquina local&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Permite que o &lt;code&gt;dotnet ef&lt;/code&gt; conecte no banco remoto&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  No Portal Azure:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Azure SQL Server&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Networking&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Firewall rules&lt;/li&gt;
&lt;li&gt;Add your client IPv4 address&lt;/li&gt;
&lt;li&gt;Save&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  4.3. Garantir que sua aplicação aponta para o Azure
&lt;/h2&gt;

&lt;p&gt;Garante que seu arquivo &lt;code&gt;appsettings.Development.json&lt;/code&gt; está apontando para o SQL Server no azure.&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="s"&gt;"ConnectionStrings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"DefaultConnection"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Server=tcp:meuservidor.database.windows.net;..."&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4.4. Executar a migration
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;dotnet&lt;/span&gt; &lt;span class="n"&gt;ef&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  O que acontece por trás:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;EF abre conexão com o Azure SQL&lt;/li&gt;
&lt;li&gt;Verifica se existe a tabela:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;__EFMigrationsHistory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Se &lt;strong&gt;não existir&lt;/strong&gt; → cria&lt;/li&gt;
&lt;li&gt;Se existir → lê quais migrations já rodaram&lt;/li&gt;
&lt;li&gt;Compara:

&lt;ul&gt;
&lt;li&gt;Migrations no código&lt;/li&gt;
&lt;li&gt;Migrations no banco&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Executa &lt;strong&gt;somente as pendentes&lt;/strong&gt;
&lt;/li&gt;

&lt;li&gt;Registra a versão aplicada&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>azure</category>
      <category>devops</category>
      <category>github</category>
      <category>sql</category>
    </item>
    <item>
      <title>Introdução ao Deploy</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Thu, 08 Jan 2026 23:06:12 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/introducao-ao-deploy-2a07</link>
      <guid>https://dev.to/yuripeixinho/introducao-ao-deploy-2a07</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Quando estamos desenvolvendo uma aplicação escrevemos o código em nosso computador. Esse código depois de escrito só consegue ser rodado em ambiente local e a aplicaçõo só pode ser acessada pelo seu próprio dispositivo.&lt;/p&gt;

&lt;p&gt;Mas como faz pra esse código rodar 24h por dia e acessível para outras pessoas? O deploy é a resposta. É o processo de “pegar” um software e colocá-lo em um ambiente que execute ele continuamente de forma estável, segura e acessível.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que precisa pra rodar o software?
&lt;/h2&gt;

&lt;p&gt;Todo sistema em produção precisa de 4 coisas básicas.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Código (sua aplicação)&lt;/li&gt;
&lt;li&gt;Máquina pra executar o código&lt;/li&gt;
&lt;li&gt;Dados (banco de dados, arquivos)&lt;/li&gt;
&lt;li&gt;Rede (internet)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Mais afinal, onde onde o deploy acontece?
&lt;/h2&gt;

&lt;p&gt;O Deploy acontece no servidor. O servidor é um computador ligado 24h, com CPU, memória, disco, sistema operacional, internet, etc. Uma observação importante é que você pode usar seu computador como um servidor (mas não é recomendado)&lt;/p&gt;

&lt;h1&gt;
  
  
  Tipos de servidores (do mais simples ao moderno)
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Servidor Físico
&lt;/h3&gt;

&lt;p&gt;É uma máquina real em um datacenter, você cuida de tudo. Geralmente é caro e complexo&lt;/p&gt;

&lt;h3&gt;
  
  
  Máquina Virtual (VM)
&lt;/h3&gt;

&lt;p&gt;Um servidor virtual dentro de outro servidor, você controla o SO (Sistema Operacional). &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Azure VM&lt;/li&gt;
&lt;li&gt;EC2 (AWS)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Plataforma Gerenciada (PaaS)
&lt;/h3&gt;

&lt;p&gt;Você só cuida do código e a nuvem cuida do servidor&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Azure App Service&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Containers (Docker)
&lt;/h3&gt;

&lt;p&gt;Seu aplicativo é empacotado com tudo que precisa e roda igual em qualquer lugar&lt;/p&gt;

&lt;h3&gt;
  
  
  Orquestração (Kubernates)
&lt;/h3&gt;

&lt;p&gt;Gerencia vários containers, alta escala e complexidade&lt;/p&gt;

&lt;h1&gt;
  
  
  O que acontece durante um deploy?
&lt;/h1&gt;

&lt;p&gt;Agora que sabemos o que é o deploy e quais são os tipos de servidores, vamos imaginar um deploy manual?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Desenvolvedor escreve o código&lt;/li&gt;
&lt;li&gt;Compila o código &lt;code&gt;(build)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Copia os arquivos para o servidor&lt;/li&gt;
&lt;li&gt;Configura variáveis de ambiente (ex: string de conexão, senhas de integrações, etc.).&lt;/li&gt;
&lt;li&gt;Inicia a aplicação&lt;/li&gt;
&lt;li&gt;Abre porta de rede&lt;/li&gt;
&lt;li&gt;Aponta um domínio &lt;/li&gt;
&lt;li&gt;Monitora erros&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>beginners</category>
      <category>devops</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Camadas de Validações de um Sistema backend</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Mon, 10 Nov 2025 23:46:55 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/camadas-de-validacoes-de-um-sistema-backend-hdg</link>
      <guid>https://dev.to/yuripeixinho/camadas-de-validacoes-de-um-sistema-backend-hdg</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Como você já deve saber, sistemas geralmente têm entrada e saída de dados (Input/Output).  Esses dados de entradas são armazenados em alguma base de dados existente.  Portanto, esses dados precisam ser controlados e validados para manter a consistência de sua aplicação.&lt;/p&gt;

&lt;p&gt;Por exemplo, se temos um campo de CPF (11 dígitos fixos) não podemos deixar o usuário inserir em nossa base de dados um CPF que contém 8 ou 15 dígitos ou que ele consiga criar dois CPFs iguais.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tipos de validações
&lt;/h2&gt;

&lt;p&gt;No backend existem três níveis principais de validação e é importante entender a diferença entre os conceitos. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validação de Entrada (Camada de API/Controller)&lt;/li&gt;
&lt;li&gt;Validação de Negócio (Camada de Aplicação /Domain Service)\&lt;/li&gt;
&lt;li&gt;Validação de Consistência/Infraestrutura&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Validação de Entrada (Camadas de API/Controller)
&lt;/h2&gt;

&lt;p&gt;Ocorre logo no início da aplicação (entrada de dados) e o objetivo é garantir que os dados cheguem válidos na camada de aplicação. É nessa camada que será realizado a validação posterior, de negócios.  É aqui que o sistema valida a estrutura e o formato, mas nunca a lógica do negócio.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo:&lt;/strong&gt; verificar se o CPF tem 11 dígitos, mas não se ele existe no banco.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validação de Negócio (Camada da Aplicação/Domain Service)
&lt;/h2&gt;

&lt;p&gt;Essa camada é posterior a validação de entrada. Caso todas as informações fornecidas no input da aplicação esteja correta, passamos para a fase da validação de negócio, seu objetivo é garantir que a ação faça sentido pra o sistema.&lt;/p&gt;

&lt;p&gt;Existem dois níveis de validação de regra de negócio.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Regras de Entidades (invariantes)&lt;/li&gt;
&lt;li&gt;Regras de negócio entre entidades (Serviço de Domínio)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Regras de Entidades (invariantes)
&lt;/h3&gt;

&lt;p&gt;São regras auto-suficientes que pertencem a uma única entidade e vão dentro da própria classe. As invariantes servem pra garantir consistência do domínio.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplos:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Não permitir criar um boleto para um cliente bloqueado.&lt;/li&gt;
&lt;li&gt;Impedir alteração de uma remessa já enviada.&lt;/li&gt;
&lt;li&gt;Garantir unicidade de um registro lógico (ex: CPF de uma pessoa).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Remessa&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;Guid&lt;/span&gt; &lt;span class="n"&gt;RemessaId&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;BancoId&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Header&lt;/span&gt; &lt;span class="n"&gt;Header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;ArquivoTXT&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Remessa&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;bancoId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Header&lt;/span&gt; &lt;span class="n"&gt;header&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;arquivoTXT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;BancoId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bancoId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Header&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;ArquivoTXT&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arquivoTXT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="nf"&gt;ValidarDominio&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;ValidarDominio&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;Header&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DomainException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Header da remessa não pode ser nulo."&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="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ArquivoTXT&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DomainException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Arquivo TXT não pode estar vazio."&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;Header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Agencia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DomainException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A agência deve ter 4 dígitos."&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 que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ValidarDominio()&lt;/code&gt; garante que &lt;strong&gt;nenhum objeto &lt;code&gt;Remessa&lt;/code&gt; inválido&lt;/strong&gt; possa existir.&lt;/li&gt;
&lt;li&gt;O construtor força a validação logo na criação.&lt;/li&gt;
&lt;li&gt;As propriedades têm &lt;code&gt;private set&lt;/code&gt;, ou seja, ninguém de fora pode alterar o estado diretamente.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E você pode criar uma &lt;code&gt;DomainException&lt;/code&gt; personalizada (mais elegante do que &lt;code&gt;ValidationException&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;DomainException&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Exception&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;DomainException&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;message&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;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Regras de negócios entre Entidades
&lt;/h3&gt;

&lt;p&gt;Essa camada geralmente valida as relações entre entidades, processos e cenário do negócio. Ele é o ponto que entende o contexto e orquestra o uso correto das entidades. &lt;/p&gt;

&lt;p&gt;Essa validação não valida formatos ou invariantes. Ele valida cenários de negócios como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Um cliente não pode ter duas assinaturas ativas”&lt;/li&gt;
&lt;li&gt;“Não é possível emitir uma fatura para um pedido cancelado”&lt;/li&gt;
&lt;li&gt;“O banco informado precisa existir e estar ativo”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Percebe que são regras contextuais e relacionais e não estruturais?&lt;/p&gt;

&lt;p&gt;Em qua fluxo de processo ela se encaixa? Ela vive entre o application Service e o Domain, e geralmente é acionada logo depois que os dados foram validados e antes de criar ou persistir entidades.&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;Controller&lt;/span&gt;  
  &lt;span class="err"&gt;⇣&lt;/span&gt;  
&lt;span class="n"&gt;DTO&lt;/span&gt; &lt;span class="nf"&gt;Validation&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FluentValidation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Valida&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;de&lt;/span&gt; &lt;span class="n"&gt;formato&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="err"&gt;⇣&lt;/span&gt;  
&lt;span class="n"&gt;Application&lt;/span&gt; &lt;span class="n"&gt;Service&lt;/span&gt;  
  &lt;span class="err"&gt;⇣&lt;/span&gt;  
&lt;span class="n"&gt;Business&lt;/span&gt; &lt;span class="nf"&gt;Validation&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;processo&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="n"&gt;contexto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="err"&gt;É&lt;/span&gt; &lt;span class="n"&gt;aqui&lt;/span&gt; &lt;span class="n"&gt;que&lt;/span&gt; &lt;span class="n"&gt;entra&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;
  &lt;span class="err"&gt;⇣&lt;/span&gt;  
&lt;span class="n"&gt;Domain&lt;/span&gt; &lt;span class="nf"&gt;Validation&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;invariantes&lt;/span&gt; &lt;span class="n"&gt;da&lt;/span&gt; &lt;span class="n"&gt;entidade&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
  &lt;span class="err"&gt;⇣&lt;/span&gt;  
&lt;span class="n"&gt;Repository&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="n"&gt;Persist&lt;/span&gt;&lt;span class="err"&gt;ê&lt;/span&gt;&lt;span class="n"&gt;ncia&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Normalmente essa etapa de validação se localiza den tro de &lt;code&gt;Application:&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="n"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;Validation&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;DTO&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;                &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;FluentValidation&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;Business&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;           &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Regras&lt;/span&gt; &lt;span class="n"&gt;contextuais&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="n"&gt;Domain&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;             &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;opcional&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;regras&lt;/span&gt; &lt;span class="n"&gt;complexas&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="n"&gt;dom&lt;/span&gt;&lt;span class="err"&gt;í&lt;/span&gt;&lt;span class="n"&gt;nio&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa camada de validação geralmente utiliza repositórios, serviços de domínios e contexto de processos. Isto é:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Repositório:&lt;/strong&gt; verificar estados do sistema (se já exist algo no banco)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Serviços de Domínio:&lt;/strong&gt; se a regra envolve lógica consolidada, por exemplo: verificar limite de crédito, calcular juros, validar estoque&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contexto de Processo:&lt;/strong&gt; estado do sistema e coerência entre entidades, exemplo:  impedir fatura de pedido cancelado, proibir duplicidade de remessa.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Validação de Consistência/Infraestrutura
&lt;/h2&gt;

&lt;p&gt;Essa é a última etapa de validação e a mais crucial. O objetivo é proteger o sistema e o banco de dados de inconsistências estruturais. Ocorre na camada de repository e banco de dados.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplos:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chaves únicas (&lt;code&gt;UNIQUE&lt;/code&gt;, &lt;code&gt;PRIMARY KEY&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Relacionamentos (&lt;code&gt;FOREIGN KEY&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Restrições de tipo (&lt;code&gt;CHECK&lt;/code&gt;, &lt;code&gt;NOT NULL&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>backend</category>
      <category>braziliandevs</category>
    </item>
  </channel>
</rss>
