<?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>Forem: Rodrigo Castro</title>
    <description>The latest articles on Forem by Rodrigo Castro (@redrodrigoc).</description>
    <link>https://forem.com/redrodrigoc</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F819310%2F7f973b37-8643-445f-98e2-a8ad2647e1c7.jpeg</url>
      <title>Forem: Rodrigo Castro</title>
      <link>https://forem.com/redrodrigoc</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/redrodrigoc"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>Rodrigo Castro</dc:creator>
      <pubDate>Fri, 05 Sep 2025 17:26:33 +0000</pubDate>
      <link>https://forem.com/redrodrigoc/-564m</link>
      <guid>https://forem.com/redrodrigoc/-564m</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/shayy" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2711665%2Fe528db00-6ac0-4654-b0d5-c68d84ed332e.png" alt="shayy"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/shayy/stop-building-for-scale-you-dont-have-users-yet-4aep" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Stop Building for "Scale." You Don't Have Users Yet.&lt;/h2&gt;
      &lt;h3&gt;Shayan ・ Sep 4&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#programming&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#ai&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>ai</category>
    </item>
    <item>
      <title>Microserviços Everywhere? Talvez seja hora de conhecer o Monólito Modular</title>
      <dc:creator>Rodrigo Castro</dc:creator>
      <pubDate>Mon, 11 Aug 2025 20:35:20 +0000</pubDate>
      <link>https://forem.com/redrodrigoc/microservicos-everywhere-talvez-seja-hora-de-conhecer-o-monolito-modular-ki</link>
      <guid>https://forem.com/redrodrigoc/microservicos-everywhere-talvez-seja-hora-de-conhecer-o-monolito-modular-ki</guid>
      <description>&lt;p&gt;&lt;strong&gt;A arquitetura que combina o melhor dos dois mundos e pode salvar seu próximo projeto&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  O Hype dos Microserviços
&lt;/h2&gt;

&lt;p&gt;Vivemos em uma era onde falar de microserviços virou quase obrigatório em qualquer conversa sobre arquitetura de software. Netflix fez, Uber fez, então &lt;strong&gt;obviamente&lt;/strong&gt; seu projeto também deveria começar com microserviços, certo?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spoiler alert:&lt;/strong&gt; Provavelmente não.&lt;/p&gt;

&lt;p&gt;A realidade é que muitas empresas estão criando &lt;strong&gt;"microserviços distribuídos monolíticos"&lt;/strong&gt; - sistemas complexos, difíceis de debuggar e manter, que herdam as desvantagens dos microserviços sem colher os benefícios.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Síndrome do "Microserviços First"
&lt;/h2&gt;

&lt;p&gt;Vamos ser honestos: quantos projetos você conhece que começaram "fazendo a coisa certa" com microserviços e acabaram assim:&lt;/p&gt;

&lt;p&gt;❌ &lt;strong&gt;5 serviços para um MVP&lt;/strong&gt; que poderia ser uma única aplicação&lt;br&gt;&lt;br&gt;
❌ &lt;strong&gt;Transações distribuídas&lt;/strong&gt; para operações que deveriam ser atômicas&lt;br&gt;&lt;br&gt;
❌ &lt;strong&gt;Debugging infernal&lt;/strong&gt; espalhado por múltiplos logs&lt;br&gt;&lt;br&gt;
❌ &lt;strong&gt;Deploy complexo&lt;/strong&gt; desde o dia 1&lt;br&gt;&lt;br&gt;
❌ &lt;strong&gt;Time perdido&lt;/strong&gt; configurando infraestrutura ao invés de validar produto  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Premature optimization is the root of all evil"&lt;/em&gt; - Donald Knuth&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Começar com microserviços é &lt;strong&gt;otimização prematura de arquitetura&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Por Que NÃO Começar com Microserviços?
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. &lt;strong&gt;Você Não É a Netflix (Ainda)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Netflix tem &lt;strong&gt;milhões de usuários simultâneos&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Você provavelmente tem &lt;strong&gt;dezenas ou centenas&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Eles têm &lt;strong&gt;centenas de desenvolvedores&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Você tem &lt;strong&gt;2-10 pessoas&lt;/strong&gt; no time&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  2. &lt;strong&gt;Complexidade Desnecessária&lt;/strong&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Monólito: 1 deploy, 1 banco, 1 log
Microserviços: N deploys, N bancos, N logs, N configurações
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Debugging Nightmare&lt;/strong&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bug no monólito: Stack trace completo
Bug em microserviços: "Qual serviço quebrou? Em que ordem?"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Over-engineering do MVP&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Você deveria estar &lt;strong&gt;validando seu produto&lt;/strong&gt;, não configurando Kubernetes.&lt;/p&gt;
&lt;h2&gt;
  
  
  Conheça o Monólito Modular
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;E se eu te disser que existe uma arquitetura que combina:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Simplicidade&lt;/strong&gt; do monólito para desenvolver e deployar&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Organização&lt;/strong&gt; dos microserviços para manter e escalar&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Flexibilidade&lt;/strong&gt; para evoluir gradualmente&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Performance&lt;/strong&gt; de transações locais  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Essa arquitetura existe e se chama Monólito Modular.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Como Funciona?
&lt;/h2&gt;

