<?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: Meriéli Manzano</title>
    <description>The latest articles on DEV Community by Meriéli Manzano (@merielimanzano).</description>
    <link>https://dev.to/merielimanzano</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%2F905006%2F77d91549-141c-41e3-9e92-bb7cc00ebed4.png</url>
      <title>DEV Community: Meriéli Manzano</title>
      <link>https://dev.to/merielimanzano</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/merielimanzano"/>
    <language>en</language>
    <item>
      <title>Dê significado aos seus dados: Objetos de Valor na prática</title>
      <dc:creator>Meriéli Manzano</dc:creator>
      <pubDate>Thu, 28 May 2026 20:29:58 +0000</pubDate>
      <link>https://dev.to/merielimanzano/de-significado-aos-seus-dados-objetos-de-valor-na-pratica-1a0p</link>
      <guid>https://dev.to/merielimanzano/de-significado-aos-seus-dados-objetos-de-valor-na-pratica-1a0p</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Pare de usar string para tudo e comece a expressar suas regras de negócio com clareza e segurança&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Você já se pegou repetindo as mesmas validações de CPF, e-mail ou telefone em várias partes do sistema? Sentiu que seus modelos de domínio estão anêmicos, cheios de getters e setters, mas sem comportamento real? Se sim, é hora de conhecer o verdadeiro poder dos &lt;strong&gt;Objetos de Valor&lt;/strong&gt; &lt;em&gt;(Value Objects)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Neste artigo, vamos mergulhar fundo nesse conceito transformador. Você vai entender por que Objetos de Valor garantem consistência, eliminam duplicação e tornam seu código mais expressivo e seguro. Prepare-se para elevar o nível da sua modelagem de domínio!&lt;/p&gt;

&lt;p&gt;Imagine um CPF: &lt;code&gt;123.456.789-00&lt;/code&gt;. O que importa é o número em si, não uma identidade única que o acompanhe. Se dois CPFs têm o mesmo número, eles são &lt;strong&gt;iguais&lt;/strong&gt; – não importa se foram instanciados em momentos diferentes ou em lugares distintos. Essa é a alma do Objeto de Valor.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Definição:&lt;/strong&gt; Um Objeto de Valor é um tipo de classe que representa um conceito abstrato, sem identidade própria (não possui ID). Ele é definido apenas por suas propriedades, encapsulando dentro de si um ou mais valores e suas respectivas regras de negócio.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Imutável:&lt;/strong&gt; uma vez criado, nunca muda. Para alterar, cria-se uma nova instância.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comparado por atributos:&lt;/strong&gt; dois Value Objects são iguais se todos os seus atributos forem iguais.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-validado:&lt;/strong&gt; ao ser instanciado, já garante que o valor é consistente com as regras do domínio.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Exemplos clássicos:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPF, CNPJ, CEP, telefone&lt;/li&gt;
&lt;li&gt;Endereço (composto por logradouro, número, cidade, CEP)&lt;/li&gt;
&lt;li&gt;Email, senha hash, duração de tempo, preço, nome próprio, cor, moeda&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Por que priorizar Objetos de Valor?
&lt;/h2&gt;

&lt;p&gt;Muitos desenvolvedores, quando pensam em DDD, correm imediatamente para as Entidades. Mas o próprio Eric Evans traz uma orientação poderosa:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Devemos nos esforçar para modelar utilizando Objetos de Valor, em vez de Entidades, sempre que possível. Mesmo quando um conceito de domínio precisa ser modelado como uma Entidade, o projeto da Entidade deve favorecer o uso de um contêiner de valores, em vez de um contêiner de Entidades filho.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Isso significa que o primeiro local para armazenar nossas regras de negócio é no Objeto de Valor, e por isso uma Entidade precisa compor Objetos de Valor, evitando ter Entidades dentro de Entidades.&lt;/p&gt;

&lt;p&gt;Os benefícios do Objeto de Valor são enormes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reuso imediato: Um Email ou CPF pode ser usado em qualquer lugar (Usuário, Cliente, Fornecedor) sem repetir regras.&lt;/li&gt;
&lt;li&gt;Código mais expressivo: Em vez de string $email, temos Email $email. O tipo já revela a intenção e as restrições.&lt;/li&gt;
&lt;li&gt;Testabilidade facilitada: Testar as regras de um Value Object isolado é trivial.&lt;/li&gt;
&lt;li&gt;Imutabilidade e segurança: Sem side-effects; objetos podem ser compartilhados sem risco.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mesmo que seu projeto não adote formalmente o DDD (Domain-Driven Design, uma abordagem que coloca o negócio e seu vocabulário no centro do código), usar objetos de valor vale a pena porque eles eliminam a duplicação de validações e garantem consistência em qualquer arquitetura.&lt;/p&gt;

