<?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: Victor Lis Bronzo</title>
    <description>The latest articles on DEV Community by Victor Lis Bronzo (@victorlisbronzo).</description>
    <link>https://dev.to/victorlisbronzo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2122308%2F5ced4a57-e3a5-40fa-90a2-45108b8f489a.jpeg</url>
      <title>DEV Community: Victor Lis Bronzo</title>
      <link>https://dev.to/victorlisbronzo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/victorlisbronzo"/>
    <language>en</language>
    <item>
      <title>From "Merge is Deploy" to Release Engineering with GitHub Actions</title>
      <dc:creator>Victor Lis Bronzo</dc:creator>
      <pubDate>Tue, 25 Aug 2026 15:30:31 +0000</pubDate>
      <link>https://dev.to/victorlisbronzo/from-merge-is-deploy-to-release-engineering-with-github-actions-3h19</link>
      <guid>https://dev.to/victorlisbronzo/from-merge-is-deploy-to-release-engineering-with-github-actions-3h19</guid>
      <description>&lt;p&gt;Have you ever stopped to think about the risk of having a pipeline where any merge into the main branch deploys straight to production without a single safety gate?&lt;/p&gt;

&lt;p&gt;For a long time, our workflow here was that classic setup almost every developer has used at some point: merge on main triggering an SSH script with git pull and pm2 restart&lt;/p&gt;

&lt;p&gt;It worked for day-to-day tasks, but it gave a false sense of stability lol&lt;/p&gt;

&lt;p&gt;The reality check hit when I found a critical blind spot in the automation: remote SSH scripts were running without strict error handling. In other words, if a git pull caused a conflict or a database migration failed halfway through, the script simply ignored the failure, ran to the end, and GitHub Actions marked the pipeline as green&lt;/p&gt;

&lt;p&gt;The absolute worst-case scenario for monitoring: the pipeline reported that everything went smoothly, while production was already completely down&lt;/p&gt;

&lt;p&gt;On top of that, the execution order was inverted: database migrations were running before the application build. If TypeScript threw a type error right after, the database schema had already advanced while the new code never booted. And since Prisma has no native down migrations, rolling back meant a high-risk manual intervention&lt;/p&gt;

&lt;p&gt;I decided to stop everything and redesign our delivery pipeline from scratch, starting from one clear premise: a tag is a release, a merge is not&lt;/p&gt;

&lt;p&gt;Today, nothing touches the production server without an annotated SemVer tag, going through 6 tightly coupled stages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Strict tag validation: only accepts annotated tags matching vX.Y.Z, ensuring author, timestamp, and audit trail for every single release&lt;/li&gt;
&lt;li&gt;Quality gates across PR and Release: automated tests with Vitest, strict typechecking, builds, and migration validation against a clean database via workflow_call&lt;/li&gt;
&lt;li&gt;Decoupled backups: an independent daily scheduled routine combined with a mandatory safety snapshot right before touching production&lt;/li&gt;
&lt;li&gt;Real migration dry-run: the most valuable gate, where the pipeline restores the latest production dump into an ephemeral scratch database directly inside the VPS, times the migration run, and checks for schema drift before touching the live database&lt;/li&gt;
&lt;li&gt;Deterministic deploy: direct checkout on the immutable tag ref, building before running migrations, and concurrency locks to eliminate simultaneous deploy races&lt;/li&gt;
&lt;li&gt;Smoke tests: active HTTP health checks and PM2 process scans to verify no service is looping in an error state&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The operational impact has been huge: we gained real predictability on migrations, complete traceability for every version, and the confidence that a green pipeline actually means a healthy system in production&lt;/p&gt;

&lt;p&gt;For anyone also managing Node and TypeScript applications on VPS or dedicated servers who wants to eliminate blind deploys, I packaged this entire architecture into an open and modular GitHub Actions template&lt;/p&gt;

&lt;p&gt;I made the repository public for anyone who wants to use it as a foundation: &lt;a href="https://github.com/victor-lis-bronzo/tag-release-template" rel="noopener noreferrer"&gt;https://github.com/victor-lis-bronzo/tag-release-template&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How do you usually handle deployment gates and database migrations in your stack?&lt;/p&gt;

</description>
      <category>devops</category>
      <category>softwareengineering</category>
      <category>githubactions</category>
      <category>security</category>
    </item>
    <item>
      <title>De "Merge é Deploy" para Release Engineering com GitHub Actions</title>
      <dc:creator>Victor Lis Bronzo</dc:creator>
      <pubDate>Tue, 25 Aug 2026 15:09:20 +0000</pubDate>
      <link>https://dev.to/victorlisbronzo/de-merge-e-deploy-para-release-engineering-com-github-actions-1a8h</link>
      <guid>https://dev.to/victorlisbronzo/de-merge-e-deploy-para-release-engineering-com-github-actions-1a8h</guid>
      <description>&lt;p&gt;Você já parou pra pensar no risco de manter uma esteira onde qualquer merge na branch principal vai direto pra produção sem nenhum gate de segurança?&lt;/p&gt;

&lt;p&gt;Por muito tempo, o nosso fluxo aqui era aquele clássico script que quase todo mundo já usou na vida: merge na main disparando SSH com git pull e pm2 restart&lt;/p&gt;

&lt;p&gt;Funcionava no dia a dia, mas era aquela falsa sensação de estabilidade kkkk&lt;/p&gt;

&lt;p&gt;A ficha caiu de verdade quando encontrei um ponto cego crítico na automação: os scripts remotos rodavam sem tratamento estrito de erro. Ou seja, se um git pull gerasse conflito ou uma migração de banco falhasse no meio do processo, o script ignorava o erro, executava até o final e o GitHub Actions marcava o pipeline como sucesso&lt;/p&gt;

&lt;p&gt;O pior cenário para quem monitora: a esteira reportava que tudo tinha corrido bem, enquanto a aplicação em produção já estava fora do ar&lt;/p&gt;

&lt;p&gt;Além disso, a ordem de execução estava invertida: a migração de banco rodava antes do build da aplicação. Se o TypeScript acusasse um erro de tipagem logo depois, o banco já tinha sido alterado e o código novo nem subia. Como o Prisma não possui down migrations nativas, reverter o estado virava uma intervenção manual de alto risco&lt;/p&gt;

&lt;p&gt;Decidi parar e redesenhar toda a nossa arquitetura de entrega do zero, partindo de uma premissa clara: tag é release, merge não é&lt;/p&gt;

&lt;p&gt;Hoje, nada toca o servidor sem uma tag SemVer anotada, atravessando 6 estágios encadeados:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Validação estrita da tag: só aceita tag anotada no padrão vX.Y.Z, garantindo autor, data e o registro auditável de cada release&lt;/li&gt;
&lt;li&gt;Gates de qualidade em PR e Release: testes automatizados com Vitest, typecheck rigoroso, build e validação de migrações em banco limpo via workflow_call&lt;/li&gt;
&lt;li&gt;Backup desacoplado: rotina diária agendada somada a um snapshot obrigatório antes de qualquer alteração de infraestrutura&lt;/li&gt;
&lt;li&gt;Ensaio real de migração: o gate de maior valor, onde o pipeline restaura o dump de produção num banco descartável dentro da própria VPS, executa a migração cronometrada e checa drift de schema antes de tocar a base oficial&lt;/li&gt;
&lt;li&gt;Deploy determinístico: checkout direto na tag imutável, build antes da migração e trava de concorrência pra evitar deploys simultâneos&lt;/li&gt;
&lt;li&gt;Smoke tests: validação ativa das portas HTTP e varredura de processos no PM2 pra garantir que nada entrou em loop de erro&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O impacto dessa mudança na operação é brutal: conquistamos previsibilidade real nas migrações, rastreabilidade de cada versão e a certeza de que pipeline verde significa sistema íntegro no ar&lt;/p&gt;

