{"id":920,"date":"2024-11-21T09:58:18","date_gmt":"2024-11-21T12:58:18","guid":{"rendered":"https:\/\/adrianosantostreina.com.br\/blog\/?p=920"},"modified":"2024-12-13T14:34:33","modified_gmt":"2024-12-13T17:34:33","slug":"como-criar-metodos-encadeados-com-fluent-interface","status":"publish","type":"post","link":"https:\/\/adrianosantostreina.com.br\/blog\/como-criar-metodos-encadeados-com-fluent-interface\/","title":{"rendered":"Como criar m\u00e9todos encadeados com Fluent Interface?"},"content":{"rendered":"\n<p>A <strong>Fluent Interface<\/strong> \u00e9 um padr\u00e3o de design que permite encadear m\u00e9todos para criar um c\u00f3digo mais leg\u00edvel, parecido com uma linguagem natural. Esse padr\u00e3o \u00e9 particularmente \u00fatil em cen\u00e1rios complexos, como o de configura\u00e7\u00e3o e emiss\u00e3o de documentos fiscais, onde diversos par\u00e2metros precisam ser definidos antes de uma a\u00e7\u00e3o ser executada.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>Neste artigo, exploraremos como implementar esse padr\u00e3o em Delphi, aplicando-o a um caso real: a emiss\u00e3o de uma Nota Fiscal Eletr\u00f4nica (NF-e). A implementa\u00e7\u00e3o demonstrar\u00e1 como utilizar m\u00e9todos fluentes para configurar dados obrigat\u00f3rios, como emitente, destinat\u00e1rio e itens da nota, finalizando com a valida\u00e7\u00e3o e gera\u00e7\u00e3o da NF-e.<\/p>\n\n\n\n<p class=\"has-medium-font-size\"><strong>Implementa\u00e7\u00e3o de Fluent Interface para NF-e<\/strong><\/p>\n\n\n\n<p>Vamos imaginar um cen\u00e1rio de emiss\u00e3o de uma NF-e, onde precisamos configurar diferentes aspectos: emitente, destinat\u00e1rio, itens e tributos. Abaixo est\u00e1 a implementa\u00e7\u00e3o com m\u00e9todos fluentes.<\/p>\n\n\n\n<p>A Classe Principal <code>TNFeBuilder<\/code><\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >type\n  TNFeBuilder = class\n  private\n    FEmitente: string;\n    FDestinatario: string;\n    FItens: TStringList;\n    FTotal: Currency;\n  public\n    constructor Create;\n    destructor Destroy; override;\n    function SetEmitente(const AEmitente: string): TNFeBuilder;\n    function SetDestinatario(const ADestinatario: string): TNFeBuilder;\n    function AddItem(const ADescricao: string; AQuantidade: Integer; AValorUnitario: Currency): TNFeBuilder;\n    function CalcularTotal: TNFeBuilder;\n    function GerarXML: string;\n  end;\n\nimplementation\n\nconstructor TNFeBuilder.Create;\nbegin\n  FItens := TStringList.Create;\n  FTotal := 0.0;\nend;\n\ndestructor TNFeBuilder.Destroy;\nbegin\n  FItens.Free;\n  inherited;\nend;\n\nfunction TNFeBuilder.SetEmitente(const AEmitente: string): TNFeBuilder;\nbegin\n  FEmitente := AEmitente;\n  Result := Self;\nend;\n\nfunction TNFeBuilder.SetDestinatario(const ADestinatario: string): TNFeBuilder;\nbegin\n  FDestinatario := ADestinatario;\n  Result := Self;\nend;\n\nfunction TNFeBuilder.AddItem(const ADescricao: string; AQuantidade: Integer; AValorUnitario: Currency): TNFeBuilder;\nbegin\n  FItens.Add(Format('%s | Qtd: %d | Unit: %.2f', [ADescricao, AQuantidade, AValorUnitario]));\n  FTotal := FTotal + (AQuantidade * AValorUnitario);\n  Result := Self;\nend;\n\nfunction TNFeBuilder.CalcularTotal: TNFeBuilder;\nbegin\n  \/\/ Aqui podem ser aplicados c\u00e1lculos de impostos ou descontos\n  Result := Self;\nend;\n\nfunction TNFeBuilder.GerarXML: string;\nbegin\n  Result := Format(\n    '&lt;NFe&gt;&lt;Emitente&gt;%s&lt;\/Emitente&gt;&lt;Destinatario&gt;%s&lt;\/Destinatario&gt;&lt;Itens&gt;%s&lt;\/Itens&gt;&lt;Total&gt;%.2f&lt;\/Total&gt;&lt;\/NFe&gt;',\n    [FEmitente, FDestinatario, FItens.Text, FTotal]\n  );\nend;\n<\/pre><\/div>\n\n\n\n<p>Exemplo de Uso:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >var\n  NFe: TNFeBuilder;\n  XML: string;\nbegin\n  NFe := TNFeBuilder.Create;\n  try\n    XML := NFe.SetEmitente('Empresa ABC LTDA')\n              .SetDestinatario('Jo\u00e3o da Silva')\n              .AddItem('Notebook', 1, 3500.00)\n              .AddItem('Mouse', 2, 120.00)\n              .CalcularTotal\n              .GerarXML;\n\n    Writeln(XML);\n  finally\n    NFe.Free;\n  end;\nend;\n<\/pre><\/div>\n\n\n\n<p>Sa\u00edda do XML Gerado<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >&lt;NFe&gt;\n  &lt;Emitente&gt;Empresa ABC LTDA&lt;\/Emitente&gt;\n  &lt;Destinatario&gt;Jo\u00e3o da Silva&lt;\/Destinatario&gt;\n  &lt;Itens&gt;\n    Notebook | Qtd: 1 | Unit: 3500.00\n    Mouse | Qtd: 2 | Unit: 120.00\n  &lt;\/Itens&gt;\n  &lt;Total&gt;3740.00&lt;\/Total&gt;\n&lt;\/NFe&gt;\n<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Explicando o C\u00f3digo: Conceitos Aplicados<\/strong><\/h3>\n\n\n\n<p>O padr\u00e3o <strong>Fluent Interface<\/strong> utiliza uma t\u00e9cnica simples, por\u00e9m poderosa, para possibilitar o encadeamento de m\u00e9todos: retornar a pr\u00f3pria inst\u00e2ncia da classe (<code>Self<\/code>). Isso permite que cada m\u00e9todo execute sua opera\u00e7\u00e3o e, ao mesmo tempo, devolva o controle ao objeto que iniciou a sequ\u00eancia. Aqui est\u00e3o os principais conceitos aplicados no c\u00f3digo:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>O Uso de <code>Self<\/code> para Encadeamento<\/strong><\/li>\n<\/ol>\n\n\n\n<p>No c\u00f3digo, cada m\u00e9todo que modifica ou configura a classe termina com a seguinte linha:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >Result := Self;\n<\/pre><\/div>\n\n\n\n<p>O <code>Self<\/code> \u00e9 uma refer\u00eancia para a pr\u00f3pria inst\u00e2ncia do objeto que est\u00e1 executando o m\u00e9todo. Quando o m\u00e9todo retorna essa inst\u00e2ncia, \u00e9 poss\u00edvel continuar chamando outros m\u00e9todos sem sair do contexto do objeto. Isso cria o efeito de &#8220;fluidez&#8221; que caracteriza o padr\u00e3o Fluent Interface.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Exemplo pr\u00e1tico:<\/h5>\n\n\n\n<p>No m\u00e9todo <code>SetEmitente<\/code>, configuramos o emitente e retornamos a inst\u00e2ncia:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >function TNFeBuilder.SetEmitente(const AEmitente: string): TNFeBuilder;\nbegin\n  FEmitente := AEmitente; \/\/ Configura o emitente\n  Result := Self;         \/\/ Retorna a pr\u00f3pria inst\u00e2ncia\nend;\n<\/pre><\/div>\n\n\n\n<p>Ao encadear chamadas, como em:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >NFe.SetEmitente('Empresa ABC LTDA')\n   .SetDestinatario('Jo\u00e3o da Silva');\n<\/pre><\/div>\n\n\n\n<p><strong>2. Manuten\u00e7\u00e3o do Estado Interno do Objeto<\/strong><\/p>\n\n\n\n<p>Cada m\u00e9todo modifica o estado interno do objeto (<code>TNFeBuilder<\/code>), atualizando os atributos privados. Isso assegura que os dados sejam acumulados \u00e0 medida que os m\u00e9todos s\u00e3o encadeados.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Exemplo:<\/h5>\n\n\n\n<p>O m\u00e9todo <code>AddItem<\/code> adiciona um item \u00e0 lista interna e recalcula o total:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >function TNFeBuilder.AddItem(const ADescricao: string; AQuantidade: Integer; AValorUnitario: Currency): TNFeBuilder;\nbegin\n  FItens.Add(Format('%s | Qtd: %d | Unit: %.2f', [ADescricao, AQuantidade, AValorUnitario]));\n  FTotal := FTotal + (AQuantidade * AValorUnitario);\n  Result := Self;\nend;\n<\/pre><\/div>\n\n\n\n<p>Ao encadear m\u00faltiplos itens:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >NFe.AddItem('Notebook', 1, 3500.00)\n   .AddItem('Mouse', 2, 120.00);\n<\/pre><\/div>\n\n\n\n<p>Os itens s\u00e3o adicionados \u00e0 lista interna <code>FItens<\/code>, e o total \u00e9 atualizado ap\u00f3s cada adi\u00e7\u00e3o.<\/p>\n\n\n\n<p><strong>3. Retorno Diferente no \u00daltimo M\u00e9todo<\/strong><\/p>\n\n\n\n<p>O \u00faltimo m\u00e9todo no encadeamento (<code>GerarXML<\/code>) n\u00e3o retorna a inst\u00e2ncia da classe. Em vez disso, ele retorna um resultado final (uma string com o XML). Essa abordagem permite finalizar o fluxo com o dado esperado, sem interromper o padr\u00e3o fluente.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Exemplo:<\/h5>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >function TNFeBuilder.GerarXML: string;\nbegin\n  Result := Format(\n    '&lt;NFe&gt;&lt;Emitente&gt;%s&lt;\/Emitente&gt;&lt;Destinatario&gt;%s&lt;\/Destinatario&gt;&lt;Itens&gt;%s&lt;\/Itens&gt;&lt;Total&gt;%.2f&lt;\/Total&gt;&lt;\/NFe&gt;',\n    [FEmitente, FDestinatario, FItens.Text, FTotal]\n  );\nend;\n<\/pre><\/div>\n\n\n\n<p>Essa distin\u00e7\u00e3o garante que, enquanto os m\u00e9todos de configura\u00e7\u00e3o e processamento retornam a inst\u00e2ncia para continuar o encadeamento, o m\u00e9todo final entrega o resultado da opera\u00e7\u00e3o.<\/p>\n\n\n\n<p><strong>4. Vantagens do Fluent Interface<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Legibilidade:<\/strong> O c\u00f3digo resultante \u00e9 claro, com m\u00e9todos que se comportam como frases descritivas.<\/li>\n\n\n\n<li><strong>Manuten\u00e7\u00e3o:<\/strong> As configura\u00e7\u00f5es s\u00e3o aplicadas no mesmo objeto, centralizando o estado e reduzindo vari\u00e1veis tempor\u00e1rias.<\/li>\n\n\n\n<li><strong>Encapsulamento:<\/strong> Todos os detalhes de implementa\u00e7\u00e3o s\u00e3o ocultos. O desenvolvedor interage apenas com os m\u00e9todos necess\u00e1rios.<\/li>\n<\/ul>\n\n\n\n<h5 class=\"wp-block-heading\">Compara\u00e7\u00e3o:<\/h5>\n\n\n\n<p>Sem Fluent Interface:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >var\n  NFe: TNFeBuilder;\nbegin\n  NFe := TNFeBuilder.Create;\n  NFe.SetEmitente('Empresa ABC LTDA');\n  NFe.SetDestinatario('Jo\u00e3o da Silva');\n  NFe.AddItem('Notebook', 1, 3500.00);\n  NFe.AddItem('Mouse', 2, 120.00);\n  NFe.CalcularTotal;\n  Writeln(NFe.GerarXML);\nend;\n<\/pre><\/div>\n\n\n\n<p>Com Fluent Interface:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >Writeln(\n  TNFeBuilder.Create\n    .SetEmitente('Empresa ABC LTDA')\n    .SetDestinatario('Jo\u00e3o da Silva')\n    .AddItem('Notebook', 1, 3500.00)\n    .AddItem('Mouse', 2, 120.00)\n    .CalcularTotal\n    .GerarXML\n);\n<\/pre><\/div>\n\n\n\n<p class=\"has-medium-font-size\"><strong>Encadeamento Avan\u00e7ado com Retorno \u00e0 Classe Pai<\/strong><\/p>\n\n\n\n<p>Vamos avan\u00e7ar um pouco mais? E se quisermos ter outras classes para preenchimento? <\/p>\n\n\n\n<p>O conceito de encadeamento avan\u00e7ado com retorno \u00e0 classe pai resolve um problema recorrente em APIs fluentes: a necessidade de navegar entre configura\u00e7\u00f5es de componentes subordinados sem perder o contexto do objeto principal. Esse modelo \u00e9 especialmente \u00fatil em cen\u00e1rios onde partes espec\u00edficas de uma configura\u00e7\u00e3o (como itens em uma nota fiscal) t\u00eam regras ou estruturas pr\u00f3prias, mas ainda precisam fazer parte de um contexto maior, representado pela classe pai.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Motivo para Fazer Isso<\/strong><\/h4>\n\n\n\n<p>A abordagem de retornar \u00e0 classe pai \u00e9 necess\u00e1ria quando:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Modularidade:<\/strong> Partes do sistema, como itens, tributos ou pagamentos, possuem l\u00f3gica pr\u00f3pria e precisam ser organizadas em classes separadas para melhorar a coes\u00e3o. Isso evita que a classe principal fique sobrecarregada com responsabilidades que poderiam ser delegadas.<\/li>\n\n\n\n<li><strong>Encadeamento Natural:<\/strong> Para que a API fluente seja cont\u00ednua e leg\u00edvel, os m\u00e9todos de uma classe subordinada (como <code>AddItem<\/code>) precisam retornar ao fluxo principal ao final de suas opera\u00e7\u00f5es. O uso de um m\u00e9todo como <code>&amp;End<\/code> permite retornar \u00e0 classe pai sem quebrar o padr\u00e3o fluente.<\/li>\n\n\n\n<li><strong>Reuso de Componentes:<\/strong> Com componentes subordinados encapsulados em classes espec\u00edficas (como <code>TItens<\/code>), \u00e9 poss\u00edvel reutiliz\u00e1-los em diferentes contextos, sem necessidade de replicar l\u00f3gica na classe principal.<\/li>\n\n\n\n<li><strong>Hierarquia de Configura\u00e7\u00e3o:<\/strong> No exemplo de emiss\u00e3o de NF-e, as configura\u00e7\u00f5es possuem uma hierarquia natural: o cabe\u00e7alho pertence ao documento principal, enquanto os itens e seus detalhes pertencem a uma parte espec\u00edfica dessa estrutura. Essa hierarquia deve ser refletida no design das classes.<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Vantagens do Retorno \u00e0 Classe Pai<\/strong><\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Legibilidade e Fluidez:<\/strong> O c\u00f3digo gerado \u00e9 mais pr\u00f3ximo de uma linguagem natural. Desenvolvedores podem configurar diferentes partes do objeto sem perder o encadeamento ou criar blocos confusos.Exemplo:<\/li>\n<\/ol>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >NFe\n  .Itens\n    .AddItem('001', 3500.00, 1)\n    .AddItem('002', 120.00, 2)\n  .&amp;End\n  .GerarXML;\n<\/pre><\/div>\n\n\n\n<p>Esse fluxo \u00e9 muito mais leg\u00edvel do que manter todas as configura\u00e7\u00f5es em uma \u00fanica classe.<\/p>\n\n\n\n<p><strong>Encapsulamento:<\/strong> Cada componente, como <code>TItens<\/code>, gerencia seu pr\u00f3prio estado e l\u00f3gica, sem expor detalhes \u00e0 classe principal. Isso melhora o design orientado a objetos, facilitando a manuten\u00e7\u00e3o e extens\u00e3o do c\u00f3digo.<\/p>\n\n\n\n<p><strong>Organiza\u00e7\u00e3o Modular:<\/strong> Com as classes subordinadas, a l\u00f3gica espec\u00edfica fica isolada. Por exemplo, a l\u00f3gica para adicionar itens \u00e0 nota fiscal est\u00e1 completamente encapsulada em <code>TItens<\/code>. A classe principal (<code>TNFeBuilder<\/code>) foca em tarefas de alto n\u00edvel, como gerar o XML.<\/p>\n\n\n\n<p><strong>Extensibilidade:<\/strong> Esse design facilita a adi\u00e7\u00e3o de novos componentes ou funcionalidades. Caso seja necess\u00e1rio adicionar tributos ou pagamentos \u00e0 NF-e, bastaria criar novas classes subordinadas e vincul\u00e1-las ao fluxo principal.<\/p>\n\n\n\n<p><strong>Menor Acoplamento:<\/strong> A classe subordinada (<code>TItens<\/code>) mant\u00e9m uma refer\u00eancia \u00e0 classe pai, mas o oposto n\u00e3o \u00e9 verdadeiro. Isso reduz o acoplamento e melhora a flexibilidade do c\u00f3digo.<\/p>\n\n\n\n<p><strong>Melhoria de Testabilidade:<\/strong> Componentes encapsulados podem ser testados isoladamente. Por exemplo, a funcionalidade de adicionar itens e calcular o total pode ser testada diretamente em <code>TItens<\/code>, sem interferir na l\u00f3gica da classe principal.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Resumo<\/strong><\/h4>\n\n\n\n<p>O encadeamento avan\u00e7ado com retorno \u00e0 classe pai n\u00e3o \u00e9 apenas uma quest\u00e3o de melhorar a legibilidade. Ele reflete boas pr\u00e1ticas de design orientado a objetos, dividindo responsabilidades, reduzindo o acoplamento e tornando o c\u00f3digo mais modular e test\u00e1vel. Em sistemas complexos, essa abordagem oferece uma combina\u00e7\u00e3o poderosa de flexibilidade, clareza e escalabilidade, essencial para aplica\u00e7\u00f5es robustas e f\u00e1ceis de manter.<\/p>\n\n\n\n<p><strong>Vamos a um exemplo pr\u00e1tico:<\/strong><\/p>\n\n\n\n<p><strong>1. Classe <code>TItens<\/code> para Gerenciar os Itens<\/strong><\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >type\n  TNFeBuilder = class; \/\/ Declara\u00e7\u00e3o forward da classe pai\n\n  TItens = class\n  private\n    FParent: TNFeBuilder; \/\/ Refer\u00eancia \u00e0 classe pai\n    FItens: TStringList;\n  public\n    constructor Create(AParent: TNFeBuilder);\n    destructor Destroy; override;\n\n    function AddItem(const AID: string; APreco: Currency; AQuantidade: Integer): TItens;\n    function &amp;End: TNFeBuilder; \/\/ Retorna \u00e0 classe pai\n  end;\n<\/pre><\/div>\n\n\n\n<p><strong>2. Classe <code>TNFeBuilder<\/code> para a NF-e<\/strong><\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >type\n  TNFeBuilder = class\n  private\n    FEmitente: string;\n    FCNPJ: string;\n    FEndereco: string;\n    FItens: TItens; \/\/ Inst\u00e2ncia de `TItens`\n  public\n    constructor Create;\n    destructor Destroy; override;\n\n    \/\/ M\u00e9todos fluentes para o cabe\u00e7alho\n    function SetEmitente(const ARazaoSocial: string): TNFeBuilder;\n    function SetCNPJ(const ACNPJ: string): TNFeBuilder;\n    function SetEndereco(const AEndereco: string): TNFeBuilder;\n\n    \/\/ M\u00e9todo fluente para acessar os itens\n    function Itens: TItens;\n\n    \/\/ Finaliza e gera o XML\n    function GerarXML: string;\n  end;\n<\/pre><\/div>\n\n\n\n<p><strong>3. Implementa\u00e7\u00e3o dos M\u00e9todos<\/strong><\/p>\n\n\n\n<p>M\u00e9todos da Classe <code>TItens<\/code><\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >constructor TItens.Create(AParent: TNFeBuilder);\nbegin\n  FParent := AParent; \/\/ Armazena a refer\u00eancia \u00e0 classe pai\n  FItens := TStringList.Create;\nend;\n\ndestructor TItens.Destroy;\nbegin\n  FItens.Free;\n  inherited;\nend;\n\nfunction TItens.AddItem(const AID: string; APreco: Currency; AQuantidade: Integer): TItens;\nbegin\n  FItens.Add(Format('ID: %s | Pre\u00e7o: %.2f | Quantidade: %d', [AID, APreco, AQuantidade]));\n  Result := Self; \/\/ Permite continuar adicionando itens\nend;\n\nfunction TItens.&amp;End: TNFeBuilder;\nbegin\n  Result := FParent; \/\/ Retorna \u00e0 classe pai para continuar o encadeamento\nend;\n<\/pre><\/div>\n\n\n\n<p><strong>4. Exemplo de Uso<\/strong><\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >var\n  NFe: TNFeBuilder;\n  XML: string;\nbegin\n  NFe := TNFeBuilder.Create;\n  try\n    XML := NFe\n      .SetEmitente('Empresa ABC LTDA')\n      .SetCNPJ('12.345.678\/0001-99')\n      .SetEndereco('Rua das Flores, 123')\n      .Itens\n        .AddItem('001', 3500.00, 1)\n        .AddItem('002', 120.00, 2)\n      .&amp;End\n      .GerarXML;\n\n    Writeln(XML);\n  finally\n    NFe.Free;\n  end;\nend;\n<\/pre><\/div>\n\n\n\n<p>Sa\u00edda do XML Gerado<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >&lt;NFe&gt;\n  &lt;Emitente&gt;Empresa ABC LTDA&lt;\/Emitente&gt;\n  &lt;CNPJ&gt;12.345.678\/0001-99&lt;\/CNPJ&gt;\n  &lt;Endereco&gt;Rua das Flores, 123&lt;\/Endereco&gt;\n  &lt;Itens&gt;\n    ID: 001 | Pre\u00e7o: 3500.00 | Quantidade: 1\n    ID: 002 | Pre\u00e7o: 120.00 | Quantidade: 2\n  &lt;\/Itens&gt;\n&lt;\/NFe&gt;\n<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Explicando o Funcionamento<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Retorno \u00e0 Classe Pai (<code>&amp;End<\/code>)<\/strong>:<br>A fun\u00e7\u00e3o <code>&amp;End<\/code> da classe <code>TItens<\/code> retorna a inst\u00e2ncia da classe <code>TNFeBuilder<\/code>, armazenada em <code>FParent<\/code>. Isso permite continuar o encadeamento no objeto principal ap\u00f3s configurar os itens.<\/li>\n\n\n\n<li><strong>Refer\u00eancia Cruzada<\/strong>:<br>A classe <code>TItens<\/code> conhece sua classe pai (<code>TNFeBuilder<\/code>), mas o oposto n\u00e3o ocorre diretamente. Isso garante encapsulamento, permitindo que <code>TItens<\/code> administre apenas os dados relacionados aos itens.<\/li>\n\n\n\n<li><strong>Legibilidade<\/strong>:<br>Esse modelo de encadeamento dentro de encadeamentos melhora a organiza\u00e7\u00e3o e torna o c\u00f3digo mais expressivo e pr\u00f3ximo da linguagem natural.<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Participe da Comunidade no Telegram<\/h3>\n\n\n\n<p>\ud83d\ude80 Quer continuar essa discuss\u00e3o e trocar ideias com outros desenvolvedores? Junte-se \u00e0 nossa comunidade no Telegram! L\u00e1, voc\u00ea pode comentar sobre o que achou deste artigo, tirar suas d\u00favidas e compartilhar suas experi\u00eancias com Delphi e ainda discutir ou tirar suas d\u00favidas sobre os mais variados temas em uma comunidade com mais de 1.000 desenvolvedores.<\/p>\n\n\n\n<p>\ud83d\udd17 <a href=\"https:\/\/t.me\/AdrianoSantosCommunity\" target=\"_blank\" rel=\"noreferrer noopener\">Clique aqui para entrar na comunidade<\/a><\/p>\n\n\n\n<p>Te vejo l\u00e1!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Conclus\u00e3o<\/strong><\/h3>\n\n\n\n<p>O padr\u00e3o Fluent Interface, combinado com o uso de <code>Self<\/code>, \u00e9 uma ferramenta poderosa para criar APIs leg\u00edveis e pr\u00e1ticas. No exemplo de emiss\u00e3o de NF-e, os m\u00e9todos encadeados simplificam a configura\u00e7\u00e3o e emiss\u00e3o, proporcionando um fluxo natural. Ao dominar esse padr\u00e3o, voc\u00ea melhora significativamente a qualidade e a clareza do c\u00f3digo, beneficiando todo o ciclo de desenvolvimento.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A Fluent Interface \u00e9 um padr\u00e3o de design que permite encadear m\u00e9todos para criar um c\u00f3digo mais leg\u00edvel, parecido com uma linguagem natural. Esse padr\u00e3o \u00e9 particularmente \u00fatil em cen\u00e1rios complexos, como o de configura\u00e7\u00e3o e emiss\u00e3o de documentos fiscais, onde diversos par\u00e2metros precisam ser definidos antes de uma a\u00e7\u00e3o ser executada.<\/p>\n","protected":false},"author":1,"featured_media":926,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-920","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"_links":{"self":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts\/920","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/comments?post=920"}],"version-history":[{"count":5,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts\/920\/revisions"}],"predecessor-version":[{"id":925,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts\/920\/revisions\/925"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/media\/926"}],"wp:attachment":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/media?parent=920"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/categories?post=920"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/tags?post=920"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}