&lt;p&gt;Se até aqui você já aprendeu algo, compartilhe este artigo com quem precisa de mais consistência e menos duplicação.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sinal de alerta para extrair um Value Object
&lt;/h2&gt;

&lt;p&gt;Quando você perceber várias classes com os mesmos atributos (ex.: &lt;code&gt;string $cpf&lt;/code&gt;, &lt;code&gt;string $email&lt;/code&gt;, &lt;code&gt;string $telefone&lt;/code&gt;), cada uma validando do seu próprio jeito, é um forte indicativo de que esses atributos merecem se tornar Objetos de Valor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Objetos de Valor vs Entidades: quando usar cada um?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Entidades
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Identidade:&lt;/strong&gt; Possui um ID único que a rastreia ao longo do tempo e o que a distingue de outras entidades.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mutabilidade:&lt;/strong&gt; Mutável (seus atributos podem mudar, mas a identidade permanece).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Igualdade:&lt;/strong&gt; Comparação por identidade (ID)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exemplos de uso:&lt;/strong&gt; Pessoa, Pedido, Conta Bancária, Produto&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Objetos de Valor
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Identidade:&lt;/strong&gt; Não tem identificador único; é definido por seus atributos ou por seu valor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mutabilidade:&lt;/strong&gt; Imutável.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Igualdade:&lt;/strong&gt; Comparação estrutural (todos os atributos/valores).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exemplos de uso:&lt;/strong&gt; CPF, Email, Endereço, Cor, Dinheiro&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Construindo um Value Object na Prática
&lt;/h2&gt;

&lt;p&gt;Vamos implementar um &lt;code&gt;Email&lt;/code&gt;, usando uma classe abstrata genérica para reaproveitar o método equals e definir por padrão o $value como readonly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Shared/ValueObject.php&lt;/span&gt;
&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;Shared&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cd"&gt;/**
 * @template TInput
 */&lt;/span&gt;
&lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ValueObject&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * @param  TInput  $value
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;mixed&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * @param  self&amp;lt;TInput&amp;gt;  $other
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;self&lt;/span&gt; &lt;span class="nv"&gt;$other&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nv"&gt;$other&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&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;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nv"&gt;$other&lt;/span&gt;&lt;span class="o"&gt;-&amp;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="cd"&gt;/**
     * @param  self&amp;lt;TInput&amp;gt;  $other
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;notEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;self&lt;/span&gt; &lt;span class="nv"&gt;$other&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;!&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="nf"&gt;equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$other&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;Agora, o Value Object concreto Email:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;Domain\Account\User\Domain\ValueObjects&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Domain\Account\User\Domain\Exceptions\InvalidEmailException&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Shared\ValueObject&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cd"&gt;/**
 * Email value object handles domain validation for emails.
 *
 * @extends ValueObject&amp;lt;string&amp;gt;
 */&lt;/span&gt;
&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Email&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ValueObject&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$trimmed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;mb_strtolower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;mb_trim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;filter_var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$trimmed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;FILTER_VALIDATE_EMAIL&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;InvalidEmailException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"The email '&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;' is invalid."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$trimmed&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$local&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;explode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'@'&lt;/span&gt;&lt;span class="p"&gt;,&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;value&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$domain&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;explode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'@'&lt;/span&gt;&lt;span class="p"&gt;,&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;value&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&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;Observações importantes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O construtor já valida e normaliza (minúsculas, trim).&lt;/li&gt;
&lt;li&gt;As propriedades $local e $domain são derivadas do valor.&lt;/li&gt;
&lt;li&gt;O objeto é readonly – imutável por design.&lt;/li&gt;
&lt;li&gt;A comparação equals verifica tanto o tipo quanto o valor.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Cuidado:&lt;/strong&gt; a lógica de negócio dentro do Value Object deve ser autossuficiente e baseada apenas no valor recebido, e não deve depender de contexto externo (como banco de dados, por exemplo).&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Objetos de Valor em uso
&lt;/h2&gt;