&lt;p&gt;Pra quem também gerencia aplicações Node e TypeScript em VPS ou servidores dedicados e quer sair do deploy cego, estruturei toda essa arquitetura em um template modular de GitHub Actions&lt;/p&gt;

&lt;p&gt;Deixei o repositório aberto pra quem quiser usar de base nos seus projetos: &lt;a href="https://github.com/victor-lis-bronzo/tag-release-template" rel="noopener noreferrer"&gt;https://github.com/victor-lis-bronzo/tag-release-template&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como vocês costumam desenhar os gates de deploy e migração de banco por aí?&lt;/p&gt;

</description>
      <category>performance</category>
      <category>security</category>
      <category>development</category>
      <category>productivity</category>
    </item>
    <item>
      <title>DEPENDENCY INVERSION PRINCIPLE</title>
      <dc:creator>Victor Lis Bronzo</dc:creator>
      <pubDate>Thu, 20 Aug 2026 13:17:44 +0000</pubDate>
      <link>https://dev.to/victorlisbronzo/dependency-inversion-principle-5a99</link>
      <guid>https://dev.to/victorlisbronzo/dependency-inversion-principle-5a99</guid>
      <description>&lt;p&gt;High-level modules should not depend on low-level modules. Both should depend on abstractions (interfaces).&lt;/p&gt;

&lt;p&gt;In practice, your business rule shouldn't know if you use MySQL, Stripe, or AWS. It should depend only on a contract (Interface) that says WHAT needs to be done, and not HOW it will be done.&lt;/p&gt;




&lt;h2&gt;
  
  
  RIGID IMPLEMENTATION
&lt;/h2&gt;

&lt;p&gt;The most common mistake on a daily basis is calling a &lt;code&gt;new ExternalTool()&lt;/code&gt; directly inside your use case.&lt;/p&gt;

&lt;p&gt;When you do this, your code depends on the tool.&lt;/p&gt;

&lt;p&gt;If the tool is discontinued or the API changes, you will have to open the "heart" of your system to fix it.&lt;/p&gt;




&lt;h2&gt;
  
  
  A BAD EXAMPLE
&lt;/h2&gt;

&lt;p&gt;The business class is tightly coupled to the email provider SendGrid. This is a bad practice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SendGridProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sendgrid-sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// BAD: The service instantiates the tool directly.&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RegisterUserUseCase&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;mailProvider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SendGridProvider&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Tight coupling!&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mailProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SendGridProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;API_KEY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...complex business logic...&lt;/span&gt;

    &lt;span class="c1"&gt;// If SendGrid changes or goes down, this class breaks.&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mailProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Welcome!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  TURNING THE TABLES
&lt;/h2&gt;

&lt;p&gt;The solution is not to depend on the concrete class &lt;code&gt;SendGridProvider&lt;/code&gt;, but rather to create a generic interface within our own domain.&lt;/p&gt;

&lt;p&gt;Our service now receives this dependency ready via the constructor (Dependency Injection).&lt;/p&gt;

&lt;p&gt;The most interesting part is that our application doesn't need to know exactly who is under the hood, whether it's Resend, EmailJS, or another, it just follows the template.&lt;/p&gt;




&lt;h2&gt;
  
  
  A GOOD EXAMPLE
&lt;/h2&gt;

&lt;p&gt;The service now depends only on the contract. The infrastructure must obey.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// GOOD: The contract belongs to OUR application.&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IMailProvider&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RegisterUserUseCase&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// We receive the abstraction from the outside (Dependency Injection)&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;mailProvider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IMailProvider&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;async&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...complex business logic...&lt;/span&gt;

    &lt;span class="c1"&gt;// The service has no idea which tool is sending it&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mailProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Welcome!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  THE POWER OF INVERSION
&lt;/h2&gt;

&lt;p&gt;The biggest advantage of DIP is Modularity.&lt;/p&gt;

&lt;p&gt;If tomorrow your client asks to swap SendGrid for AWS SES, you just create a new implementation of the interface. The &lt;code&gt;RegisterUserUseCase&lt;/code&gt; class suffers no changes.&lt;/p&gt;

&lt;p&gt;Besides that, Unit Tests become absurdly easier, because you can inject a fake email Mock without needing to trigger real emails.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;My Links&lt;/strong&gt;&lt;br&gt;
Github: &lt;a href="https://github.com/victor-lis-bronzo" rel="noopener noreferrer"&gt;victor-lis-bronzo&lt;/a&gt;&lt;br&gt;
Linkedin: &lt;a href="https://www.linkedin.com/in/victor-lis-bronzo" rel="noopener noreferrer"&gt;victor-lis-bronzo&lt;/a&gt;&lt;br&gt;
Portfolio: &lt;a href="https://portfolio.victorlisbronzo.me" rel="noopener noreferrer"&gt;portfolio.victorlisbronzo.me&lt;/a&gt;&lt;br&gt;
Coolest Portfolio: &lt;a href="https://victorlisbronzo.me" rel="noopener noreferrer"&gt;victorlisbronzo.me&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Leave your reaction ❤️&lt;/strong&gt;&lt;br&gt;
Were you already applying Dependency Injection before knowing it was the basis of DIP?&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>software</category>
      <category>softwareengineering</category>
      <category>typescript</category>
    </item>
    <item>
      <title>PRINCÍPIO DA INVERSÃO DE DEPENDÊNCIA</title>
      <dc:creator>Victor Lis Bronzo</dc:creator>
      <pubDate>Thu, 20 Aug 2026 13:11:26 +0000</pubDate>
      <link>https://dev.to/victorlisbronzo/principio-da-inversao-de-dependencia-1n86</link>
      <guid>https://dev.to/victorlisbronzo/principio-da-inversao-de-dependencia-1n86</guid>
      <description>&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ções (interfaces).&lt;/p&gt;

&lt;p&gt;Na prática, a sua regra de negócio não deve saber se você usa MySQL, Stripe ou AWS. Ela deve depender apenas de um contrato (Interface) que diz O QUE precisa ser feito, e não COMO será feito.&lt;/p&gt;




&lt;h2&gt;
  
  
  IMPLEMENTAÇÃO ENGESSADA
&lt;/h2&gt;

&lt;p&gt;O erro mais comum no dia a dia é dar um &lt;code&gt;new FerramentaExterna()&lt;/code&gt; direto dentro do seu caso de uso.&lt;/p&gt;

&lt;p&gt;Quando você faz isso, seu código depende da ferramenta.&lt;/p&gt;

&lt;p&gt;Se a ferramenta for descontinuada ou a API mudar, você terá que abrir o "coração" do seu sistema para consertar.&lt;/p&gt;




&lt;h2&gt;
  
  
  UM MAU EXEMPLO
&lt;/h2&gt;

&lt;p&gt;A classe de negócio fortemente acoplada ao provedor de e-mail SendGrid. Isso é uma má prática.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo de Código:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SendGridProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sendgrid-sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// RUIM: O serviço instancia a ferramenta diretamente.&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RegisterUserUseCase&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;mailProvider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SendGridProvider&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Forte acoplamento!&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mailProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SendGridProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;API_KEY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...lógica complexa de negócio...&lt;/span&gt;

    &lt;span class="c1"&gt;// Se o SendGrid mudar ou cair, essa classe quebra.&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mailProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bem-vindo!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  INVERTENDO O JOGO
&lt;/h2&gt;

&lt;p&gt;A solução é não depender da classe concreta &lt;code&gt;SendGridProvider&lt;/code&gt;, mas sim criar uma interface genérica dentro do nosso próprio domínio.&lt;/p&gt;