&lt;p&gt;Imagine uma aplicação Laravel organizada assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
├── Domains/
│   ├── User/          # Módulo de usuários
│   ├── Product/       # Módulo de produtos  
│   ├── Order/         # Módulo de pedidos
│   └── Payment/       # Módulo de pagamentos
├── Shared/            # Código compartilhado
└── Infrastructure/    # Concerns técnicos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Características Principais:
&lt;/h3&gt;

&lt;p&gt;🔹 &lt;strong&gt;Um único aplicativo&lt;/strong&gt; - Deploy simples, debugging fácil&lt;br&gt;&lt;br&gt;
🔹 &lt;strong&gt;Módulos bem definidos&lt;/strong&gt; - Separação clara de responsabilidades&lt;br&gt;&lt;br&gt;
🔹 &lt;strong&gt;Comunicação via interfaces&lt;/strong&gt; - Baixo acoplamento&lt;br&gt;&lt;br&gt;
🔹 &lt;strong&gt;Banco de dados compartilhado&lt;/strong&gt; - ACID transactions&lt;br&gt;&lt;br&gt;
🔹 &lt;strong&gt;Migração gradual&lt;/strong&gt; - Evolução para microserviços quando necessário  &lt;/p&gt;
&lt;h2&gt;
  
  
  Vantagens Práticas
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Para o Time
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Onboarding rápido&lt;/strong&gt; - Nova pessoa entende a estrutura em horas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Desenvolvimento ágil&lt;/strong&gt; - Mudanças rápidas sem coordenação entre times&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debugging simples&lt;/strong&gt; - Stack trace completo, logs centralizados&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Para o Negócio
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Time to market menor&lt;/strong&gt; - Foco no produto, não na infraestrutura&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custos reduzidos&lt;/strong&gt; - Menos complexidade = menos recursos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validação rápida&lt;/strong&gt; - Iterar rapidamente sobre features&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Para a Arquitetura
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Testabilidade&lt;/strong&gt; - Testes integrados simples&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistência&lt;/strong&gt; - Transações ACID entre módulos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibilidade&lt;/strong&gt; - Migration path claro para microserviços&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Quando Evoluir para Microserviços?
&lt;/h2&gt;

&lt;p&gt;O monolito modular oferece um &lt;strong&gt;migration path natural&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fase 1: Monólito modular
├── Validar produto
├── Crescer time
└── Identificar gargalos

Fase 2: Extração gradual
├── Módulo Payment → Microserviço
├── Módulo Notification → Microserviço  
└── Core continua monólito

Fase 3: Microserviços completos
└── Quando realmente justificar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sinais de que é hora de extrair:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Módulo&lt;/strong&gt; tem problemas de performance específicos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time grande&lt;/strong&gt; trabalhando no mesmo módulo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escalabilidade&lt;/strong&gt; diferente entre módulos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tecnologia&lt;/strong&gt; específica seria melhor para um módulo&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Empresas que Usam (e Recomendam)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Shopify&lt;/strong&gt; - Monólito modular gigante que atende milhões&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt; - Rails monólito que escala massivamente
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Basecamp&lt;/strong&gt; - Defensores ferrenhos do monólito bem estruturado&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Laravel&lt;/strong&gt; (próprio framework) - Monólito modular por design&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"The monolith isn't dead. It's just well-designed."&lt;/em&gt; - DHH, Basecamp&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Implementação Prática
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Estrutura de um Módulo:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nc"&gt;Domains&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nc"&gt;Models&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;           &lt;span class="c1"&gt;# Entidades do domínio&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nc"&gt;Services&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;         &lt;span class="c1"&gt;# Regras de negócio&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nc"&gt;Repositories&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;     &lt;span class="c1"&gt;# Acesso a dados&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nc"&gt;Events&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;           &lt;span class="c1"&gt;# Eventos do domínio&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nc"&gt;Http&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nc"&gt;Controllers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;  &lt;span class="c1"&gt;# Controllers REST&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nc"&gt;Livewire&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;     &lt;span class="c1"&gt;# Componentes TALL&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nc"&gt;Tests&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;           &lt;span class="c1"&gt;# Testes do módulo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Comunicação Entre Módulos:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Via Service (síncrono)&lt;/span&gt;
&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;orderService&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Via Events (assíncrono) &lt;/span&gt;
&lt;span class="nc"&gt;OrderCreated&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$order&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: Comece Simples, Escale Gradualmente
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A pergunta não é:&lt;/strong&gt; "Microserviços ou Monólito?"&lt;br&gt;&lt;br&gt;
&lt;strong&gt;A pergunta é:&lt;/strong&gt; "Qual arquitetura me permite validar meu produto mais rápido?"&lt;/p&gt;