&lt;p&gt;Uma Entidade no DDD deve ser um contêiner de valores, não uma colcha de retalhos de tipos primitivos. Veja como fica uma UserEntity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserEntity&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Entity&lt;/span&gt;  &lt;span class="c1"&gt;// Entity pai fornece $id e clone()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;Name&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;Email&lt;/span&gt; &lt;span class="nv"&gt;$email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;?HashedPassword&lt;/span&gt; &lt;span class="nv"&gt;$password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Restante do código: factory methods, comportamentos...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note que &lt;code&gt;$name&lt;/code&gt;, &lt;code&gt;$email&lt;/code&gt; e &lt;code&gt;$password&lt;/code&gt; são Objetos de Valor e cada um carrega suas próprias regras. E a Entidade &lt;code&gt;User&lt;/code&gt; não precisa se preocupar com essas validações – elas já foram resolvidas no momento da criação.&lt;/p&gt;




&lt;h3&gt;
  
  
  Dicas para usar Objetos de Valor
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Comece pelos primitivos obcecados:&lt;/strong&gt; qualquer lugar onde você vê &lt;code&gt;string $cpf&lt;/code&gt;, &lt;code&gt;string $cep&lt;/code&gt;, &lt;code&gt;string $telefone&lt;/code&gt; é candidato a Value Object.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Seja imutável:&lt;/strong&gt; depois de construído, nada pode mudar. Para alterar, crie um novo objeto.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Valide no construtor:&lt;/strong&gt; lance exceções específicas do domínio se os dados forem inválidos. Assim, um objeto de valor sempre representa um estado consistente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implemente equals corretamente:&lt;/strong&gt; compare o valor na classe e todos os atributos relevantes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ao adotar Value Objects, você:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Elimina duplicação de validações.&lt;/li&gt;
&lt;li&gt;Torna o código autodocumentado.&lt;/li&gt;
&lt;li&gt;Previne estados inválidos.&lt;/li&gt;
&lt;li&gt;Facilita a evolução do domínio.&lt;/li&gt;
&lt;/ul&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Desafio:&lt;/strong&gt; &lt;em&gt;Liste 3 atributos do seu sistema atual que são primitivos mas deveriam ser Value Objects e deixe aqui nos comentários. Exemplo: placaVeiculo, numCartaoCredito, intervaloData.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Objetos de Valor &lt;strong&gt;não são&lt;/strong&gt; exclusivos para quem adota o DDD – são uma ferramenta prática para acabar com a bagunça dos tipos primitivos e validações repetidas. Eles transformam regras de negócio escondidas em código limpo, seguro e reutilizável.&lt;/p&gt;

&lt;p&gt;Então lembre-se: todo CPF, e-mail ou telefone no seu sistema é um valor que merece respeito. Trate-os como objetos – e eles tratarão bem o seu domínio.&lt;/p&gt;

&lt;p&gt;Agora vá, identifique um atributo extraia seu primeiro Value Object, e sinta a diferença na consistência. Seu eu do futuro vai agradecer.&lt;/p&gt;

&lt;p&gt;Gostou? Então &lt;strong&gt;não perca os próximos&lt;/strong&gt;. Me siga e receba mais artigos sobre código de qualidade e arquitetura de software de verdade.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔔 Compartilhe com quem ainda valida CPF com if solto no código.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vamos juntos construir softwares mais expressivos e robustos! &lt;strong&gt;Até a próxima, galerinha&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>cleancode</category>
      <category>object</category>
      <category>php</category>
    </item>
    <item>
      <title>Facades no Laravel entregam velocidade, mas cobram o preço em acoplamento</title>
      <dc:creator>Meriéli Manzano</dc:creator>
      <pubDate>Thu, 14 May 2026 15:15:00 +0000</pubDate>
      <link>https://dev.to/merielimanzano/facades-sao-o-cafe-do-laravel-resolvem-rapido-mas-viciam-e-escondem-o-problema-1o8c</link>
      <guid>https://dev.to/merielimanzano/facades-sao-o-cafe-do-laravel-resolvem-rapido-mas-viciam-e-escondem-o-problema-1o8c</guid>
      <description>&lt;p&gt;As Facades do Laravel são algo que o framework disponibiliza e que vejo muitos projetos usando em controllers, services, entities e até mesmo em repositories. Eu pessoalmente já usei e ainda uso Facade, a produtividade inicial é maravilhosa, o código fica enxuto e você entrega valor rápido porque não precisa instanciar, é só usar a Facade direto, é lindo.&lt;/p&gt;

