<?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: Jefferson Rodrigues</title>
    <description>The latest articles on DEV Community by Jefferson Rodrigues (@rodriguesjeff).</description>
    <link>https://dev.to/rodriguesjeff</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%2F1034290%2Fcccc708e-48cf-490b-8a54-cbabf63c7346.jpg</url>
      <title>DEV Community: Jefferson Rodrigues</title>
      <link>https://dev.to/rodriguesjeff</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rodriguesjeff"/>
    <language>en</language>
    <item>
      <title>Josue Meetings - FOSS aplicativo para transcrever e resumir calls</title>
      <dc:creator>Jefferson Rodrigues</dc:creator>
      <pubDate>Thu, 30 Jul 2026 03:05:33 +0000</pubDate>
      <link>https://dev.to/rodriguesjeff/josue-meetings-foos-aplicativo-para-transcrever-e-resumir-calls-2o0m</link>
      <guid>https://dev.to/rodriguesjeff/josue-meetings-foos-aplicativo-para-transcrever-e-resumir-calls-2o0m</guid>
      <description>&lt;p&gt;&lt;strong&gt;Josue Meetings&lt;/strong&gt; é um aplicativo desktop que grava suas reuniões em segundo plano, capturando o áudio do sistema e do microfone. O aplicativo permanece na menu bar e transforma o áudio em texto utilizando o Whisper executado localmente. Depois, se desejar, gera resumos e responde perguntas usando OpenAI ou DeepSeek.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Sem servidor próprio:&lt;/strong&gt; seus dados permanecem na sua máquina.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  O problema
&lt;/h2&gt;

&lt;p&gt;Toda reunião online gera informações importantes, mas quase sempre elas acabam se perdendo. Gravar o áudio, transcrever e resumir normalmente exige várias ferramentas e serviços na nuvem.&lt;/p&gt;

&lt;p&gt;O Josue Meetings resolve tudo isso em um único fluxo, executado localmente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como funciona
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Dê um nome para a reunião (ou utilize o padrão).&lt;/li&gt;
&lt;li&gt;Inicie a gravação.&lt;/li&gt;
&lt;li&gt;Acompanhe os níveis de áudio do sistema e do microfone.&lt;/li&gt;
&lt;li&gt;Pause, retome ou finalize quando desejar.&lt;/li&gt;
&lt;li&gt;Continue trabalhando normalmente pela menu bar.&lt;/li&gt;
&lt;li&gt;Ao finalizar, a reunião é aberta automaticamente para transcrição.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Transcrição local
&lt;/h2&gt;

&lt;p&gt;Toda a transcrição é realizada utilizando o Whisper executado na própria máquina.&lt;/p&gt;