&lt;p&gt;O monólito modular oferece:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simplicidade&lt;/strong&gt; para começar&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Estrutura&lt;/strong&gt; para crescer
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibilidade&lt;/strong&gt; para evoluir&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Seu próximo projeto provavelmente deveria começar como um monólito modular.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Depois, quando você tiver:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Produto validado&lt;/li&gt;
&lt;li&gt;✅ Time maior&lt;/li&gt;
&lt;li&gt;✅ Problemas reais de escala&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Aí sim&lt;/strong&gt; considere microserviços.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;E você, já experimentou o monólito modular? Compartilhe sua experiência nos comentários! 👇&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>laravel</category>
      <category>microservices</category>
      <category>programming</category>
    </item>
    <item>
      <title>Observers no Laravel</title>
      <dc:creator>Rodrigo Castro</dc:creator>
      <pubDate>Sat, 26 Jul 2025 14:50:02 +0000</pubDate>
      <link>https://forem.com/redrodrigoc/observers-no-laravel-3aae</link>
      <guid>https://forem.com/redrodrigoc/observers-no-laravel-3aae</guid>
      <description>&lt;p&gt;Se você já trabalhou com Laravel, provavelmente já precisou executar algumas ações automaticamente quando algo acontece com seus models. Criar logs quando um usuário é cadastrado, enviar emails quando um pedido é finalizado, ou limpar cache quando um produto é atualizado.&lt;/p&gt;

&lt;p&gt;A solução mais óbvia seria colocar essa lógica diretamente nos controllers ou nos próprios models. Mas convenhamos, isso vira uma bagunça rapidinho.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Laravel Observers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Os Observers são como aquele amigo atento que sempre sabe quando algo acontece e age automaticamente. Eles "observam" os eventos do Eloquent (created, updated, deleted, etc.) e executam código específico para cada situação.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Na prática, como funciona?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine que você tem um model User e quer enviar um email de boas-vindas sempre que alguém se cadastra:&lt;/p&gt;

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

&lt;p&gt;Depois é só registrar no AppServiceProvider:&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Por que usar Observers?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Primeiro, seu código fica muito mais organizado. Toda a lógica relacionada aos eventos do model fica concentrada em um lugar só. Segundo, você segue o princípio da responsabilidade única - o controller cuida da requisição, o model cuida dos dados, e o observer cuida dos efeitos colaterais. Terceiro ponto: testabilidade. É muito mais fácil testar um observer isoladamente do que toda a stack junta.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dica de ouro&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use observers para ações que sempre devem acontecer, independente de onde o model foi alterado. Se a ação é específica de um contexto (tipo "enviar email só quando o admin cadastra"), talvez seja melhor manter no controller mesmo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusão&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Os Observers são uma ferramenta poderosa para manter seu código Laravel limpo e organizável. Eles transformam aqueles "lembretes mentais" de executar certas ações em código automático e confiável.&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>laravel</category>
      <category>php</category>
      <category>programming</category>
    </item>
    <item>
      <title>Design System no Flutter</title>
      <dc:creator>Rodrigo Castro</dc:creator>
      <pubDate>Mon, 22 Jul 2024 18:01:57 +0000</pubDate>
      <link>https://forem.com/redrodrigoc/design-system-no-flutter-4d53</link>
      <guid>https://forem.com/redrodrigoc/design-system-no-flutter-4d53</guid>
      <description>&lt;p&gt;O desenvolvimento de aplicativos móveis eficazes requer não apenas uma base sólida em termos de funcionalidades, mas também uma abordagem coesa e consistente para o design da interface do usuário. Um Design System é fundamental para atingir esse objetivo, oferecendo um conjunto de padrões reutilizáveis e modularizados que promovem a consistência, eficiência e escalabilidade.&lt;/p&gt;