&lt;p&gt;O nosso serviço passa a receber essa dependência pronta pelo construtor (Injeção de Dependência).&lt;/p&gt;

&lt;p&gt;A parte mais interessante é que nossa aplicação não precisa saber exatamente quem está por baixo dos panos, seja Resend, EmailJS ou outro, ela apenas segue o molde.&lt;/p&gt;




&lt;h2&gt;
  
  
  UM BOM EXEMPLO
&lt;/h2&gt;

&lt;p&gt;O serviço agora depende apenas do contrato. A infraestrutura que obedeça.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo de Código:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// BOM: O contrato pertence à NOSSA aplicação.&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IMailProvider&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RegisterUserUseCase&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Recebemos a abstração de fora (Injeção de Dependência)&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;mailProvider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IMailProvider&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;async&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...lógica complexa de negócio...&lt;/span&gt;

    &lt;span class="c1"&gt;// O serviço não faz ideia de qual ferramenta está enviando&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mailProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bem-vindo!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  O PODER DA INVERSÃO
&lt;/h2&gt;

&lt;p&gt;A maior vantagem do DIP é a Modularidade.&lt;/p&gt;

&lt;p&gt;Se amanhã o seu cliente pedir para trocar o SendGrid pela AWS SES, você só cria uma nova implementação da interface. A classe &lt;code&gt;RegisterUserUseCase&lt;/code&gt; não sofre nenhuma alteração.&lt;/p&gt;

&lt;p&gt;Além disso, os Testes Unitários ficam absurdamente mais fáceis, pois você pode injetar um Mock de e-mail falso sem precisar fazer disparos reais.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Meus Links&lt;/strong&gt;&lt;br&gt;
Github: &lt;a href="https://github.com/victor-lis-bronzo" rel="noopener noreferrer"&gt;victor-lis-bronzo&lt;/a&gt;&lt;br&gt;
Linkedin: &lt;a href="https://www.linkedin.com/in/victor-lis-bronzo" rel="noopener noreferrer"&gt;victor-lis-bronzo&lt;/a&gt;&lt;br&gt;
Portfólio: &lt;a href="https://portfolio.victorlisbronzo.me" rel="noopener noreferrer"&gt;portfolio.victorlisbronzo.me&lt;/a&gt;&lt;br&gt;
Portfólio mais legal: &lt;a href="https://victorlisbronzo.me" rel="noopener noreferrer"&gt;victorlisbronzo.me&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Deixe sua reação ❤️&lt;/strong&gt;&lt;br&gt;
Você já aplicava Injeção de Dependência antes de saber que isso era a base do DIP?&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>backend</category>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>INTERFACE SEGREGATION PRINCIPLE</title>
      <dc:creator>Victor Lis Bronzo</dc:creator>
      <pubDate>Thu, 20 Aug 2026 13:03:54 +0000</pubDate>
      <link>https://dev.to/victorlisbronzo/interface-segregation-principle-1l0m</link>
      <guid>https://dev.to/victorlisbronzo/interface-segregation-principle-1l0m</guid>
      <description>&lt;p&gt;No class should be dependent on methods it doesn't need.&lt;/p&gt;

&lt;p&gt;An example would be a "Machine" interface that forces the &lt;code&gt;print()&lt;/code&gt;, &lt;code&gt;scan()&lt;/code&gt;, and &lt;code&gt;fax()&lt;/code&gt; methods. Not every machine has these 3 methods.&lt;/p&gt;

&lt;p&gt;So we create the &lt;code&gt;IPrinter&lt;/code&gt;, &lt;code&gt;IScanner&lt;/code&gt;, and &lt;code&gt;IFax&lt;/code&gt; interfaces. Now a machine signs only the contracts it actually needs and fulfills only those.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Example (Optional - Illustrating the text):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ Anti-pattern: Generic interface forcing unused methods&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IMachine&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;fax&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ SOLID: Segregated and specific interfaces&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IPrinter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IScanner&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IFax&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;fax&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  THE DEFINITION
&lt;/h2&gt;

&lt;p&gt;In practice, we can understand ISP as the concept that a class should never depend on methods it doesn't use.&lt;/p&gt;

&lt;p&gt;The interface must be reusable in several cases, so a rigid interface with excessive methods hinders this process.&lt;/p&gt;

&lt;p&gt;When a class signs a giant contract, it is forced to implement methods that make no sense for its context, polluting the code and generating unnecessary coupling.&lt;/p&gt;




&lt;h2&gt;
  
  
  A BAD EXAMPLE
&lt;/h2&gt;

&lt;p&gt;Context: A blog system where every user signs the same contract.&lt;/p&gt;

&lt;p&gt;Here we violate some of the concepts I mentioned.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// BAD: Fat interface. Forces unnecessary behaviors.&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IUserActions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;readPost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;writePost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;banUser&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// A regular user shouldn't see this!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StandardUser&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IUserActions&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;readPost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Reading...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;writePost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Writing...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// ERROR: The regular user is forced to have this method&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;banUser&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Access Denied: You are not an administrator.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  DIVIDE AND CONQUER
&lt;/h2&gt;

&lt;p&gt;The solution from the point of view of ISP is clear: break this huge interface into small, well-scoped contracts.&lt;/p&gt;

&lt;p&gt;When more than one contract is needed, a new contract can be built with that specific combination, or the subscriber itself can assume more than one contract at a time (depending on the language).&lt;/p&gt;




&lt;h2&gt;
  
  
  A GOOD EXAMPLE
&lt;/h2&gt;

&lt;p&gt;Same context, but with much better defined scopes.&lt;/p&gt;

&lt;p&gt;As can be seen, only what is necessary is signed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// GOOD: Small and specific interfaces.&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IReader&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;readPost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IWriter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;writePost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IAdmin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;banUser&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// The regular user implements only what they actually do&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StandardUser&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IReader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IWriter&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;readPost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Reading...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;writePost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Writing...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// The Admin signs all contracts&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AdminUser&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IReader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IAdmin&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;readPost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Reading...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;writePost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Writing...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;banUser&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User banned!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  IN THE LONG RUN
&lt;/h2&gt;

&lt;p&gt;Segregating interfaces leaves your code highly modular. If tomorrow the banning rules of an &lt;code&gt;IAdmin&lt;/code&gt; change, the &lt;code&gt;StandardUser&lt;/code&gt; class will not need to be touched or recompiled.&lt;/p&gt;

&lt;p&gt;Your system is then built like Lego blocks, fitting together only the pieces (contracts) that make sense for that structure.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;My Links&lt;/strong&gt;&lt;br&gt;
Github: &lt;a href="https://github.com/victor-lis-bronzo" rel="noopener noreferrer"&gt;victor-lis-bronzo&lt;/a&gt;&lt;br&gt;
Linkedin: &lt;a href="https://www.linkedin.com/in/victor-lis-bronzo" rel="noopener noreferrer"&gt;victor-lis-bronzo&lt;/a&gt;&lt;br&gt;
Portfolio: &lt;a href="https://portfolio.victorlisbronzo.me" rel="noopener noreferrer"&gt;portfolio.victorlisbronzo.me&lt;/a&gt;&lt;br&gt;
Coolest Portfolio: &lt;a href="https://victorlisbronzo.me" rel="noopener noreferrer"&gt;victorlisbronzo.me&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Leave your reaction ❤️&lt;/strong&gt;&lt;br&gt;
Do you have the habit of creating several small interfaces or do you end up creating a single one for everything?&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>code</category>
      <category>softwareengineering</category>
      <category>typescript</category>
    </item>
    <item>
      <title>PRINCÍPIO DA SEGREGAÇÃO DE INTERFACES</title>
      <dc:creator>Victor Lis Bronzo</dc:creator>
      <pubDate>Thu, 20 Aug 2026 13:03:04 +0000</pubDate>
      <link>https://dev.to/victorlisbronzo/principio-da-segregacao-de-interfaces-72a</link>
      <guid>https://dev.to/victorlisbronzo/principio-da-segregacao-de-interfaces-72a</guid>
      <description>&lt;p&gt;Nenhuma classe deve ser dependente de métodos que não precisa.&lt;/p&gt;