&lt;p&gt;Só que tenho refletido sobre uma coisa que não aparece no curto prazo, especialmente quando a aplicação cresce e a manutenção se estende por anos.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Pense num cenário real:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Você tem uma classe de serviço que usa várias outras Facades internas. Funciona perfeitamente bem, até o dia que você precisar reaproveitar aquela lógica num script isolado fora do Laravel. Ou testar aquela classe sem o framework inteiro carregado.&lt;/p&gt;

&lt;p&gt;Aí você percebe: a classe não diz o que ela precisa. Você só descobre abrindo o código linha por linha. E cada facade é um fio invisível conectado ao Laravel.&lt;/p&gt;

&lt;p&gt;Não é que Facade seja errada. É que elas resolvem um problema (velocidade) e criam outro silencioso (acoplamento implícito). Cada time escolhe seu trade-off. Esse acoplamento forte com o framework vai justamente contra as regras de dependência da Clean Architecture.&lt;/p&gt;

&lt;p&gt;Para entender por que, precisamos saber que Facades do Laravel funcionam como “proxies estáticos” que fornecem acesso a objetos registrados no service container. São uma “ponte” entre uma chamada de método estático e a instância real de um objeto, resolvido em tempo de execução pelo container de injeção de dependência do Laravel.&lt;/p&gt;

&lt;p&gt;Abaixo separei algumas vantagens e desvantagens que vai te ajudar a decidir quando realmente devemos usá-las.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Código mais rápido de escrever e mais fácil de ler, acelerando drasticamente o desenvolvimento e a prototipagem.&lt;/li&gt;
&lt;li&gt;Facilidade para testar usando &lt;code&gt;shouldReceive()&lt;/code&gt; e Fakes para garantir que a lógica real não seja acionada, diferente de métodos estáticos tradicionais. &lt;em&gt;“Obs: Mas já que a IA está criando testes com maestria, será que isso faz realmente a diferença?”&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Tem comportamento Singleton, sendo resolvida uma única vez por requisição.&lt;/li&gt;
&lt;li&gt;Pode ser usada em qualquer lugar, sem a necessidade de passar dependência manualmente pelo construtor.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Acoplamento que não quebra a testabilidade, mas suja as dependências “ou seja, não é declarada a dependência, ela fica implícita e só é descoberta olhando o corpo dos métodos”. O que dificulta manutenção e reuso.&lt;/li&gt;
&lt;li&gt;Viola a Inversão de Dependência, a classe depende diretamente de uma implementação concreta ou de uma interface resolvida pela Facade, não de uma abstração definida pelo domínio, injetada de fora.&lt;/li&gt;
&lt;li&gt;Lógica acoplada ao Framework, porque Facades só funcionam com o Facade Root inicializado. Se um dia pretender reutilizar aquela classe em um script isolado, pacote PHP puro ou outro framework, precisará reescrever tudo.&lt;/li&gt;
&lt;li&gt;Por serem muito convenientes, facilitam a violação silenciosa do SRP: desenvolvedores adicionam novas responsabilidades indiretas sem que o construtor da classe sinalize o inchaço.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Deixo mais dois pontos de atenção que não são necessariamente desvantagens, mas devem ser conhecidos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Embora sejam testáveis, os mocks são aplicados globalmente – afetam todas as chamadas à facade durante o teste, não apenas uma instância específica. Sem uma limpeza explícita (como &lt;code&gt;clearResolvedInstances()&lt;/code&gt; no &lt;code&gt;tearDown&lt;/code&gt;), pode haver vazamento de comportamento entre testes. É um ponto de atenção, mas contornável.&lt;/li&gt;
&lt;li&gt;A facade não é mais rápida que a injeção direta. Cada chamada paga o custo do &lt;code&gt;__callStatic()&lt;/code&gt; e da resolução da chave no container – é tecnicamente mais lenta, mas na prática você nunca vai medir essa diferença.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Facades são ótimas em Controllers, Commands, Jobs (camadas mais próximas da infra). E podem até ser usadas em protótipos e MVPs, são uma excelente escolha para garantir velocidade de entrega.&lt;/p&gt;