&lt;h3&gt;
  
  
  O que é um Design System?
&lt;/h3&gt;

&lt;p&gt;Um Design System é um conjunto de padrões e componentes reutilizáveis que auxiliam no desenvolvimento de UIs padronizadas, bonitas e obviamente garantindo uma experiência consistente todas as partes de um produto Digital. No Flutter (ou em qualquer outro frontend), o design system faz com que nós devs foquemos mais em solucionar os requisitos funcionais e menos em construir as mesmas telas padronizadas para o nosso aplicativo. &lt;/p&gt;

&lt;p&gt;1 - &lt;strong&gt;Configurando o projeto&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Primeiro vamos criar um novo projeto, podemos criar dentro da pasta principal do app e/ou criar um package externo para ser reutilizável.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flutter create &lt;span class="nt"&gt;--template&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;package design_system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso cria a estrutura básica do package onde você pode começar a adicionar seus componentes e estilos.&lt;/p&gt;

&lt;p&gt;2 - &lt;strong&gt;Definindo as diretrizes de design&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Antes de começar a codar, defina as diretrizes de design que seu sistema seguirá. Isso inclui:&lt;br&gt;
    - &lt;strong&gt;Paleta de Cores&lt;/strong&gt;: Defina cores primárias, secundárias, de fundo, de texto, etc.&lt;br&gt;
    - &lt;strong&gt;Tipografia&lt;/strong&gt;: Escolha fontes, tamanhos e estilos de texto.&lt;br&gt;
    - &lt;strong&gt;Componentes Personalizáveis&lt;/strong&gt;: Flutter permite criar componentes altamente personalizáveis e reutilizáveis.&lt;/p&gt;

&lt;p&gt;3 - &lt;strong&gt;Estruturando o package&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Organize seu package de maneira que seja fácil de entender e manter. Uma estrutura comum pode ser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nt"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nt"&gt;components&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="nc"&gt;.dart&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nt"&gt;theme&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nt"&gt;colors&lt;/span&gt;&lt;span class="nc"&gt;.dart&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nt"&gt;text_styles&lt;/span&gt;&lt;span class="nc"&gt;.dart&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nt"&gt;theme&lt;/span&gt;&lt;span class="nc"&gt;.dart&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nt"&gt;utils&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;       &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nt"&gt;spacing&lt;/span&gt;&lt;span class="nc"&gt;.dart&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nt"&gt;design_system&lt;/span&gt;&lt;span class="nc"&gt;.dart&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4 - &lt;strong&gt;Criando paleta de cores&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No arquivo &lt;code&gt;lib/src/theme/colors.dart&lt;/code&gt;, defina sua paleta de cores:&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="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter/material.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppColors&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt; &lt;span class="n"&gt;primary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xFF6200EE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt; &lt;span class="n"&gt;primaryVariant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xFF3700B3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt; &lt;span class="n"&gt;secondary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xFF03DAC6&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt; &lt;span class="n"&gt;secondaryVariant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xFF018786&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt; &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xFFFFFFFF&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt; &lt;span class="n"&gt;surface&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xFFFFFFFF&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xFFB00020&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt; &lt;span class="n"&gt;onPrimary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xFFFFFFFF&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt; &lt;span class="n"&gt;onSecondary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xFF000000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt; &lt;span class="n"&gt;onBackground&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xFF000000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt; &lt;span class="n"&gt;onSurface&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xFF000000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt; &lt;span class="n"&gt;onError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xFFFFFFFF&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;blockquote&gt;
&lt;p&gt;No flutter &lt;code&gt;0xFF&lt;/code&gt; representa uma cor hexadecimal&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;5 - &lt;strong&gt;Definindo estilos de texto&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No arquivo &lt;code&gt;lib/src/theme/text_styles.dart&lt;/code&gt;, defina seus estilos de texto:&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="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter/material.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TextStyles&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;TextStyle&lt;/span&gt; &lt;span class="n"&gt;headline1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TextStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;fontSize:&lt;/span&gt; &lt;span class="mi"&gt;96&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;fontWeight:&lt;/span&gt; &lt;span class="n"&gt;FontWeight&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;black&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;TextStyle&lt;/span&gt; &lt;span class="n"&gt;bodyText1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TextStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;fontSize:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;black&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// Adicione mais estilos conforme necessário&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;6 - &lt;strong&gt;Criando um tema&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No arquivo &lt;code&gt;lib/src/theme/theme.dart&lt;/code&gt;, defina seu tema:&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="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter/material.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'colors.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'text_styles.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppTheme&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;ThemeData&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;lightTheme&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;ThemeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;primaryColor:&lt;/span&gt; &lt;span class="n"&gt;AppColors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;primaryColorLight:&lt;/span&gt; &lt;span class="n"&gt;AppColors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;primaryVariant&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;textTheme:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;TextTheme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;displayLarge:&lt;/span&gt; &lt;span class="n"&gt;TextStyles&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;headline1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;bodyLarge:&lt;/span&gt; &lt;span class="n"&gt;TextStyles&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;bodyText1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;colorScheme:&lt;/span&gt; &lt;span class="n"&gt;ColorScheme&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromSwatch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;copyWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;secondary:&lt;/span&gt; &lt;span class="n"&gt;AppColors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;secondary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;surface:&lt;/span&gt; &lt;span class="n"&gt;AppColors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;

      &lt;span class="c1"&gt;// Adicione mais customizações conforme necessário&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;7 - &lt;strong&gt;Criando componentes reutilizáveis&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No arquivo &lt;code&gt;lib/src/components/button.dart&lt;/code&gt;, crie um componente de botão personalizado:&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="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter/material.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'../theme/colors.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomButton&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatelessWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;label&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;VoidCallback&lt;/span&gt; &lt;span class="n"&gt;onPressed&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;CustomButton&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;key&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;label&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;onPressed&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;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ElevatedButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;style:&lt;/span&gt; &lt;span class="n"&gt;ElevatedButton&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;styleFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;backgroundColor:&lt;/span&gt; &lt;span class="n"&gt;AppColors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;padding:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;EdgeInsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;symmetric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;vertical:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;horizontal:&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="c1"&gt;// Adicione mais propriedades de estilo conforme necessário&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="n"&gt;onPressed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;style:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;TextStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="n"&gt;AppColors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onPrimary&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;8 - &lt;strong&gt;Exportando seu design system&lt;/strong&gt;&lt;br&gt;