&lt;p&gt;Um exemplo seria uma interface “Máquina”, que força os métodos &lt;code&gt;print( )&lt;/code&gt;, &lt;code&gt;scan( )&lt;/code&gt; e &lt;code&gt;fax( )&lt;/code&gt;. Nem toda máquina tem esses 3 métodos.&lt;/p&gt;

&lt;p&gt;Então criamos as interfaces &lt;code&gt;IPrinter&lt;/code&gt;, &lt;code&gt;IScanner&lt;/code&gt; e &lt;code&gt;IFax&lt;/code&gt;. Agora uma máquina assina apenas os contratos que realmente precisa e cumpre apenas esses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo de Código (Opcional - Ilustrando o texto):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ Anti-pattern: Interface genérica forçando métodos não utilizados&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IMaquina&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;fax&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ SOLID: Interfaces segregadas e específicas&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IPrinter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IScanner&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IFax&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;fax&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  A DEFINIÇÃO
&lt;/h2&gt;

&lt;p&gt;Na prática, podemos entender o ISP como o conceito de que uma classe nunca deve depender de métodos que não utiliza.&lt;/p&gt;

&lt;p&gt;A interface deve ser reutilizável em vários casos, logo uma interface engessada e com métodos em excesso atrapalha nesse processo.&lt;/p&gt;

&lt;p&gt;Quando uma classe assina um contrato gigante, ela é obrigada a implementar métodos que não fazem sentido para o contexto dela, sujando o código e gerando acoplamento desnecessário.&lt;/p&gt;




&lt;h2&gt;
  
  
  UM MAU EXEMPLO
&lt;/h2&gt;

&lt;p&gt;Contexto: Um sistema de blog onde todo user assina o mesmo contrato.&lt;/p&gt;

&lt;p&gt;Aqui ferimos alguns conceitos que citei.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo de Código:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// RUIM: Interface obesa. Força comportamentos desnecessários.&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IUserActions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;readPost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;writePost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;banUser&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Usuário comum não deveria ver isso!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StandardUser&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IUserActions&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;readPost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lendo...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;writePost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Escrevendo...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// ERRO: O usuário comum é forçado a ter esse método&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;banUser&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Acesso Negado: Você não é administrador.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  DIVIDIR PARA CONQUISTAR
&lt;/h2&gt;

&lt;p&gt;A solução no ponto de vista do ISP é clara, quebrar essa interface enorme em pequenos contratos bem escopados.&lt;/p&gt;

&lt;p&gt;Quando for necessário mais de um contrato, pode ser construído um novo contrato com essa combinação específica ou o próprio assinante assumir mais de um contrato por vez (a depender da linguagem).&lt;/p&gt;




&lt;h2&gt;
  
  
  UM BOM EXEMPLO
&lt;/h2&gt;

&lt;p&gt;Mesmo contexto, mas com escopos bem mais definidos.&lt;/p&gt;

&lt;p&gt;Como é possível observar, apenas o necessário é assinado.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo de Código:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// BOM: Interfaces pequenas e específicas.&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IReader&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;readPost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IWriter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;writePost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IAdmin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;banUser&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// O usuário comum implementa apenas o que ele realmente faz&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StandardUser&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IReader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IWriter&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;readPost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lendo...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;writePost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Escrevendo...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// O Admin assina todos os contratos&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AdminUser&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IReader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IAdmin&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;readPost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lendo...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;writePost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Escrevendo...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;banUser&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Usuário banido!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  A LONGO PRAZO
&lt;/h2&gt;

&lt;p&gt;Segregar interfaces deixa o seu código altamente modular. Se amanhã as regras de banimento de um &lt;code&gt;IAdmin&lt;/code&gt; mudarem, a classe &lt;code&gt;StandardUser&lt;/code&gt; não precisará ser tocada ou recompilada.&lt;/p&gt;

&lt;p&gt;O seu sistema passa a ser construído como blocos de Lego, encaixando apenas as peças (contratos) que fazem sentido para aquela estrutura.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Meus Links&lt;/strong&gt;&lt;br&gt;
Github: &lt;a href="https://github.com/victor-lis-bronzo" rel="noopener noreferrer"&gt;victor-lis-bronzo&lt;/a&gt;&lt;br&gt;
Linkedin: &lt;a href="https://www.linkedin.com/in/victor-lis-bronzo" rel="noopener noreferrer"&gt;victor-lis-bronzo&lt;/a&gt;&lt;br&gt;
Portfólio: &lt;a href="https://portfolio.victorlisbronzo.me" rel="noopener noreferrer"&gt;portfolio.victorlisbronzo.me&lt;/a&gt;&lt;br&gt;
Portfólio mais legal: &lt;a href="https://victorlisbronzo.me" rel="noopener noreferrer"&gt;victorlisbronzo.me&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Deixe sua reação ❤️&lt;/strong&gt;&lt;br&gt;
Você tem o costume de criar várias interfaces pequenas ou acaba criando uma só para tudo?&lt;/p&gt;

</description>
      <category>solidprinciples</category>
      <category>isp</category>
      <category>programming</category>
    </item>
    <item>
      <title>LISKOV SUBSTITUTION PRINCIPLE</title>
      <dc:creator>Victor Lis Bronzo</dc:creator>
      <pubDate>Thu, 20 Aug 2026 12:56:41 +0000</pubDate>
      <link>https://dev.to/victorlisbronzo/liskov-substitution-principle-67n</link>
      <guid>https://dev.to/victorlisbronzo/liskov-substitution-principle-67n</guid>
      <description>&lt;p&gt;A parent class must be able to be substituted by its child classes without breaking the application.&lt;/p&gt;

&lt;p&gt;In practice, this helps to organize the idea of inheritance, as it prevents us from extending a parent class only to later remove an already implemented method or do a “throw new Error(‘Not implemented’)”.&lt;/p&gt;

&lt;p&gt;Making us much more careful during planning.&lt;/p&gt;




&lt;h2&gt;
  
  
  THE BIGGEST SYMPTOM OF ERROR
&lt;/h2&gt;

&lt;p&gt;Unfortunately, it is a symptom that appears late, but it is exactly when we are going to make a new implementation.&lt;/p&gt;

&lt;p&gt;You realize you violated Liskov when you are going to build a class or subclass and need to purposely throw an error in the implementation of a method.&lt;/p&gt;

&lt;p&gt;Exactly because that method shouldn't be there, but it is.&lt;/p&gt;




&lt;h2&gt;
  
  
  A BAD EXAMPLE
&lt;/h2&gt;

&lt;p&gt;For example, in a delivery system.&lt;/p&gt;

&lt;p&gt;In this case, the “Delivery” class should be the parent/base for the other implementations.&lt;/p&gt;

&lt;p&gt;But the ‘MotoboyDelivery’ class breaks this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// BAD: The subclass breaks the parent class contract.&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Delivery&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;calculateShipping&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;15.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;getTrackingCode&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;TRK123456789&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MotoboyDelivery&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Delivery&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;calculateShipping&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;8.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// ERROR! There is no tracking code.&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;getTrackingCode&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Motoboys do not have a tracking code.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  THE SOLUTION
&lt;/h2&gt;

&lt;p&gt;For those who do not yet know the 'Liskov Substitution Principle', it might seem that fitting in a sequence of 'if's is the solution.&lt;/p&gt;

