<?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: Carol Rocha Floro</title>
    <description>The latest articles on DEV Community by Carol Rocha Floro (@carolrochafloro).</description>
    <link>https://dev.to/carolrochafloro</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%2F1348839%2Fd6eef778-fa01-489e-b8b4-0f9c5d3added.jpeg</url>
      <title>DEV Community: Carol Rocha Floro</title>
      <link>https://dev.to/carolrochafloro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/carolrochafloro"/>
    <language>en</language>
    <item>
      <title>Event Sourcing</title>
      <dc:creator>Carol Rocha Floro</dc:creator>
      <pubDate>Sat, 28 Jun 2025 12:22:55 +0000</pubDate>
      <link>https://dev.to/carolrochafloro/event-sourcing-2a68</link>
      <guid>https://dev.to/carolrochafloro/event-sourcing-2a68</guid>
      <description>&lt;h2&gt;
  
  
  O problema
&lt;/h2&gt;

&lt;p&gt;Recentemente na empresa meu gestor mencionou um pattern que eu não conhecia, o &lt;strong&gt;Event Sourcing&lt;/strong&gt;. A proposta era uma solução para um problema complexo que tínhamos no banco: controlar de forma eficiente e confiável o total transferido por clientes para um fundo de investimentos e quanto falta transferir baseado em um compromisso assinado por esses clientes, compromisso esse que eventualmente pode ser transferido para outros clientes. &lt;/p&gt;

&lt;p&gt;Sabendo que poderíamos simplesmente fazer um CRUD e acessar essa informação quando necessário, por que optar por um design pattern diferente, que adiciona uma camada de complexidade?&lt;/p&gt;

&lt;p&gt;Nossa intenção era tornar possível reconstruir o estado da aplicação em qualquer momento do tempo, não apenas obter o estado atual. Assim conseguiríamos montar uma "linha do tempo" de cada cliente em relação ao fundo de investimento do qual ele participa, e uma do fundo como um todo.&lt;/p&gt;

&lt;h2&gt;
  
  
  As vantagens do Event Sourcing
&lt;/h2&gt;

&lt;p&gt;Ao utilizar o Event Sourcing, cria-se um sistema totalmente auditável e com a possibilidade de reconstruir o estado da aplicação em qualquer momento. Ao invés de salvar os dados como estão, são salvos os eventos que levaram ao estado, o que pode ser útil em sistemas que exigem rastreabilidade detalhada por questões legais, como bancos ou aplicações de saúde.&lt;/p&gt;

&lt;p&gt;Esse pattern também facilita a testabilidade e o debug, pois ao reprocessar os eventos é possível reproduzir qualquer cenário ocorrido.&lt;/p&gt;

&lt;p&gt;Com a publicação em uma fila ou exchange, outras aplicações podem consumir esses eventos também e processa-los conforme a própria necessidade.&lt;/p&gt;

&lt;p&gt;Suponha que você tem uma conta corrente e quer saber o saldo dessa conta, mas também quer exibir o extrato dela. Ao utilizar o Event Sourcing você salva cada evento ocorrido - ou seja, cada alteração naquele estado, e pode reconstruir o saldo da conta a qualquer momento.&lt;/p&gt;

&lt;h2&gt;
  
  
  Premissas e conceitos
&lt;/h2&gt;