&lt;p&gt;Já nas camadas de domínio, serviços de aplicação, objetos de valor, entidades... faz mais sentido injetar uma interface no construtor para desacoplar sua lógica de negócio.&lt;/p&gt;

&lt;p&gt;Tá tudo bem usar Facades. Esse post não é uma regra. É só uma lente que eu peguei dos meus estudos e que, de vez em quando, me faz perguntar: “será que aqui vale a pena declarar a dependência?”&lt;/p&gt;

&lt;p&gt;Fico curiosa pra saber como vocês lidam com isso. Já sentiu alguma dificuldade prática com Facades para testar, evoluir ou reaproveitar lógica? Ou acham que eliminar Facades do Laravel da camada de negócio é uma sofisticação desnecessária?&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>Produtividade com Testes e Vue usando VSCode</title>
      <dc:creator>Meriéli Manzano</dc:creator>
      <pubDate>Mon, 26 Sep 2022 14:18:02 +0000</pubDate>
      <link>https://dev.to/merielimanzano/produtividade-com-testes-e-vue-usando-vscode-593k</link>
      <guid>https://dev.to/merielimanzano/produtividade-com-testes-e-vue-usando-vscode-593k</guid>
      <description>&lt;p&gt;Criar testes bem organizados, separados e com uma boa descrição no Jest ou inserir toda estrutura inicial padrão de um componente Vue, pode ser verboso. Mas configurando o VS Code é possível inserir automaticamente toda pré-estrutura com a escrita de apenas uma palavra.&lt;/p&gt;

&lt;p&gt;Desenvolvendo com o Visual Studio Code você pode turbinar sua produtividade de uma forma muito simples com &lt;strong&gt;Snippets&lt;/strong&gt;!&lt;/p&gt;

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

&lt;p&gt;Os snippets salvos no seu VS Code geram códigos pré-definidos ao digitar uma determinada palavra escolhida na sua configuração.&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%2Fzlv2019kffldwilqcq87.gif" 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%2Fzlv2019kffldwilqcq87.gif" alt=" " width="695" height="172"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Como criar um snippet
&lt;/h2&gt;

&lt;p&gt;Com o VS Code aberto vá em &lt;strong&gt;File&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Preferences&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Configure User Snippets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Na paleta de comandos aberta digite a linguagem para qual deseja exibir o snippet, no caso de testes Jest digite &lt;strong&gt;typescript&lt;/strong&gt; se for sua linguagem utilizada.&lt;/p&gt;

&lt;p&gt;Será aberto um arquivo typescript.json com instruções para criar seu snippet.&lt;/p&gt;

&lt;p&gt;Cada snippet tem a seguinte estrutura:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"Nome do Snippet"&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;"prefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Palavra&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;que&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;chama&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;o&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;snippet&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Corpo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;com&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;o&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;código&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ser&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;gerado&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;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Descrição&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;com&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;detalhes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;do&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;código&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Ao escrever o body, em linhas que houver indentação use &lt;strong&gt;&lt;code&gt;\t&lt;/code&gt;&lt;/strong&gt; para aplicar a tabulação necessária. Cada &lt;code&gt;\t&lt;/code&gt; representa um Tab.&lt;/p&gt;

&lt;p&gt;Para indicar as pausas do Tab para digitação de texto pelo código use &lt;strong&gt;&lt;code&gt;$1&lt;/code&gt;&lt;/strong&gt;, substituindo o número pela ordem de inserção desejada em cada trecho.&lt;/p&gt;

&lt;p&gt;Também é possível indicar o tipo de conteúdo a ser inserido em cada pausa com &lt;strong&gt;&lt;code&gt;${1:conteudo}&lt;/code&gt;&lt;/strong&gt; dando uma ideia do que escrever. E para definir um texto igual a ser usado em várias partes do código use o mesmo número de ID em todas partes que o texto for repetir.&lt;/p&gt;

&lt;p&gt;Abaixo montei um snippet completo para Jest usando BDD que você pode aproveitar nos seus códigos ou adaptar como preferir:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;O snippet de Vue é para uso com composition Api usando Typescript e Sass scoped, mas você pode adaptar como preferir:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;O artigo é para produtividade com Testes e Vue, mas também é possível criar snippets para outras linguagens. &lt;/p&gt;

&lt;p&gt;Espero ter ajudado! 😊&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>braziliandevs</category>
      <category>vue</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