&lt;p&gt;But in reality, the ideal path is to rethink how this abstraction is built.&lt;/p&gt;

&lt;p&gt;A good guiding principle is to think that a child class must always be able to take the place of the parent, without breaking the application.&lt;/p&gt;




&lt;h2&gt;
  
  
  A GOOD EXAMPLE
&lt;/h2&gt;

&lt;p&gt;Still in the delivery system.&lt;/p&gt;

&lt;p&gt;‘Delivery’ now has ‘TrackableDelivery’ in the middle of the way.&lt;/p&gt;

&lt;p&gt;With this, each “leaf”/edge of the application inherits what makes the most sense and nothing is broken.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Delivery&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;calculateShipping&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;TrackableDelivery&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Delivery&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;getTrackingCode&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CorreiosDelivery&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;TrackableDelivery&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;calculateShipping&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;15.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;getTrackingCode&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BR987654321X&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MotoboyDelivery&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;Delivery&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;calculateShipping&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;8.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;h2&gt;
  
  
  CONCLUSION
&lt;/h2&gt;

&lt;p&gt;Respecting Liskov guarantees predictability.&lt;/p&gt;

&lt;p&gt;Whoever calls your method blindly trusts that the contract will be fulfilled, regardless of the class that is passed under the hood.&lt;/p&gt;

&lt;p&gt;This brings more security during the implementation of new features or even in the maintenance of old ones.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;My Links&lt;/strong&gt;&lt;br&gt;
Github: &lt;a href="https://github.com/victor-lis-bronzo" rel="noopener noreferrer"&gt;victor-lis-bronzo&lt;/a&gt;&lt;br&gt;
Linkedin: &lt;a href="https://www.linkedin.com/in/victor-lis-bronzo" rel="noopener noreferrer"&gt;victor-lis-bronzo&lt;/a&gt;&lt;br&gt;
Portfolio: &lt;a href="https://portfolio.victorlisbronzo.me" rel="noopener noreferrer"&gt;portfolio.victorlisbronzo.me&lt;/a&gt;&lt;br&gt;
Coolest Portfolio: &lt;a href="https://victorlisbronzo.me" rel="noopener noreferrer"&gt;victorlisbronzo.me&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Leave your reaction ❤️&lt;/strong&gt;&lt;br&gt;
And have you ever come across a method violating Liskov in any application?&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>designpatterns</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>PRINCÍPIO DA SUBSTITUIÇÃO DE LISKOV</title>
      <dc:creator>Victor Lis Bronzo</dc:creator>
      <pubDate>Thu, 20 Aug 2026 12:53:54 +0000</pubDate>
      <link>https://dev.to/victorlisbronzo/principio-da-substituicao-de-liskov-4ao9</link>
      <guid>https://dev.to/victorlisbronzo/principio-da-substituicao-de-liskov-4ao9</guid>
      <description>&lt;p&gt;Uma classe mãe deve ser capaz de ser substituída pelas suas classes filhas sem que a aplicação quebre.&lt;/p&gt;

&lt;p&gt;Isso na prática ajuda a organizar a ideia de herança, já que nos faz evitar estender uma classe mãe, apenas para depois remover um método já implementado ou fazer um “throw new Error(‘Not implemented’)”.&lt;/p&gt;

&lt;p&gt;Fazendo com que tenhamos mais cuidado no planejamento.&lt;/p&gt;




&lt;h2&gt;
  
  
  O MAIOR SINTOMA DE ERRO
&lt;/h2&gt;

&lt;p&gt;Infelizmente é um sintoma que aparece de forma tardia, mas é justamente quando vamos fazer uma nova implementação.&lt;/p&gt;

&lt;p&gt;Você percebe que feriu o Liskov quando você vai construir uma classe ou subclasse e precisa lançar um erro proposital na implementação de um método.&lt;/p&gt;

&lt;p&gt;Justamente porque aquele método não deveria estar ali, mas está.&lt;/p&gt;




&lt;h2&gt;
  
  
  UM EXEMPLO RUIM
&lt;/h2&gt;

&lt;p&gt;Por exemplo em um sistema de entregas.&lt;/p&gt;

&lt;p&gt;Nesse caso a classe “Delivery” deveria ser a mãe/base para as demais implementações.&lt;/p&gt;

&lt;p&gt;Mas a classe ‘MotoboyDelivery’ quebra isso.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo de Código:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// RUIM: A subclasse quebra o contrato da classe mãe.&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Delivery&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;calculateShipping&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;15.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;getTrackingCode&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;TRK123456789&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MotoboyDelivery&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Delivery&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;calculateShipping&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;8.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// ERRO! Não tem código de rastreio.&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;getTrackingCode&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Motoboys não possuem código.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  A SOLUÇÃO
&lt;/h2&gt;

&lt;p&gt;Para quem ainda não conhece o 'Liskov Substitution Principle', pode parecer que encaixar uma sequência de ifs é a solução.&lt;/p&gt;

&lt;p&gt;Mas na verdade o caminho ideal é repensar como essa abstração é construída.&lt;/p&gt;

&lt;p&gt;Um bom norte é pensar que uma classe filha sempre deve ser capaz de substituir o lugar da mãe, sem quebrar a aplicação.&lt;/p&gt;




&lt;h2&gt;
  
  
  UM EXEMPLO BOM
&lt;/h2&gt;

&lt;p&gt;Ainda no sistema de entregas.&lt;/p&gt;

&lt;p&gt;‘Delivery’ agora tem no meio do caminho ‘TrackableDelivery’.&lt;/p&gt;

&lt;p&gt;Com isso, cada “folha”/ponta da aplicação herda quem faz mais sentido e nada é quebrado.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo de Código:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Delivery&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;calculateShipping&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;TrackableDelivery&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Delivery&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;getTrackingCode&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CorreiosDelivery&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;TrackableDelivery&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;calculateShipping&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;15.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;getTrackingCode&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BR987654321X&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MotoboyDelivery&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;Delivery&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;calculateShipping&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;8.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;h2&gt;
  
  
  CONCLUSÃO
&lt;/h2&gt;

&lt;p&gt;Respeitar o Liskov garante previsibilidade.&lt;/p&gt;

&lt;p&gt;Quem chamar o seu método confia cegamente que o contrato será cumprido, independente da classe que for passada por debaixo dos panos.&lt;/p&gt;

&lt;p&gt;Isso traz mais segurança durante a implementação de novas features ou mesmo na sustentação das antigas.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Meus Links&lt;/strong&gt;&lt;br&gt;
Github: &lt;a href="https://github.com/victor-lis-bronzo" rel="noopener noreferrer"&gt;victor-lis-bronzo&lt;/a&gt;&lt;br&gt;
Linkedin: &lt;a href="https://www.linkedin.com/in/victor-lis-bronzo" rel="noopener noreferrer"&gt;victor-lis-bronzo&lt;/a&gt;&lt;br&gt;
Portfólio: &lt;a href="https://portfolio.victorlisbronzo.me" rel="noopener noreferrer"&gt;portfolio.victorlisbronzo.me&lt;/a&gt;&lt;br&gt;
Portfólio mais legal: &lt;a href="https://victorlisbronzo.me" rel="noopener noreferrer"&gt;victorlisbronzo.me&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Deixe sua reação ❤️&lt;/strong&gt;&lt;br&gt;
E você já se deparou com um método ferindo Liskov em alguma aplicação?&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>software</category>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>OPEN - CLOSED PRINCIPLE</title>
      <dc:creator>Victor Lis Bronzo</dc:creator>
      <pubDate>Tue, 14 Jul 2026 23:56:10 +0000</pubDate>
      <link>https://dev.to/victorlisbronzo/open-closed-principle-mkm</link>
      <guid>https://dev.to/victorlisbronzo/open-closed-principle-mkm</guid>
      <description>&lt;h2&gt;
  
  
  OPEN - CLOSED PRINCIPLE