&lt;p&gt;Existem algumas premissas para a correta implementação do Event Sourcing: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Os eventos são imutáveis: para garantir a confiabilidade dos dados, não é possível alterar eventos já registrados. Para fazer correções, é preciso registrar um evento de compensação;&lt;/li&gt;
&lt;li&gt;Todo evento é reversível ou contém nele os dados necessários para sua reversão, quando aplicável: aqui é importante ressaltar a diferença entre definir um valor e adicionar um valor. Por exemplo, se a conta A tinha o saldo de R$10,00, podemos definir o novo valor como R$20,00 ou adicionar a ela R$10,00 através de um evento. Para que a reversão aconteça, o melhor é salvar o evento de adição e, caso necessário, registrar um evento oposto;&lt;/li&gt;
&lt;li&gt;Eventos fazem parte da linguagem ubíqua: todos precisam ser compreensíveis para os stakeholders e devem ter nomes claros;&lt;/li&gt;
&lt;li&gt;Todo evento deve ter um nome no pretérito perfeito: considerando que um evento sempre é algo que ocorreu no passado, é importante que o nome além de claro reflita o que aconteceu e não uma intenção;&lt;/li&gt;
&lt;li&gt;A ordem importa: eventos devem ser registrados na ordem em que ocorreram. Esse assunto vai ser abordado com mais profundidade ao longo do texto;&lt;/li&gt;
&lt;li&gt;Eventos devem ser versionáveis: o schema de um evento pode mudar ao longo do tempo, por isso é importante preparar os handlers para lidar com diferentes versões de eventos. Para isso, pode-se adicionar um campo "version" no documento, a versão como sufixo do nome do evento ou, em último caso, atualizar eventos antigos (mas isso quebra a imutabilidade);&lt;/li&gt;
&lt;li&gt;Idempotência: handlers de eventos precisam ser idempotentes, principalmente considerando que é uma boa prática aplicar retries para garantir o processamento de todos os eventos. Não deve ser possível processar o mesmo evento mais de uma vez. Além de utilizar Ids únicos para cada evento, é importante manter uma tabela ou cache de eventos já processados e ignorar os eventos já aplicados;&lt;/li&gt;
&lt;li&gt;Não é uma boa prática armazenar o estado junto ao evento, tanto pelo acoplamento gerado que dificulta mudanças na lógica de negócios quanto pela necessidade extra de processamento dos eventos passados para chegar ao estado e processar o evento em questão.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mas o que é um evento? Segundo &lt;a href="https://cqrs.wordpress.com/wp-content/uploads/2010/11/cqrs_documents.pdf" rel="noopener noreferrer"&gt;Greg Young&lt;/a&gt;, evento é algo que ocorreu no passado e representou uma alteração no estado da aplicação. Um evento torna os efeitos colaterais dessa mudança explícitos - sabemos que se a conta A tem R$20,00 agora é porque esse saldo foi adicionado, podemos saber quem adicionou, quando, e se foi subtraído algum valor. Quando apenas acontece a alteração do estado, por exemplo, foi definido o valor de R$20,00 no saldo da conta A, não se sabe o que aconteceu para que se chegasse àquele valor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reprocessar todos os eventos sempre?
&lt;/h2&gt;

&lt;p&gt;Com tudo isso em mente, pode surgir uma dúvida: toda vez que for necessário acessar o estado atual da aplicação será preciso processar todos os eventos? Qual é o custo disso para a memória?&lt;/p&gt;

&lt;p&gt;Realmente quando se trata de uma enorme quantidade de eventos poderíamos ter um custo considerável de memória e atrasos na exibição do estado para os usuários. Para resolver esse problema, pode-se utilizar snapshots, que representam o estado da aplicação em um determinado momento. Eles podem ser criados em paralelo ao funcionamento da aplicação de acordo com regras definidas, como "salvar uma vez por dia" ou "salvar o último estado depois do registro de um evento".&lt;/p&gt;

&lt;p&gt;Com os snapshots, ao precisar reconstruir o estado basta buscar o snapshot mais próximo ao estado desejado e reprocessar somente os eventos subsequentes.&lt;/p&gt;

&lt;p&gt;É importante ressaltar que o snapshot não substitui os eventos, justamente por representar o estado em um determinado momento apenas. Ele pode ficar salvo na mesma base dos eventos, em bancos otimizados para leitura ou até mesmo na memória a depender da necessidade da aplicação. &lt;/p&gt;

&lt;h2&gt;
  
  
  Event Sourcing e outros patterns
&lt;/h2&gt;

&lt;p&gt;O Event Sourcing combina muito bem com o CQRS (Command-Query Responsability Segregation), favorecendo sistemas distribuídos. Os comandos criam eventos ao invés de alterar diretamente os dados, os eventos são utilizados para gerar read models otimizados (que podem também ser os snapshots). Dessa forma, escrita e leitura podem escalar de forma independente.&lt;/p&gt;