No arquivo &lt;code&gt;lib/design_system.dart&lt;/code&gt;, exporte todas as suas definições:&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="kn"&gt;library&lt;/span&gt; &lt;span class="n"&gt;design_system&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;export&lt;/span&gt; &lt;span class="s"&gt;'src/components/button.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;export&lt;/span&gt; &lt;span class="s"&gt;'src/theme/colors.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;export&lt;/span&gt; &lt;span class="s"&gt;'src/theme/text_styles.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;export&lt;/span&gt; &lt;span class="s"&gt;'src/theme/theme.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;9 - &lt;strong&gt;Usando o Design System em um projeto&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;flutter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;sdk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;flutter&lt;/span&gt;
  &lt;span class="na"&gt;design_system&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./design_system&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em seu projeto, importe e utilize o Design System:&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="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter/material.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:design_system/design_system.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;runApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyApp&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;MyApp&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatelessWidget&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;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;MaterialApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;theme:&lt;/span&gt; &lt;span class="n"&gt;AppTheme&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lightTheme&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;home:&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;appBar:&lt;/span&gt; &lt;span class="n"&gt;AppBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Design System Example'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
        &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;CustomButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;label:&lt;/span&gt; &lt;span class="s"&gt;'Press Me'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;h3&gt;
  
  
  Conclusão
&lt;/h3&gt;

&lt;p&gt;Criar um Design System no Flutter permite uma estrutura modular e reutilizável. Isso facilita a manutenção e a escalabilidade do seu aplicativo, garantindo uma experiência de usuário consistente e de alta qualidade. Com as diretrizes e componentes bem definidos, você pode rapidamente aplicar seu Design System em diferentes projetos e manter a uniformidade visual e funcional.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>designsystem</category>
      <category>braziliandevs</category>
      <category>dart</category>
    </item>
    <item>
      <title>Server Driven UI no Flutter?</title>
      <dc:creator>Rodrigo Castro</dc:creator>
      <pubDate>Wed, 29 May 2024 11:04:15 +0000</pubDate>
      <link>https://forem.com/redrodrigoc/server-driven-ui-no-flutter-367d</link>
      <guid>https://forem.com/redrodrigoc/server-driven-ui-no-flutter-367d</guid>
      <description>&lt;p&gt;O &lt;strong&gt;Server Driven UI&lt;/strong&gt; (SDUI) no Flutter surge como um &lt;strong&gt;game-changer&lt;/strong&gt; no cenário do desenvolvimento de aplicativos. Ao transferir a lógica da interface para o servidor, abre-se um universo de possibilidades para criar interfaces mais dinâmicas, personalizadas e eficientes. Imagine um app que se adapta em tempo real às suas necessidades, sem a necessidade de constantes atualizações. É isso e muito mais que o SDUI no Flutter oferece!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;game-changer&lt;/strong&gt; se refere a um “divisor de águas”, ou seja, algo que revoluciona e muda completamente um determinado mercado ou situação.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  O que é Server Driven UI?