&lt;/h2&gt;

&lt;p&gt;The integral parts of a code should be &lt;strong&gt;open for extension&lt;/strong&gt; and &lt;strong&gt;closed for modification&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The idea is to avoid relying on conditional checks using &lt;code&gt;if-else&lt;/code&gt;, ternary operators, and &lt;code&gt;switch&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When a new requirement arrives, you add the behavior by creating something new, without modifying the old code.&lt;/p&gt;




&lt;h2&gt;
  
  
  TO BE FAIR
&lt;/h2&gt;

&lt;p&gt;The idea of not using conditional operators is a result of correctly applying OCP, not the focus itself.&lt;/p&gt;

&lt;p&gt;This is because in order to not depend on these operators, excellence in applying &lt;strong&gt;polymorphism and abstraction&lt;/strong&gt; is necessary.&lt;/p&gt;

&lt;p&gt;With this, it becomes possible to couple new implementations without rewriting the already existing code.&lt;/p&gt;




&lt;h2&gt;
  
  
  BAD EXAMPLE
&lt;/h2&gt;

&lt;p&gt;Every new payment method will cause an edit here. It makes new implementations difficult and puts the old ones at risk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// BAD: Tight coupling. The class needs to be modified for each new rule.&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentProcessor&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;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CREDIT_CARD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PIX&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PAYPAL&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CREDIT_CARD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Processing $&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; via Credit Card...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="c1"&gt;// Complex logic for acquirer integration...&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="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PIX&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Processing $&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; via Pix key...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="c1"&gt;// Complex logic for QRCode generation...&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="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PAYPAL&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Processing $&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; via PayPal...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="c1"&gt;// Complex redirection logic...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Payment method not supported.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  GOOD EXAMPLE
&lt;/h2&gt;

&lt;p&gt;Just fulfill the “IPaymentMethod” contract and the method is already valid.&lt;/p&gt;

&lt;p&gt;We can then add a “DebitCardPayment”, without affecting the other methods.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1. The Abstraction (The Contract)&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IPaymentMethod&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// 2. The Extensions (New isolated behaviors)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CreditCardPayment&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IPaymentMethod&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;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Processing $&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; via Credit Card...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PixPayment&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IPaymentMethod&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;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Processing $&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; via Pix key...`&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;// 3. The Closed Application (The Consumer)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentProcessor&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;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;paymentMethod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IPaymentMethod&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;paymentMethod&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Practical use:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;processor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PaymentProcessor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;processor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;150.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PixPayment&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  IS IT REALLY THAT IMPORTANT?
&lt;/h2&gt;

&lt;p&gt;Without hesitation, yes, very much!&lt;/p&gt;

&lt;p&gt;Rework is expensive: it is wasted labor, planning, and time.&lt;/p&gt;

&lt;p&gt;And besides that, constantly altering already “finished” code opens up more loopholes to break a business rule or feature that was already working.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;My Links&lt;/strong&gt;&lt;br&gt;
Github: &lt;a href="https://github.com/victor-lis-bronzo" rel="noopener noreferrer"&gt;victor-lis-bronzo&lt;/a&gt;&lt;br&gt;
Linkedin: &lt;a href="https://www.linkedin.com/in/victor-lis-bronzo" rel="noopener noreferrer"&gt;victor-lis-bronzo&lt;/a&gt;&lt;br&gt;
Portfolio: &lt;a href="https://portfolio.victorlisbronzo.me" rel="noopener noreferrer"&gt;portfolio.victorlisbronzo.me&lt;/a&gt;&lt;br&gt;
Coolest Portfolio: &lt;a href="https://victorlisbronzo.me" rel="noopener noreferrer"&gt;victorlisbronzo.me&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Leave your reaction ❤️&lt;/strong&gt;&lt;br&gt;
Have you ever needed to refactor old code because of poorly applied OCP?&lt;/p&gt;

</description>
      <category>ocp</category>
      <category>openclosedprinciple</category>
      <category>solidprinciples</category>
      <category>programming</category>
    </item>
    <item>
      <title>PRINCÍPIO DE ABERTO/FECHADO</title>
      <dc:creator>Victor Lis Bronzo</dc:creator>
      <pubDate>Tue, 14 Jul 2026 23:54:50 +0000</pubDate>
      <link>https://dev.to/victorlisbronzo/principio-de-abertofechado-55kc</link>
      <guid>https://dev.to/victorlisbronzo/principio-de-abertofechado-55kc</guid>
      <description>&lt;h2&gt;
  
  
  OPEN - CLOSED PRINCIPLE
&lt;/h2&gt;

&lt;p&gt;As partes integrantes de um código devem ser &lt;strong&gt;abertas para extensão&lt;/strong&gt; e &lt;strong&gt;fechadas para modificações&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A ideia é evitar a dependência de verificações condicionais com &lt;code&gt;if-else&lt;/code&gt;, operadores ternários e &lt;code&gt;switch&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Quando um novo requisito chegar, você adiciona o comportamento criando algo novo, sem modificar o código antigo.&lt;/p&gt;




&lt;h2&gt;
  
  
  PRA SER JUSTO
&lt;/h2&gt;

&lt;p&gt;A ideia de não usar operadores condicionais é um resultado de uma aplicação correta do OCP, não é o foco em si.&lt;/p&gt;

&lt;p&gt;Isso porque para conseguir não depender desses operadores é necessário excelência na aplicação de &lt;strong&gt;polimorfismo e abstração&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Com isso, se torna possível acoplar novas implementações sem reescrever o código já existente.&lt;/p&gt;




&lt;h2&gt;
  
  
  EXEMPLO RUIM
&lt;/h2&gt;

&lt;p&gt;Todo novo meio de pagamento causará uma edição aqui. Dificulta em novas implementações e põe em risco as antigas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo de Código:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// RUIM: Forte acoplamento. A classe precisa ser modificada a cada nova regra.&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentProcessor&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;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CREDIT_CARD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PIX&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PAYPAL&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CREDIT_CARD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Processando R$&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; via Cartão de Crédito...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="c1"&gt;// Lógica complexa de integração com a adquirente...&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="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PIX&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Processando R$&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; via chave Pix...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="c1"&gt;// Lógica complexa de geração de QRCode...&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="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PAYPAL&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Processando R$&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; via PayPal...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="c1"&gt;// Lógica complexa de redirecionamento...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Método de pagamento não suportado.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  EXEMPLO BOM
&lt;/h2&gt;

&lt;p&gt;Basta cumprir o contrato “IPaymentMethod” e o método já é válido.&lt;/p&gt;

&lt;p&gt;Conseguimos então adicionar um “DebitCardPayment”, sem afetar os demais métodos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo de Código:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1. A Abstração (O Contrato)&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IPaymentMethod&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// 2. As Extensões (Novos comportamentos isolados)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CreditCardPayment&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IPaymentMethod&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;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Processando R$&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; via Cartão de Crédito...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PixPayment&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IPaymentMethod&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;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Processando R$&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; via chave Pix...`&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;// 3. A Aplicação Fechada (O Consumidor)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentProcessor&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;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;paymentMethod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IPaymentMethod&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;paymentMethod&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Uso prático:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;processor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PaymentProcessor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;processor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;150.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PixPayment&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  É MESMO TÃO IMPORTANTE?
&lt;/h2&gt;

&lt;p&gt;Sem titubear, sim e muito!&lt;/p&gt;

&lt;p&gt;Retrabalho é caro: é mão de obra, planejamento e tempo desperdiçados.&lt;/p&gt;