&lt;p&gt;Você pode exportar o resultado em:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Markdown (&lt;code&gt;.md&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Texto (&lt;code&gt;.txt&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Após uma transcrição bem-sucedida, o áudio pode ser removido automaticamente, preservando sua privacidade.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inteligência Artificial (Opcional)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fidx1vbw13wvfi36mq57v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fidx1vbw13wvfi36mq57v.png" alt="Opçao de selecionar api da openai ou deepseek" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com uma chave de API da OpenAI ou DeepSeek, você pode:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gerar resumos automáticos.&lt;/li&gt;
&lt;li&gt;Conversar com um agente sobre uma reunião.&lt;/li&gt;
&lt;li&gt;Organizar reuniões em pastas.&lt;/li&gt;
&lt;li&gt;Fazer perguntas considerando todas as reuniões de um projeto.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Configuração
&lt;/h2&gt;

&lt;p&gt;O aplicativo possui um assistente de configuração que detecta o sistema operacional e orienta a instalação dos componentes necessários.&lt;/p&gt;

&lt;p&gt;Atualmente:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ macOS: captura de sistema + microfone utilizando BlackHole e Multi-Output Device.&lt;/li&gt;
&lt;li&gt;🚧 Windows: suporte em evolução.&lt;/li&gt;
&lt;li&gt;🚧 Linux: suporte em evolução.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Recursos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Aplicativo desktop (Electron)&lt;/li&gt;
&lt;li&gt;Gravação do sistema + microfone&lt;/li&gt;
&lt;li&gt;Funcionamento na menu bar&lt;/li&gt;
&lt;li&gt;Transcrição 100% local (Whisper)&lt;/li&gt;
&lt;li&gt;Resumos e chat via OpenAI ou DeepSeek&lt;/li&gt;
&lt;li&gt;Organização por projetos&lt;/li&gt;
&lt;li&gt;Agente por pasta&lt;/li&gt;
&lt;li&gt;Lixeira integrada&lt;/li&gt;
&lt;li&gt;Assistente de configuração&lt;/li&gt;
&lt;li&gt;Privacidade por padrão&lt;/li&gt;
&lt;/ul&gt;




&lt;blockquote&gt;
&lt;p&gt;Grave suas reuniões sem interromper seu trabalho, transcreva tudo localmente e utilize IA apenas quando fizer sentido, sempre com a sua própria chave de API.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O software é livre e aceitamos contribuição de pessoas bem intencionadas que queiram ajudar a melhorar cada dia mais!&lt;br&gt;
&lt;a href="https://github.com/rodriguesJeff/josue" rel="noopener noreferrer"&gt;Repositório do projeto&lt;/a&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>ai</category>
      <category>programming</category>
      <category>electron</category>
    </item>
    <item>
      <title>🚀 Revisando o S.O.L.I.D na Prática com Flutter e Dart</title>
      <dc:creator>Jefferson Rodrigues</dc:creator>
      <pubDate>Thu, 26 Feb 2026 03:58:02 +0000</pubDate>
      <link>https://dev.to/rodriguesjeff/revisando-o-solid-na-pratica-com-flutter-e-dart-44e1</link>
      <guid>https://dev.to/rodriguesjeff/revisando-o-solid-na-pratica-com-flutter-e-dart-44e1</guid>
      <description>&lt;h1&gt;
  
  
  🚀 Revisando o S.O.L.I.D na Prática com Flutter e Dart
&lt;/h1&gt;

&lt;h2&gt;
  
  
  🎯 Introdução
&lt;/h2&gt;

&lt;p&gt;Resolvi revisar os meus conhecimentos sobre temas essenciais da programação. Iniciei pelo &lt;strong&gt;SOLID&lt;/strong&gt; porque é algo que deve ser revisitado de vez em quando para garantir que estamos entendendo não só o conceito, mas a prática também.&lt;/p&gt;

&lt;p&gt;Com isso, podemos escrever códigos mais limpos, escaláveis e de fácil entendimento.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ Metodologia
&lt;/h2&gt;

&lt;p&gt;Usei como base dois repositórios meus de quando eu estava estudando &lt;strong&gt;Clean Architecture&lt;/strong&gt;. Um deles trata-se de um app simples: buscar conselhos em uma API e retornar para o usuário.&lt;/p&gt;

&lt;p&gt;Neste projeto, aplico cada um dos cinco princípios do SOLID. Abaixo, detalho como cada um deles se comporta no código.&lt;/p&gt;




&lt;h2&gt;
  
  
  🟢 S — Single Responsibility Principle (SRP)
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Princípio da Responsabilidade Única:&lt;/strong&gt; Uma classe deve ter um, e apenas um, motivo para mudar.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No exemplo abaixo, a classe abstrata para o data source define apenas o contrato de busca remota. Ela não se preocupa com lógica de negócio ou como os dados serão exibidos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AdviceRemoteDataSource&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Advice&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;getAdvice&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Outro exemplo claro é o tratamento de erros. Criamos uma estrutura base e especializamos as falhas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Failure&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;Equatable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Failure&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="n"&gt;properties&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kd"&gt;dynamic&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;[]])&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Responsável apenas por erros de servidor&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ServerFailure&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;Failure&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Responsável apenas por erros de cache local&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CacheFailure&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;Failure&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔵 O — Open/Closed Principle (OCP)
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Aberto para Extensão, Fechado para Modificação:&lt;/strong&gt; Você deve ser capaz de estender o comportamento de uma classe sem modificar o seu código-fonte original.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A classe &lt;code&gt;AdviceRepository&lt;/code&gt; está "fechada" (o contrato está definido). Se precisarmos de uma nova forma de obter dados, apenas implementamos o contrato em uma nova classe, sem tocar na interface original.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AdviceRepository&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Either&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Failure&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Advice&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;getAdvice&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;AdviceRepositoryImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="n"&gt;AdviceRepository&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;AdviceRemoteDataSource&lt;/span&gt; &lt;span class="n"&gt;remoteDataSource&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;AdviceRepositoryImpl&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;remoteDataSource&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Either&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Failure&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Advice&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;getAdvice&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;remoteAdvice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;remoteDataSource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAdvice&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;remoteAdvice&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kd"&gt;on&lt;/span&gt; &lt;span class="n"&gt;ServerException&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Left&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ServerFailure&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;
  
  
  🟡 L — Liskov Substitution Principle (LSP)
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Princípio da Substituição de Liskov:&lt;/strong&gt; Objetos de uma superclasse devem ser substituíveis por objetos de suas subclasses sem quebrar a aplicação.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No Flutter, isso é muito comum com os DataSources. A implementação &lt;code&gt;AdviceRemoteDataSourceImpl&lt;/code&gt; pode substituir perfeitamente a abstração &lt;code&gt;AdviceRemoteDataSource&lt;/code&gt; em qualquer lugar que ela seja exigida.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AdviceRemoteDataSourceImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="n"&gt;AdviceRemoteDataSource&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Client&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;AdviceRemoteDataSourceImpl&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Advice&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;getAdvice&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Implementação real da chamada HTTP&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;💡 Obs.: Uma melhoria seria criar um &lt;code&gt;AdviceDataSource&lt;/code&gt; genérico, permitindo trocar o Remote pelo Local de forma transparente.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🟠 I — Interface Segregation Principle (ISP)
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Segregação de Interface:&lt;/strong&gt; Uma classe não deve ser forçada a implementar interfaces e métodos que não utiliza.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Em vez de criar uma interface gigante "TudoNoApp", dividimos em interfaces específicas. No exemplo, o repositório depende apenas do que é essencial para ele: o DataSource de conselhos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Interface específica e focada no domínio de conselhos&lt;/span&gt;
&lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AdviceRemoteDataSource&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Advice&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;getAdvice&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;
  
  
  🔴 D — Dependency Inversion Principle (DIP)
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Inversão de Dependência:&lt;/strong&gt; Dependa de abstrações, não de implementações concretas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Aqui é onde o &lt;code&gt;GetIt&lt;/code&gt; ou &lt;code&gt;Provider&lt;/code&gt; brilham. O &lt;code&gt;AdviceRepositoryImpl&lt;/code&gt; não conhece a implementação do DataSource, ele conhece apenas o contrato. A "mágica" acontece no nosso Service Locator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setupLocator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Registramos a abstração apontando para a implementação&lt;/span&gt;
  &lt;span class="n"&gt;getIt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;registerLazySingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AdviceRepository&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;AdviceRepositoryImpl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;remoteDataSource:&lt;/span&gt; &lt;span class="n"&gt;getIt&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;getIt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;registerLazySingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AdviceRemoteDataSource&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
      &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;AdviceRemoteDataSourceImpl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;client:&lt;/span&gt; &lt;span class="n"&gt;getIt&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;

  &lt;span class="n"&gt;getIt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;registerLazySingleton&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Client&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;
  
  
  📊 Resumo Visual
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Sigla&lt;/th&gt;
&lt;th&gt;Princípio&lt;/th&gt;
&lt;th&gt;Resumo em uma frase&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;S&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Responsabilidade Única&lt;/td&gt;
&lt;td&gt;Cada classe faz apenas uma coisa.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;O&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Aberto/Fechado&lt;/td&gt;
&lt;td&gt;Estenda o comportamento sem alterar o original.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;L&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Subst. de Liskov&lt;/td&gt;
&lt;td&gt;Subclasses devem honrar o contrato da base.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;I&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Segregação de Interface&lt;/td&gt;
&lt;td&gt;Crie interfaces pequenas e específicas.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;D&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Inversão de Dependência&lt;/td&gt;
&lt;td&gt;Dependa de contratos, não de classes concretas.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




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

&lt;p&gt;Utilizar esses conceitos na prática vai além de construir "códigos bonitos". Trata-se de garantir a &lt;strong&gt;manutenibilidade&lt;/strong&gt;. Um código bem estruturado permite que ele viva mais e que as manutenções futuras não sejam um sofrimento.&lt;/p&gt;

&lt;p&gt;Lembre-se: o seu código fala muito sobre você! 🚀&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ficou com alguma dúvida sobre como aplicar isso no seu projeto Flutter? Comenta aqui embaixo e vamos trocar uma ideia!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>solidprinciples</category>
      <category>flutter</category>
      <category>cleancode</category>
      <category>mobile</category>
    </item>
  </channel>
</rss>