&lt;/h3&gt;

&lt;p&gt;Em contraste com a abordagem tradicional, onde a interface do usuário (UI) é definida no cliente (aplicativo móvel), o SDUI transfere a responsabilidade para o servidor. Isso significa que o servidor gera e envia a estrutura da UI para o aplicativo, que a renderiza na tela do dispositivo. Essa inversão de controle traz diversos benefícios:&lt;/p&gt;

&lt;h4&gt;
  
  
  Maior Agilidade e Flexibilidade:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Desenvolvimento e testes mais rápidos&lt;/strong&gt;: Alterações na UI podem ser implementadas no servidor e propagadas instantaneamente para todos os usuários, sem a necessidade de atualizações de aplicativos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Experiência do usuário aprimorada&lt;/strong&gt;: A UI pode ser personalizada em tempo real, de acordo com o perfil e contexto de cada usuário.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Redução de custos de desenvolvimento&lt;/strong&gt;: O código da UI é centralizado no servidor, diminuindo a duplicação de esforços e otimizando o processo de desenvolvimento.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mas nem tudo são flores...&lt;/p&gt;

&lt;h4&gt;
  
  
  Desafios e Considerações:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Implementação&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Arquitetura robusta&lt;/strong&gt;: O servidor precisa ter capacidade de processar e enviar as informações da UI de forma eficiente, especialmente para um grande número de usuários simultâneos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comunicação confiável&lt;/strong&gt;: A comunicação entre o servidor e o aplicativo deve ser segura e resiliente a falhas de rede.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Segurança de dados&lt;/strong&gt;: É crucial implementar medidas de segurança rigorosas para proteger os dados dos usuários e evitar acessos não autorizados.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Experiência do usuário&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Latência&lt;/strong&gt;: A latência na comunicação entre o servidor e o aplicativo pode afetar a fluidez da UI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conectividade&lt;/strong&gt;: O SDUI depende de uma conexão de internet estável para funcionar corretamente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Acessibilidade&lt;/strong&gt;: É importante garantir que a UI gerada pelo servidor seja acessível a todos os usuários, incluindo aqueles com deficiências.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Exemplos de Bibliotecas SDUI para Flutter:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Mirai&lt;/li&gt;
&lt;li&gt;server_driven_ui &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Exemplo utilizando o Mirai:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Servidor&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"scaffold"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"appBar"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"appBar"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Cards"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"column"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"mainAxisAlignment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"crossAxisAlignment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"children"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sizedBox"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"height"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"card"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"elevation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"borderOnForeground"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"margin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"top"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"bottom"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"right"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"left"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"child"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"listTile"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"leading"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://avatars.githubusercontent.com/u/31713982?v=4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"height"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"padding"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"padding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"top"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"child"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Rodrigo Castro"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"align"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"style"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"fontSize"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"subtitle"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"padding"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"padding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"top"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"bottom"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"child"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="s2"&gt;"Desenvolvedor de Software com foco em Laravel e Flutter. (Open to Work)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"align"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"style"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"fontSize"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Flutter&lt;/strong&gt;:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

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

&lt;h4&gt;
  
  
  Conclusão:
&lt;/h4&gt;

&lt;p&gt;O SDUI no Flutter se apresenta como uma ferramenta poderosa para impulsionar a inovação e criar experiências de usuário excepcionais. Ao abraçar essa abordagem com cautela e planejamento estratégico, os desenvolvedores terão a oportunidade de revolucionar o cenário de desenvolvimento de aplicativos.&lt;/p&gt;