&lt;p&gt;E além disso, ficar constantemente alterando código já “finalizado” abre mais brechas para quebrar uma regra de negócio ou feature que já funcionava.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Meus Links&lt;/strong&gt;&lt;br&gt;
Github: &lt;a href="https://github.com/victor-lis-bronzo" rel="noopener noreferrer"&gt;victor-lis-bronzo&lt;/a&gt;&lt;br&gt;
Linkedin: &lt;a href="https://www.linkedin.com/in/victor-lis-bronzo" rel="noopener noreferrer"&gt;victor-lis-bronzo&lt;/a&gt;&lt;br&gt;
Portfólio: &lt;a href="https://portfolio.victorlisbronzo.me" rel="noopener noreferrer"&gt;portfolio.victorlisbronzo.me&lt;/a&gt;&lt;br&gt;
Portfólio mais legal: &lt;a href="https://victorlisbronzo.me" rel="noopener noreferrer"&gt;victorlisbronzo.me&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Deixe sua reação ❤️&lt;/strong&gt;&lt;br&gt;
Você já precisou refatorar código antigo por ter aplicado mal o OCP?&lt;/p&gt;

</description>
      <category>ocp</category>
      <category>openclosedprinciple</category>
      <category>solidprinciples</category>
      <category>programming</category>
    </item>
    <item>
      <title>SINGLE RESPONSIBILITY PRINCIPLE</title>
      <dc:creator>Victor Lis Bronzo</dc:creator>
      <pubDate>Mon, 13 Jul 2026 20:35:26 +0000</pubDate>
      <link>https://dev.to/victorlisbronzo/single-responsibility-principle-1g20</link>
      <guid>https://dev.to/victorlisbronzo/single-responsibility-principle-1g20</guid>
      <description>&lt;h2&gt;
  
  
  SINGLE RESPONSIBILITY PRINCIPLE (SRP)
&lt;/h2&gt;

&lt;p&gt;A class should have one, and exclusively &lt;strong&gt;one&lt;/strong&gt;, reason to change.&lt;/p&gt;

&lt;p&gt;In other words, we shouldn't have a single class doing everything: receiving data, validating requests, applying business rules, and accessing the database...&lt;/p&gt;

&lt;p&gt;This class that “does it all” is the famous &lt;em&gt;God Class&lt;/em&gt;, and it is an anti-pattern.&lt;/p&gt;




&lt;h2&gt;
  
  
  IS IT REALLY THAT IMPORTANT?
&lt;/h2&gt;

&lt;p&gt;An analogy that explains its importance well is the comparison between a Swiss Army Knife vs. a Scalpel.&lt;/p&gt;

&lt;p&gt;I know it might sound weird at first, but let's break it down. A pocket knife can be quite useful, carrying a bunch of functionalities at once, being practical in everyday life.&lt;/p&gt;

&lt;p&gt;But what if &lt;strong&gt;one tool&lt;/strong&gt; in it breaks?&lt;/p&gt;




&lt;h2&gt;
  
  
  POINT FOR SPECIALIZATION
&lt;/h2&gt;

&lt;p&gt;You &lt;strong&gt;will have to buy another one&lt;/strong&gt;, even if all the other tools are working well. A waste, right? This applied to software is even worse.&lt;/p&gt;

&lt;p&gt;On the other hand, the scalpel, besides having fewer chances of breaking, is a specialist in its own function. You will only replace the scalpel if it actually has a problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  CONNECTION TO ARCHITECTURE
&lt;/h2&gt;

&lt;p&gt;In practice, SRP is the foundation for organizing the structure of your project.&lt;/p&gt;

&lt;p&gt;A class that only serves a single responsibility helps in understanding architectures like MVC, Hexagonal, Clean Arch...&lt;/p&gt;

&lt;p&gt;This principle determines that it makes no sense to have a class that defines attributes, validates fields, saves data to the database... In this scenario, the class would assume multiple responsibilities, which violates the precepts of any of these architectures.&lt;/p&gt;




&lt;h2&gt;
  
  
  A BAD EXAMPLE
&lt;/h2&gt;

&lt;p&gt;This class below fulfills more than one responsibility. A class that deals with persistence, validation, business rules... violates the SRP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Example (The Anti-pattern):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="c1"&gt;// Responsibility 1: Data Validation&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;validateEmail&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Responsibility 2: Data Persistence (Database Access)&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;saveToDatabase&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Saving user &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; to MySQL database...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Responsibility 3: Sending Notifications&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;sendWelcomeEmail&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Sending welcome email to &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Responsibility 4: Report Generation (Presentation/Visualization)&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;generateUserReportPDF&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Generating PDF report for &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Responsibility 5: Infrastructure (Error Logging)&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;logSystemError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`[LOG] &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  AND WHAT WOULD BE A GOOD EXAMPLE?
&lt;/h2&gt;

&lt;p&gt;It would be extracting all these responsibilities (Persistence, Business Rule, Validation, Boundary...) from a single class.&lt;/p&gt;