&lt;p&gt;Alternativamente ao Event Sourcing mas com a finalidade de permitir a auditabilidade, é possível utilizar o CDC (Change Data  Capture) que monitora alterações diretamente no banco de dados e permite auditabilidade técnica, mas não semântica.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quando não usar e desafios
&lt;/h2&gt;

&lt;p&gt;É verdade que esse pattern não se aplica a qualquer sistema. Suas vantagens são percebidas em aplicações complexas que exigem rastreabilidade, já que a complexidade para lidar com os eventos levando em consideração todas as premissas aumenta a curva de aprendizado. Além disso, há um custo de armazenamento e manutenção dos eventos e a dificuldade de fazer consultas simples direto no banco de dados, já que para chegar ao estado atual todos os eventos precisam ser processados.&lt;/p&gt;

&lt;p&gt;Existem outros desafios a serem enfrentados quando se aplica esse pattern. É preciso lidar com a consistência eventual, garantindo que o usuário tenha ciência desse delay entre o evento e seu processamento. Além disso, pela assincronicidade do sistema, é possível que dois eventos concorrentes cheguem na ordem errada. Para garantir que os eventos sejam salvos na ordem correta, deve haver uma validação de timestamp ou id incremental.&lt;/p&gt;

&lt;p&gt;Há um risco a ser observado no desenvolvimento: quando um handler gera um evento que ativa o mesmo handler o sistema pode entrar em um loop infinito.&lt;/p&gt;

&lt;p&gt;Sobre os handlers, é importante destacar que devem apenas lidar com os eventos e salva-los de forma durável antes de produzir quaisquer outros efeitos.&lt;/p&gt;

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

&lt;p&gt;O Event Sourcing traz uma série de vantagens para aplicações de domínio complexo em sistemas distribuídos, principalmente quando há necessidade de auditabilidade dos dados. Ainda assim, deve ser aplicado considerando os tradeoffs mencionados anteriormente.&lt;/p&gt;

</description>
      <category>eventsourcing</category>
      <category>designpatterns</category>
      <category>programming</category>
      <category>backend</category>
    </item>
    <item>
      <title>React para uma dev back-end</title>
      <dc:creator>Carol Rocha Floro</dc:creator>
      <pubDate>Sat, 14 Jun 2025 01:08:17 +0000</pubDate>
      <link>https://dev.to/carolrochafloro/react-para-uma-dev-back-end-5fad</link>
      <guid>https://dev.to/carolrochafloro/react-para-uma-dev-back-end-5fad</guid>
      <description>&lt;p&gt;No dia a dia do meu trabalho atuo com muito back-end usando C# e .NET, tanto dando manutenção e criando novas features quando criando soluções do zero - agora posso dizer isso, já criei minha primeira API do zerinho! Também tenho alguma familiaridade com Javascript e Typescript e CSS, então não vou entrar nesses pormenores aqui, vou focar mais na arquitetura e nas features do React e o que encontrei de novidade pra mim.&lt;/p&gt;

&lt;p&gt;Embora seja back-ender de coração, sou contratada como fullstack e eventualmente preciso fazer algo relacionado a front-end. Já criei algumas features e fiz pequenos ajustes em React e Vue mas dessa vez recebi uma demanda diferente: criar uma tela do zero pra um novo produto. Uma tela simples, mas ainda cheia de regras de negócio importantes a serem seguidas. &lt;/p&gt;

&lt;p&gt;Como a demanda se divide em front e back, optei por deixar o back o mais redondo possível para só então começar o front - procrastinando a tarefa mais difícil na cara de pau. &lt;/p&gt;

&lt;p&gt;Quando chegou a hora de começar o front, peguei alguns projetos como referência, baixei o boilerplate do projeto inicial e deu branco: &lt;strong&gt;por onde começo?&lt;/strong&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Criando a UI
&lt;/h2&gt;