&lt;h4&gt;
  
  
  Para se aprofundar no assunto:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://robertocsd.medium.com/unraveling-sdui-a-deep-dive-into-server-driven-user-interfaces-using-mirai-in-flutter-e99cd3c81abe" rel="noopener noreferrer"&gt;Artigo "Server Driven UI with Mirai in Flutter"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://m.youtube.com/watch?v=sWIS18Njr3I" rel="noopener noreferrer"&gt;Vídeo "Flutter Server Driven UI é possível? Descubra neste vídeo!"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pub.dev/packages/server_driven_ui" rel="noopener noreferrer"&gt;Pacote "server_driven_ui" no Pub.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pub.dev/packages/mirai" rel="noopener noreferrer"&gt;Pacote "mirai" no Pub.dev&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>braziliandevs</category>
      <category>flutter</category>
      <category>dart</category>
      <category>programming</category>
    </item>
    <item>
      <title>Como abstrair sua aplicação flutter para não depender de packages</title>
      <dc:creator>Rodrigo Castro</dc:creator>
      <pubDate>Fri, 17 May 2024 15:52:45 +0000</pubDate>
      <link>https://forem.com/redrodrigoc/como-abstrair-sua-aplicacao-flutter-para-nao-depender-de-packages-1k68</link>
      <guid>https://forem.com/redrodrigoc/como-abstrair-sua-aplicacao-flutter-para-nao-depender-de-packages-1k68</guid>
      <description>&lt;p&gt;Flutter, o framework de UI do Google para criar aplicativos multiplataforma, é conhecido por sua extensa coleção de pacotes que simplificam o desenvolvimento. No entanto, confiar demais em pacotes pode tornar seu projeto vulnerável a problemas como descontinuação de pacotes, falta de manutenção ou incompatibilidades futuras. Abstrair sua aplicação para minimizar a dependência de pacotes pode aumentar a longevidade e a estabilidade do seu projeto. Neste artigo, vamos explorar estratégias para alcançar isso.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tópicos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Entenda suas Necessidades&lt;/li&gt;
&lt;li&gt;Use Interfaces para Abstração&lt;/li&gt;
&lt;li&gt;Implementação Própria de Funcionalidades Simples&lt;/li&gt;
&lt;li&gt;Módulos de Serviço&lt;/li&gt;
&lt;li&gt;Conclusão&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Entenda Suas Necessidades
&lt;/h2&gt;

&lt;p&gt;Antes de decidir abstrair seu aplicativo, é crucial entender as necessidades específicas do seu projeto. Nem todos os pacotes são iguais e alguns fornecem funcionalidades complexas que podem ser difíceis de replicar. Avalie se a funcionalidade fornecida pelo pacote é algo que você pode ou deve implementar por conta própria. &lt;br&gt;
Pergunte-se:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Este pacote é crucial para a funcionalidade principal do meu aplicativo?&lt;/li&gt;
&lt;li&gt;A funcionalidade é complexa ou pode ser implementada com uma solução personalizada?&lt;/li&gt;
&lt;li&gt;O pacote tem uma alta probabilidade de ser descontinuado?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Com essas informações em mãos, podemos elaborar algumas estratégias para o seu desacoplamento:&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Interfaces para Abstração
&lt;/h2&gt;

&lt;p&gt;Uma das melhores práticas para reduzir a dependência de pacotes é usar interfaces para definir a funcionalidade necessária. Em vez de depender diretamente de uma implementação de um pacote, você pode definir uma interface que descreve o comportamento necessário e, em seguida, fornecer uma implementação concreta que utiliza o pacote.&lt;/p&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Definindo a interface&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;LocalStorage&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="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;saveData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;value&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="kt"&gt;String&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;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Implementação usando um pacote (por exemplo, SharedPreferences)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SharedPreferencesStorage&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="n"&gt;LocalStorage&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;SharedPreferences&lt;/span&gt; &lt;span class="n"&gt;_prefs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;SharedPreferencesStorage&lt;/span&gt;&lt;span class="p"&gt;(&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;_prefs&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="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;saveData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;value&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;await&lt;/span&gt; &lt;span class="n"&gt;_prefs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&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="kt"&gt;String&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;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;key&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;return&lt;/span&gt; &lt;span class="n"&gt;_prefs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa forma, você pode facilmente substituir &lt;code&gt;SharedPreferencesStorage&lt;/code&gt; por outra implementação sem alterar o restante do código que depende de &lt;code&gt;LocalStorage&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementação Própria de Funcionalidades Simples
&lt;/h2&gt;

&lt;p&gt;Para funcionalidades simples, considere implementar você mesmo em vez de usar um pacote. Por exemplo, se você precisa apenas de uma solução simples de cache ou armazenamento local, pode ser mais fácil escrever sua própria implementação do que depender de um pacote.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exemplo de Cache Simples
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Define a classe SimpleCache&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SimpleCache&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;// Cria um mapa privado para armazenar pares de chave-valor  &lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="c1"&gt;// Método para adicionar dados ao cache&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;saveData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// Método para recuperar dados do cache&lt;/span&gt;
  &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Módulos de Serviço