&lt;p&gt;And exactly because of this, SRP communicates so well with architectures and their layers. Using the famous "Clean Arch" as an example, each of its layers will assume a well-defined responsibility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Example (Applying SRP):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ✅ SOLID: Each class has only one reason to change&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserValidator&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;isValidEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserRepository&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;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Saving user &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; to database...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmailService&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;sendWelcomeEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Sending welcome email to &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ReportGenerator&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;generateUserPDF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Generating PDF report for &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Logger&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;logError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`[LOG] &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  SRP + CLEAN ARCH
&lt;/h2&gt;

&lt;p&gt;Each layer fulfills only its responsibility and passes it on to the next layer, following the flow. The detail is that, depending on the size of the project, the team, and the needs, the layers can increase or decrease.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ROUTE&lt;/strong&gt;: Receives the HTTP request and directs the traffic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CONTROLLER&lt;/strong&gt;: Validates the input data and formats the final response.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SERVICE&lt;/strong&gt;: Orchestrates the application rules and entities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;REPOSITORY&lt;/strong&gt;: Isolates the database and executes the persistence.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  OTHER CASES
&lt;/h2&gt;

&lt;p&gt;The previous example focused on Clean Arch, but other architectural approaches, like MVC and Hexagonal, also apply SRP to their core.&lt;/p&gt;

&lt;p&gt;SOLID acts as a foundation for these patterns, not as a competitor.&lt;/p&gt;

&lt;p&gt;In practice, the division of responsibilities ends up being implicit in the very definition of the layers of any good architecture:&lt;br&gt;
⬇️ &lt;code&gt;user.route.ts&lt;/code&gt;&lt;br&gt;
⬇️ &lt;code&gt;user.controller.ts&lt;/code&gt;&lt;br&gt;
⬇️ &lt;code&gt;user.service.ts&lt;/code&gt;&lt;br&gt;
⬇️ &lt;code&gt;user.repository.ts&lt;/code&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;My Links&lt;/strong&gt;&lt;br&gt;
Github: &lt;a href="https://github.com/victor-lis-bronzo" rel="noopener noreferrer"&gt;victor-lis-bronzo&lt;/a&gt;&lt;br&gt;
Linkedin: &lt;a href="https://www.linkedin.com/in/victor-lis-bronzo" rel="noopener noreferrer"&gt;victor-lis-bronzo&lt;/a&gt;&lt;br&gt;
Portfolio: &lt;a href="https://portfolio.victorlisbronzo.me" rel="noopener noreferrer"&gt;portfolio.victorlisbronzo.me&lt;/a&gt;&lt;br&gt;
Coolest Portfolio: &lt;a href="https://victorlisbronzo.me" rel="noopener noreferrer"&gt;victorlisbronzo.me&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Leave your reaction ❤️&lt;/strong&gt;&lt;br&gt;
Had you already realized the importance of SRP?&lt;/p&gt;

</description>
      <category>solidprinciples</category>
      <category>singleresponsibility</category>
      <category>programming</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>PRINCÍPIO DA RESPONSABILIDADE ÚNICA</title>
      <dc:creator>Victor Lis Bronzo</dc:creator>
      <pubDate>Mon, 13 Jul 2026 20:34:04 +0000</pubDate>
      <link>https://dev.to/victorlisbronzo/principio-da-responsabilidade-unica-301d</link>
      <guid>https://dev.to/victorlisbronzo/principio-da-responsabilidade-unica-301d</guid>
      <description>&lt;h2&gt;
  
  
  PRINCÍPIO DA RESPONSABILIDADE ÚNICA
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Em Inglês: SINGLE RESPONSIBILITY PRINCIPLE (SRP)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Uma classe deve ter um, e exclusivamente &lt;strong&gt;um&lt;/strong&gt;, motivo para ser alterada.&lt;/p&gt;

&lt;p&gt;Ou seja, não devemos ter uma única classe fazendo de tudo: recebendo dados, validando requisições, aplicando regras de negócio e acessando o banco de dados...&lt;/p&gt;

&lt;p&gt;Essa classe que “faz tudo” é a famosa &lt;em&gt;God Class&lt;/em&gt;, e é um anti-pattern.&lt;/p&gt;




&lt;h2&gt;
  
  
  É MESMO TÃO IMPORTANTE?
&lt;/h2&gt;

&lt;p&gt;Uma analogia que explica bem a importância, é a comparação entre Canivete Suíço vs. Bisturi.&lt;/p&gt;

&lt;p&gt;Eu sei que pode soar esquisito de primeira, mas vamos destrinchar. Um canivete até pode ser bem útil, carregando um monte de funcionalidades de uma vez, sendo prático no dia a dia.&lt;/p&gt;

&lt;p&gt;Mas e se &lt;strong&gt;uma ferramenta&lt;/strong&gt; dele quebrar?&lt;/p&gt;




&lt;h2&gt;
  
  
  PONTO PARA ESPECIALIZAÇÃO
&lt;/h2&gt;

&lt;p&gt;Você &lt;strong&gt;vai ter que comprar outro&lt;/strong&gt;, mesmo que todas as outras ferramentas estejam funcionando bem. Um desperdício né? Isso aplicado em software fica pior ainda.&lt;/p&gt;

&lt;p&gt;Já o bisturi, além de ter menos possibilidades de quebrar, ele é especialista na própria função. Você só vai trocar o bisturi, se ele realmente tiver algum problema.&lt;/p&gt;




&lt;h2&gt;
  
  
  CONEXÃO COM ARQUITETURA
&lt;/h2&gt;

&lt;p&gt;Na prática, o SRP é a base para organizar a estrutura do seu projeto.&lt;/p&gt;

&lt;p&gt;Uma classe que só atende a uma única responsabilidade ajuda na compreensão de arquiteturas como MVC, Hexagonal, Clean Arch...&lt;/p&gt;

&lt;p&gt;Esse princípio determina que não faz sentido você ter uma classe que define atributos, valida campos, salva dados no banco... Nesse cenário, a classe assumiria múltiplas responsabilidades, o que viola os preceitos de qualquer uma dessas arquiteturas.&lt;/p&gt;




&lt;h2&gt;
  
  
  UM MAU EXEMPLO
&lt;/h2&gt;

&lt;p&gt;Essa classe abaixo cumpre mais de uma responsabilidade. Uma classe que lida com persistência, validação, regras de negócio... fere o SRP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo de Código (O Anti-pattern):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="c1"&gt;// Responsabilidade 1: Validação de Dados&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;validateEmail&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Responsabilidade 2: Persistência de Dados (Acesso ao Banco de Dados)&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;saveToDatabase&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Saving user &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; to MySQL database...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Responsabilidade 3: Envio de Notificações&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;sendWelcomeEmail&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Sending welcome email to &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Responsabilidade 4: Geração de Relatórios (Apresentação/Visualização)&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;generateUserReportPDF&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Generating PDF report for &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Responsabilidade 5: Infraestrutura (Log de Erros)&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;logSystemError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`[LOG] &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  E O QUE SERIA UM BOM EXEMPLO?
&lt;/h2&gt;

&lt;p&gt;Seria extrair todas essas responsabilidades (Persistência, Regra de Negócio, Validação, Fronteira...) de uma única classe.&lt;/p&gt;

&lt;p&gt;E justamente por isso, o SRP conversa tão bem com arquiteturas e suas camadas. Usando a famosa "Clean Arch" como exemplo, cada uma de suas camadas vai assumir uma responsabilidade bem definida.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo de Código (Aplicando o SRP):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ✅ SOLID: Cada classe tem apenas um motivo para mudar&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserValidator&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;isValidEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserRepository&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;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Saving user &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; to database...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmailService&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;sendWelcomeEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Sending welcome email to &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ReportGenerator&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;generateUserPDF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Generating PDF report for &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Logger&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;logError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`[LOG] &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  SRP + CLEAN ARCH
&lt;/h2&gt;

&lt;p&gt;Cada camada cumpre apenas sua responsabilidade e repassa para a próxima camada, seguindo o fluxo. O detalhe é que, dependendo do tamanho do projeto, da equipe e das necessidades, as camadas podem aumentar ou diminuir.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ROUTE&lt;/strong&gt;: Recebe a requisição HTTP e direciona o tráfego.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CONTROLLER&lt;/strong&gt;: Valida os dados de entrada e formata a resposta final.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SERVICE&lt;/strong&gt;: Orquestra as regras da aplicação e as entidades.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;REPOSITORY&lt;/strong&gt;: Isola o banco de dados e executa a persistência.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  OUTROS CASOS
&lt;/h2&gt;

&lt;p&gt;O exemplo anterior focou em Clean Arch, mas outras abordagens arquiteturais, como MVC e Hexagonal, também aplicam o SRP em suas bases.&lt;/p&gt;

&lt;p&gt;O SOLID atua como um alicerce para esses padrões, não como um concorrente.&lt;/p&gt;

&lt;p&gt;Na prática, a divisão de responsabilidades acaba ficando implícita na própria definição das camadas de qualquer boa arquitetura:&lt;br&gt;
⬇️ &lt;code&gt;user.route.ts&lt;/code&gt;&lt;br&gt;
⬇️ &lt;code&gt;user.controller.ts&lt;/code&gt;&lt;br&gt;
⬇️ &lt;code&gt;user.service.ts&lt;/code&gt;&lt;br&gt;
⬇️ &lt;code&gt;user.repository.ts&lt;/code&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Meus Links&lt;/strong&gt;&lt;br&gt;
Github: &lt;a href="https://github.com/victor-lis-bronzo" rel="noopener noreferrer"&gt;victor-lis-bronzo&lt;/a&gt;&lt;br&gt;
Linkedin: &lt;a href="https://www.linkedin.com/in/victor-lis-bronzo" rel="noopener noreferrer"&gt;victor-lis-bronzo&lt;/a&gt;&lt;br&gt;
Portfólio: &lt;a href="https://portfolio.victorlisbronzo.me" rel="noopener noreferrer"&gt;portfolio.victorlisbronzo.me&lt;/a&gt;&lt;br&gt;
Portfólio mais legal: &lt;a href="https://victorlisbronzo.me" rel="noopener noreferrer"&gt;victorlisbronzo.me&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Deixe sua reação ❤️&lt;/strong&gt;&lt;br&gt;
Você já tinha percebido a importância do SRP?&lt;/p&gt;

</description>
      <category>singleresponsibility</category>
      <category>solidprinciples</category>
      <category>cleancode</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