&lt;p&gt;Resolvi seguir uma estratégia top-down na divisão e criação dos componentes. Também optei por criar todo o esqueleto da página para só no final adicionar lógica e refinar os estilos caso necessário (spoiler: foi necessário). Essa parte foi relativamente mais tranquila porque usei componentes do design system do banco, embora eu prefira criar tudo na mão preciso confessar que foi uma mão na roda - pelo menos os que não precisei estilizar.&lt;/p&gt;

&lt;p&gt;Na hora de adicionar a lógica, tendo alguns projetos como base, optei por manter o máximo possível os métodos separados do componente em si, então minha estrutura ficou dessa forma para cada componente:&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%2F769wf0re8s2j2bexpvzb.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%2F769wf0re8s2j2bexpvzb.png" alt="Uma pasta chamada Header contendo três arquivos: index.tsx, style.scss e methods.ts" width="174" height="93"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Criado o esqueleto, criei os services que vão se comunicar com a API utilizando Axios. Para isso criei as interfaces de parâmetros e objetos a serem recebidos e um arquivo de config do Axios exportando a configuração com a URL base da API. Implementei a princípio somente os services que iriam obter os dados para apagar os mocks e começar a trabalhar com dados reais na tela, deixando os services de post e put para um segundo momento.&lt;/p&gt;

&lt;h2&gt;
  
  
  Estado
&lt;/h2&gt;