&lt;/h2&gt;

&lt;p&gt;Separar a lógica de negócios em módulos de serviço pode ajudar a reduzir a dependência de pacotes. Esses módulos podem fornecer abstração sobre qualquer funcionalidade de terceiros, permitindo que você mude facilmente a implementação sem impactar outras partes do código.&lt;/p&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Define a classe AuthService&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Cria uma instância privada de FirebaseAuth&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;FirebaseAuth&lt;/span&gt; &lt;span class="n"&gt;_firebaseAuth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Construtor que aceita uma instância de FirebaseAuth&lt;/span&gt;
  &lt;span class="n"&gt;AuthService&lt;/span&gt;&lt;span class="p"&gt;(&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;_firebaseAuth&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Método para autenticar um usuário com email e senha&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;User&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;signIn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;password&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="c1"&gt;// Tenta autenticar o usuário com email e senha&lt;/span&gt;
      &lt;span class="n"&gt;UserCredential&lt;/span&gt; &lt;span class="n"&gt;userCredential&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;_firebaseAuth&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;signInWithEmailAndPassword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;email:&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;password:&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="c1"&gt;// Se a autenticação for bem-sucedida, retorna o User&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;userCredential&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Se ocorrer um erro, imprime o erro e retorna null&lt;/span&gt;
      &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error: &lt;/span&gt;&lt;span class="si"&gt;$e&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&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;// Método para deslogar o usuário atual&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="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;signOut&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;await&lt;/span&gt; &lt;span class="n"&gt;_firebaseAuth&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;signOut&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui, &lt;code&gt;AuthService&lt;/code&gt; abstrai a implementação do &lt;code&gt;FirebaseAuth&lt;/code&gt;, permitindo que você substitua facilmente &lt;code&gt;_firebaseAuth&lt;/code&gt; por outra solução de autenticação no futuro.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gerenciamento de Estado Independente de Pacotes
&lt;/h2&gt;

&lt;p&gt;O gerenciamento de estado é uma área onde muitos desenvolvedores dependem de pacotes como Provider, Bloc ou Riverpod. No entanto, é possível gerenciar o estado de forma eficiente sem depender de pacotes externos, utilizando apenas as funcionalidades nativas do Flutter, como &lt;code&gt;InheritedWidget&lt;/code&gt;, &lt;code&gt;ChangeNotifier&lt;/code&gt; e &lt;code&gt;ValueNotifier&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exemplo usando &lt;code&gt;ChangeNotifier&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Define a classe Counter que notifica os ouvintes quando o valor do contador muda&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;ChangeNotifier&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Inicializa o contador como 0&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Getter para obter o valor atual do contador&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;count&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;_count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Método para incrementar o contador&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Incrementa o contador&lt;/span&gt;
    &lt;span class="n"&gt;notifyListeners&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// Notifica os ouvintes sobre a mudança&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Define a classe CounterProvider que fornece uma instância de Counter para seus descendentes&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CounterProvider&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;InheritedWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Mantém uma referência para a instância de Counter&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;Counter&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Construtor que aceita um filho e uma instância de Counter&lt;/span&gt;
  &lt;span class="n"&gt;CounterProvider&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;child&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;counter&lt;/span&gt;&lt;span class="p"&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="nl"&gt;key:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Método para obter a instância mais próxima de CounterProvider na árvore de widgets&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;CounterProvider&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;dependOnInheritedWidgetOfExactType&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CounterProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Método para determinar se este widget deve notificar seus descendentes quando é reconstruído&lt;/span&gt;
  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;updateShouldNotify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CounterProvider&lt;/span&gt; &lt;span class="n"&gt;oldWidget&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Retorna true se a instância de Counter mudou&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;oldWidget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;counter&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;Abstrair sua aplicação Flutter para não depender de pacotes envolve um equilíbrio entre reutilização de código e a criação de uma base sólida e independente. Usando interfaces, implementando funcionalidades simples por conta própria e separando a lógica em módulos de serviço, você pode reduzir a dependência de pacotes externos e aumentar a flexibilidade e a longevidade do seu projeto. Adotar essas práticas pode exigir um esforço adicional no início, mas os benefícios a longo prazo de um código mais limpo e sustentável valem a pena.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>braziliandevs</category>
      <category>dart</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