&lt;p&gt;Aqui vale mencionar alguns conceitos importantes relacionados ao front-end e à forma como o React lida com o &lt;strong&gt;estado&lt;/strong&gt; da aplicação: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Estado é uma representação dos dados em um componente, como o conteúdo de um formulário ou um item selecionado.&lt;/li&gt;
&lt;li&gt;Gerenciamento de estado: ajuda a controlar esses dados entre os componentes quando é necessário o compartilhamento entre eles, evitando que sejam passados como propriedades por diversos componentes da árvore (o chamado &lt;em&gt;prop drilling&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;O React utiliza um &lt;strong&gt;hook&lt;/strong&gt; chamado &lt;strong&gt;useState&lt;/strong&gt; para gerenciar o estado local, ou seja, dentro de um componente. Já para o estado global, temos a ContextAPI do próprio React ou o Redux, que oferece opções mais robustas e complexas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Como preciso de dados de diversos componentes para montar uma requisição para a API, decidi criar esse estado global com os valores iniciais vazios. Para isso, usei a ContextAPI já que se trata de uma aplicação relativamente simples.&lt;/p&gt;

&lt;p&gt;Para fins de exemplo vou criar o gerenciamento de estado para um usuário:&lt;br&gt;
1- Criar o contexto utilizando o hook useContext:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const UserContext = createContext();

export const useUser = () =&amp;gt; useContext(UserContext);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2- Criar um provider, que vai envolver os outros componentes e fornecer o estado do contexto para eles. Aqui o estado inicial foi definido como vazio:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const UserProvider = ({ children }) =&amp;gt; {
  const [user, setUser] = useState(null);

  return (
    &amp;lt;UserContext.Provider value={{ user, setUser }}&amp;gt;
      {children}
    &amp;lt;/UserContext.Provider&amp;gt;
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3- Envolver a aplicação com o provider, para que todos os componentes tenham acesso ao contexto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const App = () =&amp;gt; (
  &amp;lt;UserProvider&amp;gt;
    &amp;lt;UserProfile /&amp;gt; // Todos os elementos da aplicação ficam dentro do provider
  &amp;lt;/UserProvider&amp;gt;
);

ReactDOM.render(&amp;lt;App /&amp;gt;, document.getElementById('root'));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com esses 3 passos, é possível então consumir o contexto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const UserProfile = () =&amp;gt; {
  const { user, setUser } = useUser();

  const handleLogin = () =&amp;gt; {
    setUser({ name: 'Exemplo', email: 'exemplo@email.com' });
  };

  return (
    &amp;lt;div&amp;gt;
      {user ? (
        &amp;lt;div&amp;gt;
          &amp;lt;h1&amp;gt;Bem-vindo, {user.name}&amp;lt;/h1&amp;gt;
          &amp;lt;p&amp;gt;Email: {user.email}&amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;
      ) : (
        &amp;lt;button onClick={handleLogin}&amp;gt;Login&amp;lt;/button&amp;gt;
      )}
    &amp;lt;/div&amp;gt;
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Repare que aqui foi utilizado um ternário para definir se vai ser exibida a div com as boas vindas ao usuário ou o botão de login. Outra forma possível seria utilizar o operador &amp;amp;&amp;amp;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return (
    &amp;lt;div&amp;gt;
      {user &amp;amp;&amp;amp; (
        &amp;lt;div&amp;gt;
          &amp;lt;h1&amp;gt;Bem-vindo, {user.name}&amp;lt;/h1&amp;gt;
          &amp;lt;p&amp;gt;Email: {user.email}&amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;
      );
    &amp;lt;/div&amp;gt;
  );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nessa segunda forma, se o user não estivesse setado, nada seria exibido. É importante não utilizar números no lado esquerdo do operador &amp;amp;&amp;amp;, apenas comparações ou valores que podem ser convertidos em booleanos (por exemplo, se existe um user).&lt;/p&gt;

&lt;h2&gt;
  
  
  Listas
&lt;/h2&gt;

&lt;p&gt;Para exibir os elementos de um array, deve-se usar as funções Map ou Filter do JS dessa forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const itemArray = ["item1", "item2", "item3"];

export const DisplayItems = () =&amp;gt; {
    return(
      itemArray.map((item) =&amp;gt; (&amp;lt;p&amp;gt;{item}&amp;lt;/p&amp;gt;)
  );
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  E agora?
&lt;/h2&gt;

&lt;p&gt;Depois de uma longa jornada, minha demanda está finalmente em produção! Encarar esse desafio me tornou uma desenvolvedora melhor, não só por aprender sobre mais uma tecnologia mas porque aprendi a pensar o desenvolvimento em si de uma forma diferente. &lt;br&gt;
Se você, back-ender, precisa encarar uma demanda de front, saiba: this too shall pass. E não, não é o fim do mundo. Tente entender o padrão utilizado pela sua empresa, pesquise boas práticas, leia o código dos colegas e lembre-se: o debug é uma m**** mas pelo menos o feedback é imediato!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Design Patterns em C# - Builder</title>
      <dc:creator>Carol Rocha Floro</dc:creator>
      <pubDate>Mon, 24 Feb 2025 16:17:21 +0000</pubDate>
      <link>https://dev.to/carolrochafloro/design-patterns-em-c-builder-2jnf</link>
      <guid>https://dev.to/carolrochafloro/design-patterns-em-c-builder-2jnf</guid>
      <description>&lt;p&gt;&lt;em&gt;Repositório: &lt;a href="https://github.com/carolrochafloro/DesignPatternsPoC/tree/main/DesignPatternsPoC" rel="noopener noreferrer"&gt;https://github.com/carolrochafloro/DesignPatternsPoC/tree/main/DesignPatternsPoC&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sobre o pattern
&lt;/h2&gt;

&lt;p&gt;O builder pattern permite construir objetos complexos sem a necessidade de criar diversas subclasses herdando da classe principal e sem sobrecarregar o construtor da classe com inúmeros parâmetros, reduzindo a complexidade do código.&lt;/p&gt;

&lt;p&gt;Deve ser utilizado quando a construção do objeto precisar ficar separada das partes desse objeto ou quando o processo de construção precisar permitir diferentes representações do mesmo objeto.&lt;/p&gt;

&lt;h3&gt;
  
  
  Estrutura
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Builder interface
&lt;/h4&gt;

&lt;p&gt;Especifica uma interface abstrata para criar partes do produto (objeto).&lt;/p&gt;

&lt;h4&gt;
  
  
  ConcreteBuilder
&lt;/h4&gt;

&lt;p&gt;Constrói as partes implementando a Builder interface, define a representação do objeto, oferece uma interface para obter o produto.&lt;/p&gt;

&lt;h4&gt;
  
  
  Director
&lt;/h4&gt;

&lt;p&gt;Chama a Builder interface para construir o objeto.&lt;/p&gt;

&lt;h4&gt;
  
  
  Product
&lt;/h4&gt;

&lt;p&gt;É o objeto criado pelo builder. Pode incluir classes que definem as partes que o constituem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Como funciona
&lt;/h3&gt;

&lt;p&gt;O client instancia a classe Director e configura com o Builder referente ao objeto desejado.&lt;br&gt;
A classe Director notifica o builder quando uma parte deve ser construída.&lt;br&gt;
O builder lida com os requests adicionando as partes do produto.&lt;br&gt;
O client obtém o produto do builder.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vantagens
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Permite variar a representação interna de um objeto: como o objeto é construído através de uma interface genérica, para mudar a representação interna do mesmo só é preciso definir um novo tipo de builder;&lt;/li&gt;
&lt;li&gt;Isola os códigos de construção e representação, melhorando a modularidade do código;&lt;/li&gt;
&lt;li&gt;Oferece maior controle do processo de construção: permite a definição de uma ordem específica para a construção e só permite que o client tenha acesso ao objeto ao final do processo de construção.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;A builder interface precisa ser genérica o suficiente para permitir a construção de products para todos os tipos de concrete builders;&lt;/li&gt;
&lt;li&gt;Pode ser preciso acessar partes do produto antes do final da construção, embora não seja o caso na maioria das vezes;&lt;/li&gt;
&lt;li&gt;Na maioria dos casos, os produtos vão ser tão diferentes entre si que não faz sentido criar uma classe abstrata para todos herdarem. O client vai configurar a classe director com o concrete builder necessário.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Como eu fiz
&lt;/h2&gt;

&lt;p&gt;Agora vou descrever o meu passo a passo para criar um builder de personagens de RPG. O tema não foi escolhido por acaso, meu filho é apaixonado por RPG de mesa e a escolha foi pensando nele, que me ajudou com alguns detalhes.&lt;/p&gt;

&lt;p&gt;Optei por uma versão stepwise do builder, definindo uma ordem certa para que nenhuma propriedade deixe de ser setada pelo usuário. Para isso, usei interfaces para cada passo, com o método correspondente retornando a interface seguinte. A implementação é bem simples, embora repetitiva. &lt;/p&gt;

&lt;p&gt;Criada a classe Character, defini o construtor para receber uma instância de CharacterBuilder e setar as propriedades conforme os valores recebidos no builder.&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%2Fkx0s0ojugb19bfatjyyu.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%2Fkx0s0ojugb19bfatjyyu.png" alt="Trecho de código disponível no github" width="332" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Criei também as interfaces de cada etapa do processo de criação do personagem, sempre recebendo o parâmetro correspondente e retornando a interface seguinte.&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%2Fjsd4obbfkjz24hg37hxf.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%2Fjsd4obbfkjz24hg37hxf.png" alt="Trecho de código disponível no github" width="264" height="76"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após criar a entidade e as interfaces, criei o builder implementando todas as interfaces do passo a passo, com as mesmas propriedades da entidade, o construtor privado e o método inicial static, para que só fosse possível iniciar a construção por esse método, que retorna uma instância do próprio construtor.&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%2Fy2jrqu7kec4ese05a3ct.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%2Fy2jrqu7kec4ese05a3ct.png" alt="Trecho de código disponível no github" width="800" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Por último, implementei todas as interfaces até chegar ao último método em que chamei o construtor do personagem passando a própria classe builder como parâmetro e retornei o mesmo.&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%2Fdb268egbnyukxg2wwpx7.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%2Fdb268egbnyukxg2wwpx7.png" alt="Trecho de código disponível no github" width="353" height="266"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como tive uma experiência recente no trabalho em que precisava construir um objeto complexo para o desenvolvimento de testes de integração, quando estudei essa implementação do builder com os passos definidos achei uma excelente ideia, já que quando existem muitas propriedades é possível que a gente deixe passar alguma e encontre erros mais pra frente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://refactoring.guru/pt-br/design-patterns/builder" rel="noopener noreferrer"&gt;Refactoring.guru&lt;/a&gt;&lt;br&gt;
Design Patterns: elements of reusable object-oriented software&lt;/p&gt;

</description>
      <category>designpatterns</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
