<?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: Rodrigo Vieira</title>
    <description>The latest articles on DEV Community by Rodrigo Vieira (@rodrigovp).</description>
    <link>https://dev.to/rodrigovp</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%2F832393%2Fd2a4f1b4-c7ee-4176-8746-fa3bd02e58f1.jpeg</url>
      <title>DEV Community: Rodrigo Vieira</title>
      <link>https://dev.to/rodrigovp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rodrigovp"/>
    <language>en</language>
    <item>
      <title>Padrões de Projeto são relevantes para o desenvolvimento apoiado por IAs? E por que sim? (Bônus no final)</title>
      <dc:creator>Rodrigo Vieira</dc:creator>
      <pubDate>Tue, 27 May 2025 11:14:29 +0000</pubDate>
      <link>https://dev.to/rodrigovp/padroes-de-projeto-sao-relevantes-para-o-desenvolvimento-apoiado-por-ias-e-por-que-sim-bonus-no-28ai</link>
      <guid>https://dev.to/rodrigovp/padroes-de-projeto-sao-relevantes-para-o-desenvolvimento-apoiado-por-ias-e-por-que-sim-bonus-no-28ai</guid>
      <description>&lt;p&gt;(Artigo originalmente escrito &lt;a href="https://www.linkedin.com/pulse/padr%C3%B5es-de-projeto-s%C3%A3o-relevantes-para-o-apoiado-por-rodrigo-mlgbf/" rel="noopener noreferrer"&gt;aqui&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Recentemente surgiu uma dúvida relacionada a codificação usando padrões de projeto, princípios SOLID, orientação a objetos e outras coisas mais num mundo onde a IA está cada vez mais presente.&lt;/p&gt;

&lt;p&gt;A ideia de utilizarmos padrões para codificarmos nossos softwares vem de longa data. Talvez a publicação mais antiga na nossa área seja o famosíssimo &lt;a href="https://www.amazon.com.br/Padr%C3%B5es-Projetos-Solu%C3%A7%C3%B5es-Reutiliz%C3%A1veis-Orientados/dp/8573076100" rel="noopener noreferrer"&gt;Padrões de Projeto&lt;/a&gt; (ou em inglês, Design Patterns) do GoF. Alguns anos depois, diversos livros contendo "padrões" no nome foram lançados, como o &lt;a href="https://www.amazon.com.br/Padr%C3%B5es-Arquitetura-Aplica%C3%A7%C3%B5es-Corporativas-Martin/dp/8536306386" rel="noopener noreferrer"&gt;Padrões de Arquitetura de Aplicações Corporativas&lt;/a&gt; do Martin Fowler, &lt;a href="https://www.amazon.com.br/Padr%C3%B5es-Implementa%C3%A7%C3%A3o-Cat%C3%A1logo-Indispens%C3%A1vel-Programador/dp/8565837971" rel="noopener noreferrer"&gt;Padrões de Implementação&lt;/a&gt;, do Kent Beck e até o &lt;a href="https://www.amazon.com.br/Refatora%C3%A7%C3%A3o-para-Padr%C3%B5es-Joshua-Kerievsky-ebook/dp/B019HIO22C" rel="noopener noreferrer"&gt;Refatoração para Padrões&lt;/a&gt; do Joshua Kerievsky. Todos eles buscando facilitar a extensão do software e o seu entendimento por parte dos programadores. &lt;/p&gt;

&lt;p&gt;Isso sem contar os livros que não possuem "padrões" no nome, mas seguem na linha de nos passar conhecimento relacionado a como escrever software melhor.&lt;/p&gt;

&lt;p&gt;Temos até o &lt;a href="https://www.amazon.com.br/Padr%C3%B5es-Para-Kubernetes-Reutiliz%C3%A1veis-Aplica%C3%A7%C3%B5es/dp/8575228145" rel="noopener noreferrer"&gt;Padrões para Kubernetes&lt;/a&gt;! :D &lt;/p&gt;

&lt;p&gt;Entretanto, será que eles também são úteis para uma IA? &lt;/p&gt;

&lt;p&gt;Pense num Github Copilot. Seu entendimento do código seria diferente se aplicarmos todos os padrões e boas práticas recomendadas para que desenvolvedores possam produzir código mais desacoplado, extensível e entendível?&lt;/p&gt;

&lt;p&gt;Será que as IAs poderiam entender melhor as aplicações quando elas seguem todos os bons princípios de organização, arquitetura e escrita de software que aprendemos todos esses anos? Ou para elas isso é irrelevante?&lt;/p&gt;

&lt;p&gt;Para responder essas perguntas, convoquei o Chat GPT, e lhe fiz algumas perguntas. &lt;/p&gt;

&lt;p&gt;Segue o diálogo que tive com ele. Um tanto longo, é verdade:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dado um software cuidadosamente arquitetado, com o estado da arte em padrões e ferramentas implementado nele. Caso uma IA como você ou qualquer outra seja utilizada para implementar uma funcionalidade nova nesse software, o trabalho de vocês seria facilitado ou padrões de projeto e SOLID e padrões para microsservicos são bons apenas para facilitar a vida de seres humanos?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Essa é uma excelente pergunta, que toca em um ponto profundo sobre o propósito dos padrões de software: eles são pensados principalmente para humanos.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;1. Para quem servem os padrões como SOLID, DDD, Clean Architecture, etc.?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Esses padrões e boas práticas foram desenvolvidos com o objetivo de:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Facilitar o entendimento, manutenção e evolução do sistema por humanos (desenvolvedores, arquitetos, etc.).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Reduzir o acoplamento e aumentar a coesão, permitindo que sistemas possam crescer sem se tornarem inadministráveis.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Permitir testabilidade, extensibilidade e legibilidade.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Esses benefícios fazem sentido porque somos limitados na nossa capacidade de entender e manter sistemas grandes e complexos.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;2. E para uma IA?&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Para uma IA como eu ou similares, a situação muda:&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Padrões de projeto ajudam um pouco: quando um projeto segue uma arquitetura clara e bem estruturada, fica mais fácil para a IA navegar, inferir intenções e encontrar os pontos de extensão corretos. Ex: uma arquitetura hexagonal ou um uso correto de interfaces facilita sugerir onde encaixar uma nova funcionalidade.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Mas a IA não depende desses padrões para “compreender” o código: IAs podem lidar com grandes volumes de código não estruturado, spaghetti ou fortemente acoplado. Isso não é ideal, mas não é uma limitação tão dura quanto é para humanos. A IA pode ainda sim inferir comportamentos e fazer refatorações automaticamente.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;3. Resumindo: padrões ajudam a IA, mas são pensados para humanos&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Para uma IA atual, como eu, um código bem arquitetado torna o trabalho mais rápido e seguro – mas não é uma exigência.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Para desenvolvedores humanos, esses padrões são quase indispensáveis em sistemas complexos, pois mantêm a sanidade do projeto.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;No futuro, com IAs mais autônomas e integradas ao ciclo de vida do software, pode ser que padrões tradicionais sejam repensados ou adaptados para tornar o código mais IA-friendly do que human-friendly.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;E continuei, perguntando:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Isso significa que os programadores futuros não precisarão dar tanta importância a esses conceitos? Afinal, se eles usarem vocês como ferramenta principal, e vocês não precisam desses padrões pra trabalhar melhor, pode ser que isso aconteça.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;E a resposta:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Você captou uma tendência muito real — e sim, é possível que a ênfase em muitos dos padrões e boas práticas tradicionais diminua com o tempo, especialmente à medida que IAs se tornem participantes mais ativos do processo de desenvolvimento.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Mas essa não é uma resposta simples, então vamos por partes:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;📌 1. Se a IA entende e navega bem em código sem padrões, por que mantê-los?&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Hoje, os padrões existem principalmente porque os sistemas são mantidos, evoluídos e compreendidos por humanos.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Amanhã, se a maior parte da leitura, manutenção e evolução for feita por IA, a prioridade pode mudar:&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;O código poderá ser mais direto, menos preocupado com abstrações elegantes e mais focado em funcionalidade explícita e interpretação por máquina.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Conceitos como SOLID, DDD, Clean Architecture poderão se tornar mais "opcionais" — úteis em alguns contextos (especialmente onde humanos ainda são leitores ativos), mas não fundamentais.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;📌 2. Mas os humanos ainda vão revisar, discutir e decidir&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Mesmo com IA:&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Equipes humanas ainda vão querer entender o sistema em alto nível.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Revisões de código (code reviews), troubleshooting, decisões de arquitetura, auditorias, compliance... ainda precisarão de legibilidade e estrutura.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ou seja: os padrões continuarão sendo importantes enquanto humanos estiverem no ciclo crítico.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;📌 3. O papel dos programadores pode mudar, mas não vai desaparecer&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;No futuro:&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Programadores podem atuar mais como arquitetos de intenção: descrevendo o que precisa ser feito, e deixando que a IA se encarregue do como.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;As boas práticas podem ser traduzidas para regras e constraints que a IA deve seguir.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Exemplo: “Quero que você implemente isso seguindo uma abordagem hexagonal”, ou “Use o padrão Strategy aqui para manter o comportamento extensível”.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;📌 4. Padrões novos podem emergir — para IA&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Pode surgir uma nova geração de “padrões”:&lt;/em&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Otimizada para leitura e manipulação por IA, não por humanos.&lt;/em&gt; &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Mais declarativos, com metadados ricos, menos boilerplate.&lt;/em&gt; &lt;/li&gt;
&lt;li&gt;&lt;em&gt;Talvez mais parecidos com modelos de comportamento, diagramas vivos, ou DSLs específicas.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;✅ Resumo: o futuro muda o papel dos padrões — mas não os torna obsoletos&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Claro que tudo isso é um exercício de futurologia. Mas entendo que a resposta da IA foi bem satisfatória.&lt;/p&gt;

&lt;p&gt;E você? O que acha dessa discussão? Concorda com o ChatGPT? Acredita que o futuro será diferente?&lt;/p&gt;

&lt;p&gt;E por falar em padrões, para escrever esse diálogo com o ChatGPT, utilizei os conceitos trazidos neste &lt;a href="https://www.infoq.com/articles/practical-design-patterns-modern-ai-systems/" rel="noopener noreferrer"&gt;excelente artigo da sempre excelente InfoQ&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Abraços e até a próxima!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Livro de Kafka Connect e Kafka Streams em Português</title>
      <dc:creator>Rodrigo Vieira</dc:creator>
      <pubDate>Wed, 22 May 2024 11:34:20 +0000</pubDate>
      <link>https://dev.to/rodrigovp/livro-de-kafka-connect-e-kafka-streams-em-portugues-p81</link>
      <guid>https://dev.to/rodrigovp/livro-de-kafka-connect-e-kafka-streams-em-portugues-p81</guid>
      <description>&lt;p&gt;&lt;a href="https://media.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%2F8eesn3ofs1rxmzp175a2.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F8eesn3ofs1rxmzp175a2.PNG" alt="Capa do livro"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Inicialmente gostaria de pedir desculpas pela falta de posts por aqui. Gostaria muito de continuar escrevendo, e considero o dev.to uma excelente ferramenta para isso. Mas, como na maioria dos casos de outros autores, estou um tanto sem tempo para escrever :(&lt;/p&gt;

&lt;p&gt;Bem, voltei. E espero conseguir mais tempo para postar assuntos que considero interessantes para a maioria de nós :) Ainda mais agora que meu mais recente livro foi publicado.&lt;/p&gt;

&lt;p&gt;Acredito que consegui trazer a maior quantidade de assuntos possíveis relacionados ao Kafka Connect. Há inclusive algumas curiosidades, como por exemplo, como o Kafka Connect acessa fontes de dados, como bancos relacionais. Te garanto que somente em poucos casos ele fará consultas nas tabelas do seu banco, o que é uma vantagem (!!)&lt;/p&gt;

&lt;p&gt;Além disso, entendo que o Kafka pode ser visto de várias maneiras: tanto como um sistema de mensageria quanto como uma outra fonte de dados. E fontes de dados podem ser consultadas. E, se os dados presentes possuírem alguma relação, podemos criar essas consultas com base nisso. Podemos inclusive filtrar e mapear alguns deles, com base em alguns critérios. &lt;/p&gt;

&lt;p&gt;É isso que o Kafka Streams nos proporciona, usando os tópicos do Kafka como fontes de dados.&lt;/p&gt;

&lt;p&gt;Ficou interessado? Dá uma olhadinha no link abaixo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.casadocodigo.com.br/products/livro-kafka-connect-e-kafka-streams" rel="noopener noreferrer"&gt;https://www.casadocodigo.com.br/products/livro-kafka-connect-e-kafka-streams&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Espero que ele te traga bastante informação a respeito dessas ferramentas. &lt;/p&gt;

&lt;p&gt;Até a próxima! &lt;/p&gt;

</description>
      <category>books</category>
      <category>kafka</category>
    </item>
    <item>
      <title>Pix Saque, pix troco e modelagem de software</title>
      <dc:creator>Rodrigo Vieira</dc:creator>
      <pubDate>Sun, 10 Jul 2022 13:05:35 +0000</pubDate>
      <link>https://dev.to/rodrigovp/pix-saque-pix-troco-e-modelagem-de-software-b17</link>
      <guid>https://dev.to/rodrigovp/pix-saque-pix-troco-e-modelagem-de-software-b17</guid>
      <description>&lt;p&gt;&lt;em&gt;Artigo escrito anteriormente no meu &lt;a href="https://www.linkedin.com/pulse/pix-saque-troco-e-modelagem-de-software-rodrigo-vieira-pinto-msc/"&gt;linkedin&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Há mais de 10 anos atrás, a operadora Oi entrava no nosso mercado de telefonia celular. Já tínhamos a Vivo e a TIM (e a Nextel com seus aparelhos de beeps irritantes, ao menos pra mim). E a Oi surge nesse cenário como mais uma companhia querendo ganhar dinheiro com nossas ligações. Usavam (e até hoje devem usar) crianças bonitinhas dizendo "oi" no final dos comerciais.&lt;/p&gt;

&lt;p&gt;Por falar em comerciais, alguns anos depois de sua inauguração, eles lançaram uma campanha no rádio e na TV que me chamou a atenção. E não, não estava a fim de ser mais um cliente deles. Era uma propaganda engraçada, que fazia referência ao fato de que poucas pessoas no Brasil realizavam ligações, embora os celulares sempre tivessem essa funcionalidade. Não é que a gente não sabia que podia fazer ligações. É que o minuto de ligação de celular na época era muito caro, e não tínhamos What's App ou Telegram. No máximo um bom serviço de SMS (que também era caro). A ideia era diminuir os custos das ligações por meio de compra de créditos de recarga e outras coisas mais.&lt;/p&gt;

&lt;p&gt;O que importa no caso era o slogan da propaganda, que era mais ou menos assim:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Utilize um chip Oi e torne-se um LIGADOR!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A propaganda era engraçada, e pra quem viveu essa época, fica mais ainda, até por imaginar o contexto que ela foi criada, e como as coisas estão hoje. Veja o vídeo &lt;a href="https://youtu.be/b6QqOx1eyYg"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Mas vamos ao que interessa!&lt;/p&gt;

&lt;p&gt;Na época, eu já tinha alguns anos de estrada como desenvolvedor, e estava fazendo minha pós graduação em engenharia de software. Então, modelagem de sistemas estava na minha mente o tempo todo. E a mensagem acima acabou por ficar na minha cabeça.&lt;/p&gt;

&lt;p&gt;Ao modelar a situação do cliente das operadoras de celular, cheguei no seguinte diagrama:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs434qg2nxlyb1dpvrly9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs434qg2nxlyb1dpvrly9.png" alt="Image description" width="237" height="305"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E, ao aderir aos planos da Oi, a "modelagem" passaria a ser assim:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwf5580h54z7k7ti6lgut.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwf5580h54z7k7ti6lgut.png" alt="Image description" width="354" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Embora esse exemplo possa ser engraçado (até hoje o utilizo em algumas aulas como uma piada) foi uma época onde percebi a importância de uma boa modelagem de software. Foi um momento onde estava fazendo uma transição de "programador-que-conhece-todos-os-frameworks-da-moda" para um profissional que passou a se preocupar mais com o código que escrevia. Passei a entender que as linguagens e frameworks são importantes, mas uma boa organização de código é o que mantém o sistema vivo por mais tempo, causando menos gastos para a empresa, e menos dores de cabeça para os desenvolvedores.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mas o que diabos isso tem a ver com o pix saque e o pix troco?
&lt;/h2&gt;

&lt;p&gt;Recentemente fui pesquisar, do ponto de vista do cliente, como funciona essas modalidades de pix, por pura curiosidade. O pix saque foi o que me chamou mais atenção, e já explico os motivos.&lt;/p&gt;

&lt;p&gt;Há &lt;a href="https://www.jornalcontabil.com.br/pix-saque-e-pix-troco-entram-em-operacao-veja-como-se-adaptar/"&gt;diversos&lt;/a&gt; &lt;a href="https://agenciabrasil.ebc.com.br/economia/noticia/2021-11/pix-saque-e-pix-troco-estao-disponiveis-partir-de-hoje"&gt;links&lt;/a&gt; na &lt;a href="https://www.istoedinheiro.com.br/pix-saque-e-pix-troco-saiba-como-usar-e-sacar-dinheiro-so-com-o-celular/"&gt;internet&lt;/a&gt; que explicam como o processo funciona, mas basicamente (no pix saque) é possível que você, como pessoa física e com conta em banco, realize saques em dinheiro em qualquer estabelecimento comercial que tenha aderido à modalidade. É como se os estabelecimentos comerciais se transformassem em caixas eletrônicos.&lt;/p&gt;

&lt;p&gt;Mas espere! Os links acima até se referem a caixas eletrônicos. Mas eles também se referem a outro termo: o &lt;strong&gt;agente de saque&lt;/strong&gt;. E, pelo que entendi, é como os estabelecimentos comerciais que aderiram ao pix saque estão sendo chamados pelo banco central. Eles, inclusive, serão remunerados por cada saque realizado.&lt;/p&gt;

&lt;p&gt;Bem, podemos dizer que, até outro dia, se a gente precisasse sacar dinheiro para comprar algo num estabelecimento comercial, tínhamos que ir até o caixa eletrônico. Então, podemos pensar numa modelagem mais ou menos assim:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyaw0w9b9qminznpduh8w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyaw0w9b9qminznpduh8w.png" alt="Image description" width="557" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Para quem conhece UML a fundo, desculpe se estou cometendo algum pecado imperdoável :D)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Eu poderia ter mapeado o relacionamento entre Pessoa e as demais classes de forma invertida. Mas, para os nossos propósitos neste artigo, vamos deixar assim.&lt;/p&gt;

&lt;p&gt;Com o advento do pix saque, podemos também sacar diretamente no estabelecimento comercial. Então, podemos até escolher onde queremos realizar o saque!&lt;/p&gt;

&lt;p&gt;Nesse caso, a modelagem OO nos ensina que há uma abstração comum às abstrações EstabelecimentoComercial e CaixaEletronico: o AgenteDeSaque:&lt;/p&gt;

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

&lt;p&gt;Modelei o AgenteDeSaque como uma interface, mas ele poderia ser também uma classe abstrata. Poderíamos inclusive implementar um &lt;a href="https://refactoring.guru/pt-br/design-patterns/template-method"&gt;template method&lt;/a&gt; caso AgenteDeSaque fosse assim.&lt;/p&gt;

&lt;p&gt;Há também uma refatoração a ser feita aqui: a Pessoa agora pode sacar dinheiro num AgenteDeSaque, independente de quem ele seja:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F82agw59g5y16gm63osdw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F82agw59g5y16gm63osdw.png" alt="Image description" width="778" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Deu até para colocar o EstabelecimentoComercial mais perto da Pessoa. Afinal, quem não vai querer ter um lugar como esse por perto? :D&lt;/p&gt;

&lt;p&gt;E com isso terminamos o exemplo utilizando o pix saque. Não sei se o banco central considera os caixas eletrônicos como agentes de saque. Também não faço ideia se os sistemas foram modelados ou refatorados da forma sugerida acima (embora seria interessante que decisões semelhantes a essas tenham sido tomadas). Só quis mostrar o que modelei na minha cabeça quando entendi como funcionava o pix saque. No fim, me ajudou a entender melhor todo os agentes envolvidos no processo e como ele seria implementado.&lt;/p&gt;

&lt;p&gt;É possível também realizar uma refatoração na classe Pessoa. Atualmente, ela é capaz de realizar saques e fazer compras. Mas, e se tivermos que considerar outros agentes além de pessoas que possam executar essas funcionalidades? Podemos pensar que, do ponto de vista bancário, o sistema não deveria lidar como pessoas, mas com correntistas, e o estabelecimento, com clientes.&lt;/p&gt;

&lt;p&gt;Isso parece com o &lt;a href="https://www.zup.com.br/blog/design-principle-solid"&gt;princípio de segregação de interfaces&lt;/a&gt;. Mas aí é papo para outro artigo :)&lt;/p&gt;

&lt;p&gt;Até a próxima!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>discuss</category>
      <category>tutorial</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Qual a diferença entre a inversão e a injeção de dependências?</title>
      <dc:creator>Rodrigo Vieira</dc:creator>
      <pubDate>Fri, 03 Jun 2022 00:37:45 +0000</pubDate>
      <link>https://dev.to/rodrigovp/qual-a-diferenca-entre-a-inversao-e-a-injecao-de-dependencias-3d9</link>
      <guid>https://dev.to/rodrigovp/qual-a-diferenca-entre-a-inversao-e-a-injecao-de-dependencias-3d9</guid>
      <description>&lt;p&gt;É comum a confusão entre esses dois conceitos. E veremos neste artigo que há alguns bons motivos para isso :D&lt;/p&gt;

&lt;h2&gt;
  
  
  O Princípio da Inversão de Dependências
&lt;/h2&gt;

&lt;p&gt;Considere o diagrama abaixo. Ele representa parte de um sistema de negativação de títulos. Quando um devedor deixa de pagar um título, a empresa pode enviar o mesmo para o SERASA.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Ffa8lfqi62y7st6w5gj72.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ffa8lfqi62y7st6w5gj72.jpg" alt="Diagrama de parte de nossa solução de negativação de títulos"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note que a classe &lt;code&gt;Departamento&lt;/code&gt; possui 2 dependências com classes de camadas mais baixas, e que lida com questões tecnológicas. O &lt;code&gt;Departamento&lt;/code&gt; então busca os títulos a serem negativados em &lt;code&gt;TitulosDAO&lt;/code&gt; (que acessa o banco de dados) e, de posse da lista de títulos, os envia à &lt;code&gt;SERASA&lt;/code&gt; (que pode lidar com uma interface REST com o SERASA, por exemplo).&lt;/p&gt;

&lt;p&gt;Para representarmos a dependência de uma classe por outra, criamos uma seta que aponte para a direção da dependência. Assim, existem 2 setas, saindo de &lt;code&gt;Departamento&lt;/code&gt; e apontando para &lt;code&gt;TitulosDAO&lt;/code&gt; e &lt;code&gt;SERASA&lt;/code&gt; e, consequentemente, o módulo de uma camada superior está dependendo de módulos de uma camada inferior. Guarde essa informação!&lt;/p&gt;

&lt;p&gt;Se pensarmos em classes Java, teremos algo parecido com os códigos abaixo:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;br.com.rodnet.negativador.dao&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;br.com.rodnet.negativador.dominio.Titulo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TitulosDAO&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Titulo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;emAtraso&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//implementacao&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


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

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;br.com.rodnet.negativador.serasa&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;br.com.rodnet.negativador.dominio.Titulo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Serasa&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;negativar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Titulo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;titulos&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


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

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;br.com.rodnet.negativador.dominio&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;br.com.rodnet.negativador.dao.TitulosDAO&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;br.com.rodnet.negativador.serasa.Serasa&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&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;Departamento&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;TitulosDAO&lt;/span&gt; &lt;span class="n"&gt;titulosDAO&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Serasa&lt;/span&gt; &lt;span class="n"&gt;serasa&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;Departamento&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;TitulosDAO&lt;/span&gt; &lt;span class="n"&gt;titulosDAO&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Serasa&lt;/span&gt; &lt;span class="n"&gt;serasa&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&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;titulosDAO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;titulosDAO&lt;/span&gt;&lt;span class="o"&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;serasa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serasa&lt;/span&gt;&lt;span class="o"&gt;;&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;negativar&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Titulo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;titulos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;titulosDAO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;emAtraso&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;serasa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;negativar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;titulos&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Embora essa estrutura seja simples, ela apresenta alguns problemas. A camada superior do sistema depende de abstrações da camada inferior. Consequentemente, se houver alguma alteração em classes como &lt;code&gt;TituloDAO&lt;/code&gt;, é possível que a classe &lt;code&gt;Departamento&lt;/code&gt; sofra alterações.&lt;/p&gt;

&lt;p&gt;Esse problema parece pequeno e talvez a princípio não mereça tanta atenção, mas é algo bem antigo na nossa profissão. O tão falado livro (não sem razão) do &lt;a href="https://www.amazon.com.br/Arquitetura-Limpa-Artes%C3%A3o-Estrutura-Software/dp/8550804606/" rel="noopener noreferrer"&gt;Uncle Bob&lt;/a&gt; cita exemplos de uns 50 anos atrás, onde precisávamos escrever software que precisava, entre outras coisas, escrever nos discos que existiam na época (enormes, barulhentos e com pouca capacidade). E quando eles precisaram trocar os discos para elementos menores (com mais capacidade e, provavelmente, menos barulhentos), os programas precisaram ser reescritos, não somente no código que cuidava da leitura e escrita nos discos, mas em todos os demais códigos que dependiam deles. As vezes, as correções subiam até para camadas mais acima do sistema. &lt;/p&gt;

&lt;p&gt;De lá pra cá, aprendemos (aprendemos?) que é importante que o nosso software utilize as tecnologias adequadas, e que esteja preparado para uma possível substituição delas. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Mas não podemos dizer isso!"&lt;/em&gt; diria o narrador.&lt;/p&gt;

&lt;p&gt;Então podemos dizer que:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Módulos de alto nível não devem incorporar (ou incluir) nada dos módulos de baixo nível. Ambos devem trabalhar apenas com abstrações (interfaces ou classes abstratas).&lt;br&gt;
Abstrações não devem depender de detalhes. Detalhes é que devem depender de abstrações.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Assim, se revisitarmos as classes do nosso sistema, podemos concluir que as classes de alto nível dependem de classes de baixo nível (&lt;code&gt;Departamento&lt;/code&gt; depende de &lt;code&gt;TitulosDAO&lt;/code&gt; e de &lt;code&gt;SERASA&lt;/code&gt;). Portanto, mudanças devem ser feitas.&lt;/p&gt;

&lt;p&gt;Segundo a citação acima, o &lt;code&gt;Departamento&lt;/code&gt; deveria depender de abstrações. No caso, abstrações das classes que ele depende hoje.&lt;/p&gt;

&lt;p&gt;Para que isso seja possível, não temos muitas alternativas a não ser criarmos interfaces que sejam implementadas pelas dependências atuais de &lt;code&gt;Departamento&lt;/code&gt;. Então, mãos à obra:&lt;/p&gt;

&lt;p&gt;Podemos começar pelo &lt;code&gt;TitulosDAO&lt;/code&gt;, &lt;a href="https://refactoring.guru/pt-br/extract-interface" rel="noopener noreferrer"&gt;extraindo uma interface&lt;/a&gt; do mesmo:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;br.com.rodnet.negativador.dominio&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;RepositorioTitulos&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Titulo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;emAtraso&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


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

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;br.com.rodnet.negativador.dao&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;br.com.rodnet.negativador.dominio.RepositorioTitulos&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;br.com.rodnet.negativador.dominio.Titulo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TitulosDAO&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;RepositorioTitulos&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Titulo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;emAtraso&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//implementacao&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;e fazer o mesmo com &lt;code&gt;SERASA&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;br.com.rodnet.negativador.dominio&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ServicoDeProtecaoAoCredito&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;negativar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Titulo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;titulos&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


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

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;br.com.rodnet.negativador.serasa&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;br.com.rodnet.negativador.dominio.ServicoDeProtecaoAoCredito&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;br.com.rodnet.negativador.dominio.Titulo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Serasa&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ServicoDeProtecaoAoCredito&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;negativar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Titulo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;titulos&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Agora que temos abstrações das classes de camadas inferiores, podemos agora substituir as dependências de &lt;code&gt;Departamento&lt;/code&gt; por elas:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;br.com.rodnet.negativador.dominio&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&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;Departamento&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;RepositorioTitulos&lt;/span&gt; &lt;span class="n"&gt;repositorioTitulos&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;ServicoDeProtecaoAoCredito&lt;/span&gt; &lt;span class="n"&gt;servicoDeProtecaoAoCredito&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;Departamento&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RepositorioTitulos&lt;/span&gt; &lt;span class="n"&gt;repositorioTitulos&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ServicoDeProtecaoAoCredito&lt;/span&gt; &lt;span class="n"&gt;servicoDeProtecaoAoCredito&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&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;repositorioTitulos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repositorioTitulos&lt;/span&gt;&lt;span class="o"&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;servicoDeProtecaoAoCredito&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;servicoDeProtecaoAoCredito&lt;/span&gt;&lt;span class="o"&gt;;&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;negativar&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Titulo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;titulos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repositorioTitulos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;emAtraso&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;servicoDeProtecaoAoCredito&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;negativar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;titulos&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;OBS:&lt;/strong&gt; troquei também os nomes dos atributos para que ficassem mais condizentes com as novas abstrações.&lt;/p&gt;

&lt;p&gt;Percebam que agora as classes &lt;code&gt;TitulosDAO&lt;/code&gt; e &lt;code&gt;SERASA&lt;/code&gt; podem ser alteradas à vontade, pois isso não acarretará em alterações em &lt;code&gt;Departamento&lt;/code&gt;. Elas só precisam implementar as interfaces de domínio, da maneira que for melhor para elas. &lt;/p&gt;

&lt;p&gt;Podemos inclusive pensar mais longe:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;trocamos de empresa de negativação? Sem problemas. Basta criar uma nova classe que implemente &lt;code&gt;ServicoDeProtecaoAoCredito&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;não estamos mais usando um banco de dados, mas um serviço externo de busca de títulos? Tudo bem! Basta trocarmos a classe que implementa &lt;code&gt;RepositorioTitulos&lt;/code&gt;. O &lt;code&gt;Departamento&lt;/code&gt; não deverá sofrer nenhuma alteração sequer!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agora, observem como nosso diagrama ficou após todas essas mudanças:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F7r4zcd0xj27z5snwan7b.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F7r4zcd0xj27z5snwan7b.jpg" alt="Modelagem da solução após as refatorações realizadas"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Naturalmente que existem mais elementos no nosso diagrama. Afinal, precisamos representar nossas novas interfaces. Mas reparem para as setas. Mais precisamente as setas que indicam herança (ou implementação, no nosso caso).&lt;/p&gt;

&lt;p&gt;Lembra que pedi para você guardar a informação sobre o sentido das setas? Pois bem: antes, as setas apontavam para baixo. E agora, elas apontam para cima. Ou seja, houve uma inversão de quem depende de quem. Ou, se preferir, &lt;strong&gt;houve uma inversão das dependências&lt;/strong&gt;. Agora são os módulos das camadas inferiores é que dependem dos módulos superiores.&lt;/p&gt;

&lt;p&gt;Basicamente esse é o &lt;a href="https://deviq.com/principles/dependency-inversion-principle" rel="noopener noreferrer"&gt;Princípio de Inversão de Dependências&lt;/a&gt;. E a sua definição mais básica é aquela citação feita lá em cima:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Módulos de alto nível não devem incorporar (ou incluir) nada dos módulos de baixo nível. Ambos devem trabalhar apenas com abstrações (interfaces ou classes abstratas).&lt;br&gt;
Abstrações não devem depender de detalhes. Detalhes é que devem depender de abstrações.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  E a injeção de dependências?
&lt;/h2&gt;

&lt;p&gt;Bem, a injeção de dependências tem mais a ver com a maneira com que criamos nossos objetos. &lt;/p&gt;

&lt;p&gt;Vamos ver novamente a classe &lt;code&gt;Departamento&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;br.com.rodnet.negativador.dominio&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&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;Departamento&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;RepositorioTitulos&lt;/span&gt; &lt;span class="n"&gt;repositorioTitulos&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;ServicoDeProtecaoAoCredito&lt;/span&gt; &lt;span class="n"&gt;servicoDeProtecaoAoCredito&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;Departamento&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RepositorioTitulos&lt;/span&gt; &lt;span class="n"&gt;repositorioTitulos&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ServicoDeProtecaoAoCredito&lt;/span&gt; &lt;span class="n"&gt;servicoDeProtecaoAoCredito&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&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;repositorioTitulos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repositorioTitulos&lt;/span&gt;&lt;span class="o"&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;servicoDeProtecaoAoCredito&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;servicoDeProtecaoAoCredito&lt;/span&gt;&lt;span class="o"&gt;;&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;negativar&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Titulo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;titulos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repositorioTitulos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;emAtraso&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;servicoDeProtecaoAoCredito&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;negativar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;titulos&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Em Java, independente do fato de usarmos ou não um &lt;em&gt;framework&lt;/em&gt;, os objetos devem ser instanciados de alguma forma. E as formas mais conhecidas são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;instanciação simples: via o famoso operador &lt;code&gt;new&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.java2s.com/ref/java/java-reflection-constructor-instantiate-objects.html" rel="noopener noreferrer"&gt;instanciação via API de reflection
&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;instanciação via framework de injeção de dependências&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agora, pense no caso da classe &lt;code&gt;Departamento&lt;/code&gt;. Se usarmos o operador new para instanciá-la, podemos fazer algo como:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;repositorioTitulos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TitulosDAO&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;servicoDeProtecaoAoCredito&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Serasa&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;departamento&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Departamento&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repositorioTitulos&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;servicoDeProtecaoAoCredito&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;E quem seria responsável por instanciar todas essas classes?&lt;br&gt;
No passado, usávamos bastante os padrões criacionais do &lt;a href="https://www.amazon.com.br/Padr%C3%B5es-Projetos-Solu%C3%A7%C3%B5es-Reutiliz%C3%A1veis-Orientados/dp/8573076100" rel="noopener noreferrer"&gt;GoF&lt;/a&gt; (como &lt;a href="https://refactoring.guru/pt-br/design-patterns/abstract-factory" rel="noopener noreferrer"&gt;Abstract Factory&lt;/a&gt; ou &lt;a href="https://refactoring.guru/pt-br/design-patterns/factory-method" rel="noopener noreferrer"&gt;Factory Method&lt;/a&gt;). Depois, passamos a trabalhar com o &lt;em&gt;pattern&lt;/em&gt; &lt;a href="https://java-design-patterns.com/patterns/registry/" rel="noopener noreferrer"&gt;Registry&lt;/a&gt; e até mesmo com &lt;a href="https://docs.oracle.com/javase/tutorial/jndi/overview/index.html" rel="noopener noreferrer"&gt;JNDI&lt;/a&gt;. E, resumidamente falando, tínhamos mais desvantagens do que vantagens. &lt;/p&gt;

&lt;p&gt;Talvez num cenário com apenas 3 classes, os problemas não sejam tão visíveis, mas pense num sistema maior, com mais classes. Um grande problema era o fato de que essas classes "fábrica" viviam em constante mudança, o que as tornavam bastante instáveis. E devemos evitar mudanças constantes, tanto em classes quanto em módulos inteiros. Para maiores detalhes e informações sobre o problema de mudanças em módulos, vale a pena estudar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devlead.io/DevTips/StableDependenciesPrinciple" rel="noopener noreferrer"&gt;o Princípio das Dependências Estáveis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://devlead.io/DevTips/StableAbstractionsPrinciple" rel="noopener noreferrer"&gt;o Princípio das Abstrações Estáveis&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No fundo, o SOLID também se preocupa com o excesso de mudanças, mas em classes. E por falar em SOLID, o Uncle Bob também fala sobre os princípios acima &lt;a href="https://www.amazon.com.br/Arquitetura-Limpa-Artes%C3%A3o-Estrutura-Software/dp/8550804606" rel="noopener noreferrer"&gt;no seu livro&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Bem, feita a tangente e voltando para o problema principal: se você conhece o Spring, normalmente você resolveria o problema de criação das classes inserindo as famosas anotações &lt;code&gt;@Autowired&lt;/code&gt; e, no mínimo &lt;code&gt;@Component&lt;/code&gt; ou alguma outra parecida nas dependências. Algo como:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="nd"&gt;@Service&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Departamento&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;RepositorioTitulos&lt;/span&gt; &lt;span class="n"&gt;repositorioTitulos&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;ServicoDeProtecaoAoCredito&lt;/span&gt; &lt;span class="n"&gt;servicoDeProtecaoAoCredito&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="nc"&gt;Departamento&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RepositorioTitulos&lt;/span&gt; &lt;span class="n"&gt;repositorioTitulos&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ServicoDeProtecaoAoCredito&lt;/span&gt; &lt;span class="n"&gt;servicoDeProtecaoAoCredito&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&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;repositorioTitulos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repositorioTitulos&lt;/span&gt;&lt;span class="o"&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;servicoDeProtecaoAoCredito&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;servicoDeProtecaoAoCredito&lt;/span&gt;&lt;span class="o"&gt;;&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;negativar&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Titulo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;titulos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repositorioTitulos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;emAtraso&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;servicoDeProtecaoAoCredito&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;negativar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;titulos&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;e nas demais classes:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="nd"&gt;@Repository&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TitulosDAO&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;RepositorioTitulos&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Titulo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;emAtraso&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//implementacao&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


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

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Serasa&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ServicoDeProtecaoAoCredito&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;negativar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Titulo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;titulos&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Repare que, quando você utiliza um &lt;em&gt;framework&lt;/em&gt; como o spring, você não precisa instanciar essas classes, muito menos passá-las como parâmetro para &lt;code&gt;Departamento&lt;/code&gt;. O spring as instancia e as "injeta" em &lt;code&gt;Departamento&lt;/code&gt;, que também pode ser injetada em outra classe. Assim, ele consegue montar boa parte da árvore de objetos necessária para o funcionamento do sistema. &lt;/p&gt;

&lt;p&gt;Naturalmente que ainda temos que instanciar manualmente algumas classes. Mas não podemos negar que a injeção de dependências é uma mão na roda quando temos que construir objetos com uma árvore de dependências complexa (dependência que depende de dependência, que depende de dependência...).&lt;/p&gt;

&lt;p&gt;E aí? Ficou mais clara a diferença entre esses dois conceitos? Normalmente eles são usados juntos, e talvez por isso crie-se tanta confusão entre eles.&lt;/p&gt;

&lt;p&gt;Até a próxima!&lt;/p&gt;

</description>
      <category>java</category>
      <category>solid</category>
      <category>spring</category>
    </item>
    <item>
      <title>Feign com SOAP: uma PoC</title>
      <dc:creator>Rodrigo Vieira</dc:creator>
      <pubDate>Sun, 24 Apr 2022 21:52:40 +0000</pubDate>
      <link>https://dev.to/rodrigovp/feign-com-soap-uma-poc-2daf</link>
      <guid>https://dev.to/rodrigovp/feign-com-soap-uma-poc-2daf</guid>
      <description>&lt;p&gt;Faz tempo que se diz que devemos &lt;a href="https://www.amazon.com.br/Padr%C3%B5es-Projetos-Solu%C3%A7%C3%B5es-Reutiliz%C3%A1veis-Orientados/dp/8573076100/"&gt;programar para uma interface, e não para uma implementação&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;E, de uns anos pra cá, ao menos no mundo Java, isso está sendo levado ao extremo, por diversos frameworks. Neles, não precisamos mais implementar interfaces, mas simplesmente escrevê-las (seguindo algumas regras, claro). O framework faz todo o resto.&lt;/p&gt;

&lt;p&gt;Recentemente, escrevi sobre a &lt;a href="https://dev.to/rodrigovp/do-jdbc-ao-spring-data-ou-e-possivel-reduzir-codigo-361f"&gt;evolução dos DAOs em Java, chegando ao Spring Data&lt;/a&gt;. E, neste artigo, vou falar um pouco sobre o &lt;a href="https://dev.toou%20simplesmente%20Feign"&gt;Spring Open Feign&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Esse framework é bem conhecido quando o assunto é criar uma integração com serviços REST. Em resumo: cria-se uma interface, coloca-se umas anotações e pronto! Temos um client REST se conectando com outra aplicação sem a necessidade de instanciarmos um &lt;code&gt;RestTemplate&lt;/code&gt; ou outros objetos, o que é uma boa notícia, pois fazemos o mesmo trabalho com menos código.&lt;/p&gt;

&lt;p&gt;Mas, recentemente na &lt;a href="https://www.vr.com.br"&gt;empresa onde trabalho atualmente&lt;/a&gt;, surgiu uma dúvida: temos alguns sistemas legados, com interface SOAP, e pensamos: será que o Feign também suporta esse protocolo? &lt;/p&gt;

&lt;p&gt;Para aqueles que estiverem sem paciência: sim :D. O código está disponível &lt;a href="https://github.com/rodrigovp/teste-open-feign"&gt;aqui&lt;/a&gt;. E, como sempre, com testes automatizados!&lt;/p&gt;

&lt;p&gt;Ela foi construída usando a versão 17 do Java, mas é possível rodá-la também em versões inferiores da JVM. E, se for a versão 8, algumas dependências não serão necessárias. Veja o pom.xml para mais informações ;)&lt;/p&gt;

&lt;h2&gt;
  
  
  O serviço a ser acessado
&lt;/h2&gt;

&lt;p&gt;Para escrever o &lt;em&gt;client&lt;/em&gt;, é necessário termos o servidor antes, que suporte o protocolo SOAP. Pode-se construir um, mas é um tanto difícil encontrar material para desenvolver um serviço SOAP hoje em dia. Se quiser pesquisar a respeito, há um bom artigo do sempre excelente &lt;a href="https://www.baeldung.com/spring-boot-soap-web-service"&gt;Baeldung&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Nesta PoC, usei como &lt;em&gt;server&lt;/em&gt; um &lt;a href="https://www.dataaccess.com/webservicesserver/NumberConversion.wso"&gt;serviço disponibilizado gratuitamente&lt;/a&gt; que faz conversões simples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;de número simples para número em extenso&lt;/li&gt;
&lt;li&gt;de um valor em dólares para o mesmo valor em extenso&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esse serviço possui também uma interface web, para melhor entendimento. Mas vamos para a interface SOAP, que é a que nos interessa.&lt;/p&gt;

&lt;h2&gt;
  
  
  A interface SOAP
&lt;/h2&gt;

&lt;p&gt;A interface Java é bem simples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@FeignClient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"dataAccess"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"${dataaccess.soap.url}"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;configuration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DataAccessSOAPConfiguration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;DataAccessSOAP&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@PostMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;produces&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TEXT_XML_VALUE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;consumes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TEXT_XML_VALUE&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nc"&gt;NumberToWordsResponse&lt;/span&gt; &lt;span class="nf"&gt;porExtenso&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@RequestBody&lt;/span&gt; &lt;span class="nc"&gt;NumberToWords&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="nd"&gt;@PostMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;produces&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TEXT_XML_VALUE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;consumes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TEXT_XML_VALUE&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nc"&gt;NumberToDollarsResponse&lt;/span&gt; &lt;span class="nf"&gt;dolaresPorExtenso&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@RequestBody&lt;/span&gt; &lt;span class="nc"&gt;NumberToDollars&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para quem já trabalhou com o Feign, a anotação &lt;code&gt;@FeignClient&lt;/code&gt; é a mesma que se usa quando a integração é usando o REST. E, pra quem já trabalhou com Spring MVC, a anotação &lt;code&gt;@PostMapping&lt;/code&gt; não é tão incomum. &lt;/p&gt;

&lt;p&gt;É possível também que estamos trabalhando com XML (vide os parâmetros das anotações). Afinal, quando a integração é com SOAP, dificilmente não usamos XML :D&lt;/p&gt;

&lt;p&gt;Há também algumas classes de requisição e resposta. Essas classes são criadas por meio do &lt;a href="https://www.dataaccess.com/webservicesserver/NumberConversion.wso?WSDL"&gt;WSDL&lt;/a&gt; oferecido pelo próprio serviço:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;definitions&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.xmlsoap.org/wsdl/"&lt;/span&gt; &lt;span class="na"&gt;xmlns:xs=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema"&lt;/span&gt; &lt;span class="na"&gt;xmlns:soap=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.xmlsoap.org/wsdl/soap/"&lt;/span&gt; &lt;span class="na"&gt;xmlns:soap12=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.xmlsoap.org/wsdl/soap12/"&lt;/span&gt; &lt;span class="na"&gt;xmlns:tns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.dataaccess.com/webservicesserver/"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberConversion"&lt;/span&gt; &lt;span class="na"&gt;targetNamespace=&lt;/span&gt;&lt;span class="s"&gt;"http://www.dataaccess.com/webservicesserver/"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;types&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;xs:schema&lt;/span&gt; &lt;span class="na"&gt;elementFormDefault=&lt;/span&gt;&lt;span class="s"&gt;"qualified"&lt;/span&gt; &lt;span class="na"&gt;targetNamespace=&lt;/span&gt;&lt;span class="s"&gt;"http://www.dataaccess.com/webservicesserver/"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;xs:element&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberToWords"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;xs:complexType&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;xs:sequence&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;xs:element&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"ubiNum"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"xs:unsignedLong"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/xs:sequence&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/xs:complexType&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/xs:element&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;xs:element&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberToWordsResponse"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;xs:complexType&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;xs:sequence&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;xs:element&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberToWordsResult"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"xs:string"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/xs:sequence&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/xs:complexType&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/xs:element&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;xs:element&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberToDollars"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;xs:complexType&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;xs:sequence&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;xs:element&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"dNum"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"xs:decimal"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/xs:sequence&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/xs:complexType&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/xs:element&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;xs:element&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberToDollarsResponse"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;xs:complexType&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;xs:sequence&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;xs:element&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberToDollarsResult"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"xs:string"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/xs:sequence&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/xs:complexType&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/xs:element&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/xs:schema&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/types&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;message&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberToWordsSoapRequest"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;part&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"parameters"&lt;/span&gt; &lt;span class="na"&gt;element=&lt;/span&gt;&lt;span class="s"&gt;"tns:NumberToWords"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/message&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;message&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberToWordsSoapResponse"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;part&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"parameters"&lt;/span&gt; &lt;span class="na"&gt;element=&lt;/span&gt;&lt;span class="s"&gt;"tns:NumberToWordsResponse"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/message&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;message&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberToDollarsSoapRequest"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;part&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"parameters"&lt;/span&gt; &lt;span class="na"&gt;element=&lt;/span&gt;&lt;span class="s"&gt;"tns:NumberToDollars"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/message&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;message&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberToDollarsSoapResponse"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;part&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"parameters"&lt;/span&gt; &lt;span class="na"&gt;element=&lt;/span&gt;&lt;span class="s"&gt;"tns:NumberToDollarsResponse"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/message&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;portType&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberConversionSoapType"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;operation&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberToWords"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;documentation&amp;gt;&lt;/span&gt;Returns the word corresponding to the positive number passed as parameter. Limited to quadrillions.&lt;span class="nt"&gt;&amp;lt;/documentation&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;message=&lt;/span&gt;&lt;span class="s"&gt;"tns:NumberToWordsSoapRequest"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;output&lt;/span&gt; &lt;span class="na"&gt;message=&lt;/span&gt;&lt;span class="s"&gt;"tns:NumberToWordsSoapResponse"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/operation&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;operation&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberToDollars"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;documentation&amp;gt;&lt;/span&gt;Returns the non-zero dollar amount of the passed number.&lt;span class="nt"&gt;&amp;lt;/documentation&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;message=&lt;/span&gt;&lt;span class="s"&gt;"tns:NumberToDollarsSoapRequest"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;output&lt;/span&gt; &lt;span class="na"&gt;message=&lt;/span&gt;&lt;span class="s"&gt;"tns:NumberToDollarsSoapResponse"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/operation&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/portType&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;binding&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberConversionSoapBinding"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"tns:NumberConversionSoapType"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;soap:binding&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"document"&lt;/span&gt; &lt;span class="na"&gt;transport=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.xmlsoap.org/soap/http"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;operation&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberToWords"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;soap:operation&lt;/span&gt; &lt;span class="na"&gt;soapAction=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"document"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;input&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;soap:body&lt;/span&gt; &lt;span class="na"&gt;use=&lt;/span&gt;&lt;span class="s"&gt;"literal"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/input&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;output&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;soap:body&lt;/span&gt; &lt;span class="na"&gt;use=&lt;/span&gt;&lt;span class="s"&gt;"literal"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/output&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/operation&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;operation&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberToDollars"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;soap:operation&lt;/span&gt; &lt;span class="na"&gt;soapAction=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"document"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;input&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;soap:body&lt;/span&gt; &lt;span class="na"&gt;use=&lt;/span&gt;&lt;span class="s"&gt;"literal"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/input&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;output&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;soap:body&lt;/span&gt; &lt;span class="na"&gt;use=&lt;/span&gt;&lt;span class="s"&gt;"literal"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/output&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/operation&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/binding&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;binding&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberConversionSoapBinding12"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"tns:NumberConversionSoapType"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;soap12:binding&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"document"&lt;/span&gt; &lt;span class="na"&gt;transport=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.xmlsoap.org/soap/http"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;operation&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberToWords"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;soap12:operation&lt;/span&gt; &lt;span class="na"&gt;soapAction=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"document"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;input&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;soap12:body&lt;/span&gt; &lt;span class="na"&gt;use=&lt;/span&gt;&lt;span class="s"&gt;"literal"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/input&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;output&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;soap12:body&lt;/span&gt; &lt;span class="na"&gt;use=&lt;/span&gt;&lt;span class="s"&gt;"literal"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/output&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/operation&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;operation&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberToDollars"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;soap12:operation&lt;/span&gt; &lt;span class="na"&gt;soapAction=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"document"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;input&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;soap12:body&lt;/span&gt; &lt;span class="na"&gt;use=&lt;/span&gt;&lt;span class="s"&gt;"literal"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/input&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;output&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;soap12:body&lt;/span&gt; &lt;span class="na"&gt;use=&lt;/span&gt;&lt;span class="s"&gt;"literal"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/output&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/operation&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/binding&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;service&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberConversion"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;documentation&amp;gt;&lt;/span&gt;The Number Conversion Web Service, implemented with Visual DataFlex, provides functions that convert numbers into words or dollar amounts.&lt;span class="nt"&gt;&amp;lt;/documentation&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;port&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberConversionSoap"&lt;/span&gt; &lt;span class="na"&gt;binding=&lt;/span&gt;&lt;span class="s"&gt;"tns:NumberConversionSoapBinding"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;soap:address&lt;/span&gt; &lt;span class="na"&gt;location=&lt;/span&gt;&lt;span class="s"&gt;"https://www.dataaccess.com/webservicesserver/NumberConversion.wso"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/port&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;port&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"NumberConversionSoap12"&lt;/span&gt; &lt;span class="na"&gt;binding=&lt;/span&gt;&lt;span class="s"&gt;"tns:NumberConversionSoapBinding12"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;soap12:address&lt;/span&gt; &lt;span class="na"&gt;location=&lt;/span&gt;&lt;span class="s"&gt;"https://www.dataaccess.com/webservicesserver/NumberConversion.wso"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/port&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/service&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/definitions&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Repare que alguns elementos do XML possuem nomes iguais aos nomes das classes de requisição e resposta. Como boa prática, essas classes são geradas por frameworks que lêem esse WSDL e nos retornam as classes correspondentes. Digo boa prática porque escrever essas classes na mão dá muito trabalho.&lt;/p&gt;

&lt;p&gt;No passado, existiam diversos frameworks que faziam esse trabalho pra gente, como o &lt;a href="https://cxf.apache.org/"&gt;CXF&lt;/a&gt;, o &lt;a href="https://xmlbeans.apache.org/"&gt;XMLBeans&lt;/a&gt; ou mesmo o &lt;a href="https://axis.apache.org/axis/"&gt;Axis&lt;/a&gt;. Na PoC, entretanto, usei o &lt;a href="https://github.com/highsource/maven-jaxb2-plugin"&gt;maven-jaxb2-plugin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;O código para a geração das classes de requisição e resposta está abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;            &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.jvnet.jaxb2.maven2&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-jaxb2-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;0.14.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
                    &lt;span class="c"&gt;&amp;lt;!-- Dependência necessária para gerar os stubs no Java 17 --&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.glassfish.jaxb&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;jaxb-runtime&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.3.3&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;dataaccess&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;generate&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;schemaDirectory&amp;gt;&lt;/span&gt;${project.basedir}/src/main/resources/schema/dataaccess&lt;span class="nt"&gt;&amp;lt;/schemaDirectory&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;schemaIncludes&amp;gt;&lt;/span&gt;
                                &lt;span class="nt"&gt;&amp;lt;include&amp;gt;&lt;/span&gt;dataaccess.wsdl&lt;span class="nt"&gt;&amp;lt;/include&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;/schemaIncludes&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;cleanPackageDirectories&amp;gt;&lt;/span&gt;false&lt;span class="nt"&gt;&amp;lt;/cleanPackageDirectories&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;generateDirectory&amp;gt;&lt;/span&gt;${project.build.directory}/generated-sources/dataaccess&lt;span class="nt"&gt;&amp;lt;/generateDirectory&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;generatePackage&amp;gt;&lt;/span&gt;br.org.rodnet.dataaccess.stub&lt;span class="nt"&gt;&amp;lt;/generatePackage&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explicando alguns pontos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;com o &lt;em&gt;goal&lt;/em&gt; configurado como &lt;em&gt;generate&lt;/em&gt;, as classes serão geradas quando o comando &lt;code&gt;mvn compile&lt;/code&gt; for chamado.&lt;/li&gt;
&lt;li&gt;o &lt;code&gt;schemaDirectory&lt;/code&gt; e o &lt;code&gt;schemaIncludes&lt;/code&gt; apontam onde está o WSDL do servidor. Basicamente copiei o WSDL fornecido pelo servidor para um arquivo.&lt;/li&gt;
&lt;li&gt;as classes serão geradas na pasta &lt;code&gt;target/generate-sources/dataccess&lt;/code&gt;, no pacote &lt;code&gt;br.org.rodnet.dataaccess.stub&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Por último, há também a classe &lt;code&gt;DataAccessSOAPConfiguration&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DataAccessSOAPConfiguration&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;JAXBContextFactory&lt;/span&gt; &lt;span class="n"&gt;jaxbFactory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;JAXBContextFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withMarshallerSchemaLocation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"${dataaccess.soap.url} ${dataaccess.soap.wsdl}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="nc"&gt;Encoder&lt;/span&gt; &lt;span class="nf"&gt;soapEncoder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SOAPEncoder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jaxbFactory&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="nc"&gt;Decoder&lt;/span&gt; &lt;span class="nf"&gt;soapDecoder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SOAPDecoder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jaxbFactory&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O Feign é altamente configurável. &lt;a href="https://www.baeldung.com/spring-cloud-openfeign"&gt;É possível customizá-lo usando outras bibliotecas diferentes das que ele utiliza por padrão.&lt;/a&gt; E, no nosso caso, precisamos configurar o &lt;em&gt;Encoder&lt;/em&gt; e o &lt;em&gt;Decoder&lt;/em&gt; para que ele suporte o SOAP.&lt;/p&gt;

&lt;p&gt;Resumidamente falando:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Encoder&lt;/em&gt; é a classe que prepara o objeto para ser enviado para o servidor&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Decoder&lt;/em&gt; é a classe que receberá a resposta e a converte para os objetos que precisamos&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ou seja, para trabalharmos com SOAP, precisamos sobrescrever o &lt;code&gt;Encoder&lt;/code&gt; e o &lt;code&gt;Decoder&lt;/code&gt; (que por &lt;em&gt;default&lt;/em&gt;) lida com REST. Por isso que normalmente não se cria esses beans quando o protocolo é o REST.&lt;/p&gt;

&lt;p&gt;Ao rodar os testes da aplicação:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.02 s - &lt;span class="k"&gt;in &lt;/span&gt;br.org.rodnet.testeopenfeign.TesteOpenFeignApplicationTests
&lt;span class="o"&gt;[&lt;/span&gt;INFO]
&lt;span class="o"&gt;[&lt;/span&gt;INFO] Results:
&lt;span class="o"&gt;[&lt;/span&gt;INFO]
&lt;span class="o"&gt;[&lt;/span&gt;INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
&lt;span class="o"&gt;[&lt;/span&gt;INFO]
&lt;span class="o"&gt;[&lt;/span&gt;INFO] &lt;span class="nt"&gt;------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;INFO] BUILD SUCCESS
&lt;span class="o"&gt;[&lt;/span&gt;INFO] &lt;span class="nt"&gt;------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;INFO] Total &lt;span class="nb"&gt;time&lt;/span&gt;:  18.014 s
&lt;span class="o"&gt;[&lt;/span&gt;INFO] Finished at: 2022-04-24T18:38:26-03:00
&lt;span class="o"&gt;[&lt;/span&gt;INFO] &lt;span class="nt"&gt;------------------------------------------------------------------------&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Espero que tenha ficado claro como utilizar o Feign em sistemas que lidam com SOAP. &lt;/p&gt;

&lt;p&gt;O Feign é um &lt;em&gt;framework&lt;/em&gt; bem versátil, e com ele, foi possível escrevermos a integração com sistemas legados de forma simples, sem muita complexidade. Isso sem contar o "programar para uma interface, não para uma implementação" levado ao extremo.&lt;/p&gt;

&lt;p&gt;Até a próxima!&lt;/p&gt;

</description>
      <category>spring</category>
      <category>soap</category>
      <category>tutorial</category>
      <category>java</category>
    </item>
    <item>
      <title>Do JDBC ao Spring Data (ou: é possível reduzir código?)</title>
      <dc:creator>Rodrigo Vieira</dc:creator>
      <pubDate>Mon, 28 Mar 2022 23:54:06 +0000</pubDate>
      <link>https://dev.to/rodrigovp/do-jdbc-ao-spring-data-ou-e-possivel-reduzir-codigo-361f</link>
      <guid>https://dev.to/rodrigovp/do-jdbc-ao-spring-data-ou-e-possivel-reduzir-codigo-361f</guid>
      <description>&lt;p&gt;Há tempos que venho querendo escrever este post. Mais precisamente, desde quando comentei sobre o tema deste artigo numa &lt;a href="https://www.youtube.com/watch?v=TX1NztPbvMw"&gt;live sobre o livro de spring boot, escrito pelo&lt;/a&gt; &lt;a class="mentioned-user" href="https://dev.to/boaglio"&gt;@boaglio&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Bem, finalmente saiu :D&lt;/p&gt;

&lt;p&gt;No vídeo, cito que o Spring Data é uma das ferramentas mais interessantes do Mundo Java, dada a sua facilidade de utilização. Mas, outra coisa que me também me chama a atenção é a quantidade de código que deixamos de escrever quando usamos esse &lt;em&gt;framework&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Isso me fez lembrar como criávamos nossos &lt;a href="https://www.tutorialspoint.com/design_pattern/data_access_object_pattern.htm"&gt;DAOs&lt;/a&gt; no passado. E acho que vale a pena falar um pouco sobre isso aqui. Divirtam-se! ;) &lt;/p&gt;

&lt;h2&gt;
  
  
  No princípio, era o JDBC
&lt;/h2&gt;

&lt;p&gt;Java Database Connectivity foi o primeiro mecanismo que conheci para conectar com um banco de dados e enviar instruções SQL para ele (&lt;code&gt;insert&lt;/code&gt;, &lt;code&gt;select&lt;/code&gt;, etc).&lt;/p&gt;

&lt;p&gt;Mais do que isso, é uma API que nos permite conectar com qualquer banco de dados, bastando que tenhamos apenas o &lt;em&gt;driver&lt;/em&gt; do banco em mãos.&lt;/p&gt;

&lt;p&gt;Isso gerou diversas vantagens. Entre elas, o fato de podermos usar as mesmas classes/interfaces para que nossos sistemas se conectassem em diversos bancos de dados relacionais. &lt;/p&gt;

&lt;p&gt;Bem, isso não significa que nosso código era simples, muito menos de fácil manutenção, como podemos ver na classe abaixo. Ela representa um DAO de usuários, com todas as operações básicas que podemos fazer num banco:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Repository&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RepositorioUsuariosJdbc&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;RepositorioUsuarios&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Value&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"${spring.datasource.url}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Value&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"${spring.datasource.username}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Value&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"${spring.datasource.password}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;senha&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;conexao&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@PostConstruct&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;posConstrutor&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;conexao&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DriverManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getConnection&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;senha&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SQLException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Usuario&lt;/span&gt; &lt;span class="n"&gt;umUsuario&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;existe&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;umUsuario&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="n"&gt;salvar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;umUsuario&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;atualizar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;umUsuario&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;existe&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Usuario&lt;/span&gt; &lt;span class="n"&gt;umUsuario&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;umUsuario&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;atualizar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Usuario&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;statement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conexao&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prepareStatement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"update usuarios set nome = ? where id = ?"&lt;/span&gt;&lt;span class="o"&gt;)){&lt;/span&gt;
            &lt;span class="n"&gt;statement&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getNome&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="n"&gt;statement&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setLong&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="n"&gt;statement&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeUpdate&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SQLException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;deleteById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;statement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conexao&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prepareStatement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"delete from usuarios where id = ?"&lt;/span&gt;&lt;span class="o"&gt;)){&lt;/span&gt;
            &lt;span class="n"&gt;statement&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setLong&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;statement&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeUpdate&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SQLException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Usuario&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;usuarios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Usuario&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;();&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;statement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conexao&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prepareStatement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"select * from usuarios"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;resultset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;statement&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeQuery&lt;/span&gt;&lt;span class="o"&gt;()){&lt;/span&gt;
            &lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;()){&lt;/span&gt;
                &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resultset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLong&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resultset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"nome"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;dataNascimento&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resultset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data_nascimento"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;LocalDate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Usuario&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dataNascimento&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;usuarios&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SQLException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;usuarios&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;conexao&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SQLException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;idEhNulo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Usuario&lt;/span&gt; &lt;span class="n"&gt;umUsuario&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;umUsuario&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;salvar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Usuario&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"insert into usuarios (nome, data_nascimento) values (?, ?)"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;statement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conexao&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prepareStatement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Statement&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;RETURN_GENERATED_KEYS&lt;/span&gt;&lt;span class="o"&gt;)){&lt;/span&gt;
            &lt;span class="n"&gt;statement&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getNome&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="n"&gt;statement&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDataNascimento&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="n"&gt;statement&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeUpdate&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

            &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;statement&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getGeneratedKeys&lt;/span&gt;&lt;span class="o"&gt;()){&lt;/span&gt;
                &lt;span class="n"&gt;ids&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                &lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ids&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLong&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SQLException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Escrevi este código num pequeno projeto, criado apenas para este artigo. Ele pode ser consultado &lt;a href="https://github.com/rodrigovp/diferentes-daos"&gt;aqui&lt;/a&gt;. E, para provar que esse código (e os demais que veremos a seguir) funciona, há testes automatizados no projeto. &lt;/p&gt;

&lt;p&gt;Outras observações:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;o código foi compilado usando Java 17 (queria testar alguns recursos novos poxa :P)&lt;/li&gt;
&lt;li&gt;na época que usávamos o que é chamado hoje de "JDBC puro" (o código acima) não tínhamos recursos como o &lt;em&gt;&lt;a href="https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html"&gt;try-with-resources&lt;/a&gt;&lt;/em&gt;. Então, pode ter certeza de que o DAO acima poderia ser muito maior.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Também não tive a preocupação de controlar a conexão com o banco de dados (hoje, usamos &lt;em&gt;&lt;a href="https://www.baeldung.com/hikaricp"&gt;connection pools&lt;/a&gt;&lt;/em&gt; e não temos que nos preocupar com isso), nem de capturar corretamente as exceções.&lt;/p&gt;

&lt;p&gt;Sobre o DAO acima... bem, acho que não preciso dizer muita coisa. Tínhamos que nos preocupar com o objeto de conexão com o banco, mas mais que isso: haviam também os objetos &lt;code&gt;ResultSet&lt;/code&gt; e &lt;code&gt;PreparedStatement&lt;/code&gt; (ou &lt;code&gt;Statement&lt;/code&gt;, quando estávamos aprendendo a usar o JDBC. Depois que aprendíamos os problemas de uso do &lt;code&gt;Statement&lt;/code&gt;, partíamos para o &lt;code&gt;PreparedStatement&lt;/code&gt;). Esses objetos eram criados, e tinham que ser fechados quando não eram mais usados.&lt;/p&gt;

&lt;p&gt;Também a construção de queries era trabalhosa, e altamente propensa a erros. O que pode acontecer quando adicionamos um parâmetro a mais no &lt;code&gt;insert&lt;/code&gt; do código acima, por exemplo?&lt;/p&gt;

&lt;p&gt;Isso sem contar a quantidade imensa de código repetido.&lt;/p&gt;

&lt;p&gt;Mas então veio o Hibernate, e nossa vida melhorou (bastante, eu diria):&lt;/p&gt;

&lt;h2&gt;
  
  
  Tabelas e objetos são (quase) a mesma coisa - Hibernate
&lt;/h2&gt;

&lt;p&gt;Dizem que o Gavin King é uma pessoa muito parecida com o Linus Torwalds em termos de simpatia e carisma. &lt;/p&gt;

&lt;p&gt;Se isso é verdade, não sei dizer. Mas posso afirmar sem medo de errar que ele foi o criador de uma das ferramentas mais importantes do Mundo Java. &lt;a href="https://www.alura.com.br/conteudo/persistencia-jpa-introducao-hibernate"&gt;Ela foi criada em 2001&lt;/a&gt; e até hoje usamos ela (a implementação de referência do Spring Data usa Hibernate por baixo dos panos). &lt;/p&gt;

&lt;p&gt;Ele entendeu que, de certa forma, podíamos fazer um paralelo entre atributos de objetos e registros em tabelas, com o conjunto de atributos de um objeto sendo comparado a uma linha de uma tabela. Pode ser que seja algo meio óbvio hoje em dia, mas não sei se em 2001 isso era tão claro assim (alguns de nós nem eram nascidos em 2001 :D). &lt;/p&gt;

&lt;p&gt;Utilizando o Hibernate, nosso código fica consideravelmente menor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Repository&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RepositorioUsuariosHibernate&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;RepositorioUsuarios&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@PersistenceContext&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;EntityManager&lt;/span&gt; &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Session&lt;/span&gt; &lt;span class="n"&gt;sessao&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@PostConstruct&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;posConstrutor&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
        &lt;span class="n"&gt;sessao&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;unwrap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Usuario&lt;/span&gt; &lt;span class="n"&gt;umUsuario&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;sessao&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;umUsuario&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;deleteById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sessao&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"from Usuario where id = %d"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;formatted&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;uniqueResult&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;sessao&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delete&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Usuario&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sessao&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"from Usuario"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;getResultList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;sessao&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Não temos mais o objeto &lt;code&gt;Connection&lt;/code&gt; nem mesmo os objetos &lt;code&gt;PreparedStatement&lt;/code&gt; ou o &lt;code&gt;ResultSet&lt;/code&gt;, mas apenas a &lt;code&gt;Session&lt;/code&gt;. Ela era como um &lt;a href="https://refactoring.guru/pt-br/design-patterns/facade"&gt;Façade&lt;/a&gt; para o banco. Toda vez que precisávamos fazer algo nele, era só usar a &lt;code&gt;Session&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;OBS: para obter a &lt;code&gt;Session&lt;/code&gt;, usei o &lt;code&gt;EntityManager&lt;/code&gt; que veio com o JPA. Falarei sobre ele mais tarde.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Para obtermos a &lt;code&gt;Session&lt;/code&gt; do Hibernate, era necessário um pouco mais de código. Como o Hibernate utiliza o JDBC, também precisava da URL de conexão, usuário, senha e o dialeto do banco que se usaria no sistema. E essa &lt;code&gt;Session&lt;/code&gt; podia ser obtida via configuração programática ou por XML (o famoso &lt;code&gt;hibernate.cfg.xml&lt;/code&gt;). Uma boa referência sobre como esse processo era feito é essa &lt;a href="https://docs.jboss.org/hibernate/orm/3.5/reference/pt-BR/html/session-configuration.html"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Isso resolveu boa parte dos nossos problemas. Entretanto, o Hibernate era uma solução muito boa. Tão boa que outros programadores/empresas também criaram suas ferramentas de mapeamento objeto-relacional (como o TopLink, que depois virou &lt;a href="https://www.eclipse.org/eclipselink/"&gt;EclipseLink&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Por essas e outras &lt;a href="https://www.amazon.com.br/Pro-EJB-Java-Persistence-API/dp/1590596455"&gt;razões&lt;/a&gt; foi criada a especificação JPA.&lt;/p&gt;

&lt;h2&gt;
  
  
  A unificação de diversas ferramentas de ORM: Java Persistence API
&lt;/h2&gt;

&lt;p&gt;Com a criação da JPA, ferramentas como o EclipseLink e o Hibernate passaram a compartilhar principalmente de diversas anotações que serviam na maioria das vezes para realizar o mapeamento de objetos para tabelas e vice-versa. &lt;/p&gt;

&lt;p&gt;Essas anotações deviam ser inseridas na classe que se pretendia persistir. Abaixo, a classe &lt;code&gt;Usuario&lt;/code&gt; devidamente "anotada":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Entity&lt;/span&gt;
&lt;span class="nd"&gt;@Table&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"usuarios"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@DynamicUpdate&lt;/span&gt;
&lt;span class="nd"&gt;@NoArgsConstructor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;access&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AccessLevel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;PRIVATE&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@EqualsAndHashCode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"nome"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"dataNascimento"&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
&lt;span class="nd"&gt;@Getter&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Usuario&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Id&lt;/span&gt;
    &lt;span class="nd"&gt;@GeneratedValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GenerationType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;IDENTITY&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@Setter&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;LocalDate&lt;/span&gt; &lt;span class="n"&gt;dataNascimento&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Usuario&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;LocalDate&lt;/span&gt; &lt;span class="n"&gt;dataNascimento&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&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;nome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="o"&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;dataNascimento&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataNascimento&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;atualizarNome&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;novoNome&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&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;nome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;novoNome&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;OBS: essa classe está sendo usada em todos os DAOs deste artigo. Logo, pode haver código necessário para um DAO e desnecessário para outro (por exemplo, os getters e setters são necessários para o DAO JDBC, mas completamente dispensáveis para os demais DAOs)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Abaixo, podemos ver o mesmo DAO, implementado usando o Hibernate segundo a especificação JPA:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Repository&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RepositorioUsuariosJpa&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;RepositorioUsuarios&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@PersistenceContext&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;EntityManager&lt;/span&gt; &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Usuario&lt;/span&gt; &lt;span class="n"&gt;umUsuario&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;persist&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;umUsuario&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;flush&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;deleteById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="nc"&gt;Usuario&lt;/span&gt; &lt;span class="n"&gt;usuario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;find&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Usuario&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;remove&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Usuario&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"from Usuario"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;getResultList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A priori não há praticamente nenhuma diferença. Agora usamos esse tal de &lt;code&gt;EntityManager&lt;/code&gt; no lugar da &lt;code&gt;Session&lt;/code&gt;. De fato, olhando somente o código, pouca coisa mudou. &lt;/p&gt;

&lt;p&gt;O &lt;code&gt;EntityManager&lt;/code&gt; nos ajudou a lidar com a persistência de forma padronizada, pois veio com a especificação JPA. Para mais detalhes, veja esse artigo &lt;a href="https://www.theserverside.com/news/2240186700/The-JPA-20-EntityManager-vs-the-Hibernate-Session-Which-one-to-use"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;De qualquer forma, ainda tínhamos que lidar com uma certa quantidade de código repetido. Pense que os DAOs precisavam receber de forma injetada o &lt;code&gt;EntityManager&lt;/code&gt;, e manipulá-lo em todos os DAOs.&lt;/p&gt;

&lt;p&gt;Isso não era um grande problema (pra quem já tinha trabalhado com DAOs usando JDBC). Mas aí veio o pessoal da VMWare dizer pra gente que dava pra fazer melhor ainda. E, normalmente, eles estão certos.&lt;/p&gt;

&lt;h2&gt;
  
  
  O estado da arte - Spring Data
&lt;/h2&gt;

&lt;p&gt;O Spring Data (mais especificamente o &lt;a href="https://spring.io/projects/spring-data-jpa"&gt;Spring Data JPA&lt;/a&gt;, embora todos da família seguem os mesmos princípios) é um &lt;em&gt;framework&lt;/em&gt; que facilitou de vez a criação de DAOs. Basicamente não temos que escrever praticamente nada no DAO para ele funcionar.&lt;/p&gt;

&lt;p&gt;Veja como fica nosso DAO com a utilização dele:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Repository&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;RepositorioUsuariosSpringDataJpa&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;JpaRepository&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Usuario&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apenas uma interface que estende de outra do próprio &lt;code&gt;framework&lt;/code&gt; é suficiente. Nada mais!&lt;/p&gt;

&lt;p&gt;Ok, tem também as anotações na classe &lt;code&gt;Usuario&lt;/code&gt;, mas você entendeu.&lt;/p&gt;

&lt;p&gt;Para quem está começando agora com programação Java, se não pegar nenhum sistema legado para dar manutenção, provavelmente já começa com essa ferramenta. Talvez não veja o que ela traz de bom e suas vantagens. Então, se um dia você reclamar que ela não é boa por alguma razão...bem, já foi bem pior :D&lt;/p&gt;

&lt;p&gt;Podem ter certeza que resumi bastante toda a história. Há muitos outros detalhes que valeriam a pena citar. Mas procurei focar no código, e o quanto ele foi reduzindo com o passar do tempo.&lt;/p&gt;

&lt;p&gt;Perceberam o quanto evoluímos na escrita de nossos DAOs? Atualmente, quase não precisamos escrever eles. E DAOs já foram as classes que mais tinham código em diversos sistemas!&lt;/p&gt;

&lt;p&gt;O que o futuro nos reserva? Será que um dia não precisaremos nem mais escrever essa interface? As anotações no código bastarão?&lt;/p&gt;

&lt;p&gt;E você? Ainda acha que não é possível refatorar o código da sua aplicação?&lt;/p&gt;

&lt;p&gt;Abraço!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>java</category>
      <category>orm</category>
    </item>
    <item>
      <title>Um conselho para quem está começando na área de TI</title>
      <dc:creator>Rodrigo Vieira</dc:creator>
      <pubDate>Sun, 20 Mar 2022 21:46:46 +0000</pubDate>
      <link>https://dev.to/rodrigovp/um-conselho-para-quem-esta-comecando-na-area-de-ti-4l9n</link>
      <guid>https://dev.to/rodrigovp/um-conselho-para-quem-esta-comecando-na-area-de-ti-4l9n</guid>
      <description>&lt;p&gt;(Artigo originalmente publicado no meu twitter, &lt;a href="https://twitter.com/rvieirapinto"&gt;@rvieirapinto&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Lembro de quando tinha meus 20 e poucos anos e começando com TI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;em transição de carreira (até a faculdade, eu era metalúrgico);&lt;/li&gt;
&lt;li&gt;praticamente todos na minha turma de faculdade tinham feito técnico em Processamento de Dados antes;&lt;/li&gt;
&lt;li&gt;não tinha computador em casa. Pensem em 2 caixas enormes (monitor e gabinete) acessando uma internet discada ruim lá em 1999. Em casa, não víamos necessidade de ter um treco desses e pronto.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A primeira vez que vi um código-fonte, achei terrivelmente difícil (um hello world em C).&lt;/p&gt;

&lt;p&gt;O que eu fiz? Bem, eu sabia algumas coisas de mim:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;que eu não sabia NADA de nada do que viria pela frente. NADA mesmo. Só podia planejar e ver no que daria;&lt;/li&gt;
&lt;li&gt;que eu podia me tornar um desses colegas de faculdade também. Bastava estudar! E com 20 e poucos anos, tempo eu tinha.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E foi o que fiz!&lt;/p&gt;

&lt;p&gt;Com o tempo, percebi também que podia ter alguns mentores na minha carreira. Gente que escrevia seus próprios blogs (alguém ainda escreve em blogs?) e respondia dúvidas em fóruns como o &lt;a href="https://www.guj.com.br"&gt;GUJ&lt;/a&gt; . Isso contribuiu MUITO para a minha carreira.&lt;/p&gt;

&lt;p&gt;Todo esse processo levou tempo? CLARO que sim! &lt;/p&gt;

&lt;p&gt;Até eu me considerar um sênior, levou uns bons 10 anos! E foi por acidente! Algo do tipo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;É sério que sou sênior??&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Então, pra quem é jovem (de idade e de área) uma dica que posso dar é: TENHAM PACIÊNCIA PELO AMOR DE DEUS! Querem ficar mal de saúde? Botar tudo a perder?&lt;/p&gt;

&lt;p&gt;Querem ter status o quanto antes? Como dizia Uncle Bob em &lt;a href="https://www.amazon.com.br/Codificador-Limpo-Bob-Martin/dp/8576086476/ref=asc_df_8576086476/?tag=googleshopp00-20&amp;amp;linkCode=df0&amp;amp;hvadid=379787347388&amp;amp;hvpos=&amp;amp;hvnetw=g&amp;amp;hvrand=12501346715006790406&amp;amp;hvpone=&amp;amp;hvptwo=&amp;amp;hvqmt=&amp;amp;hvdev=c&amp;amp;hvdvcmdl=&amp;amp;hvlocint=&amp;amp;hvlocphy=1001754&amp;amp;hvtargid=pla-809202560536&amp;amp;psc=1"&gt;O Codificador Limpo&lt;/a&gt;, cuidado com o que você pede!&lt;/p&gt;

&lt;p&gt;Quer ganhar muito dinheiro logo? &lt;/p&gt;

&lt;p&gt;Olha, não sei o que você considera muito. Mas, se compararmos a média salarial das demais profissões com a nossa, vemos que mesmo um júnior não ganha tão mal assim. Então, calma!&lt;/p&gt;

&lt;p&gt;Veja uma comparação salarial &lt;a href="https://www.nexojornal.com.br/interativo/2016/01/11/O-seu-sal%C3%A1rio-diante-da-realidade-brasileira"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Então, façam um favor a vocês, a sua carreira e a sua saúde: PAREM de discutir essa coisa de sênior de 2 anos (e outras discussões similares) e deem importância aos estudos. Só isso!&lt;/p&gt;

&lt;p&gt;Lá atrás (e até HOJE penso assim) eu dizia: podem me chamar até de estagiário. Me pagando o salário que lutei para ter, tudo bem!&lt;/p&gt;

&lt;p&gt;O mercado de TI está aquecido. E está mesmo. Difícil era quando eu era metalúrgico, que eu via sempre histórias de demissões em massa e achatamento de salários. &lt;/p&gt;

&lt;p&gt;É possível vermos demissões em massa em TI? Sim, é possível. Mas não dá pra comparar! E acho que vai levar um tempo ainda pra vermos isso com frequência.&lt;/p&gt;

&lt;p&gt;(OBS: não tenho ideia de como está a área metalúrgica hoje. O que sei é de 20 anos atrás. Espero que tenha mudado).&lt;/p&gt;

&lt;p&gt;Por último, acredito muito na ideia de ter um mentor. Alguém que lhe ajude a trilhar caminhos e que te dê umas dicas. Os que eu tive me ajudaram até quando eu estava em empresas, digamos, defasadas.&lt;/p&gt;

&lt;p&gt;Eles me diziam, indiretamente: calma, o melhor neste momento é usar essa boa prática, ou a tecnologia x ou y. Se você não consegue trabalhar assim ainda, não se preocupe. Você já sabe o que é fazer direito. Um dia você poderá trabalhar assim, nessa empresa ou em outra.&lt;/p&gt;

&lt;p&gt;Espero ter contribuído com menos &lt;a href="https://twitter.com/devscansados"&gt;@devscansados&lt;/a&gt; na internet com esse textão :D&lt;/p&gt;

&lt;p&gt;Por último, pra quem é mais velho e está em transição de carreira, recomendo os vídeos de carreira do &lt;a href="https://twitter.com/akitaonrails"&gt;Fabio Akita&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Aliás, vejam todos os vídeos do &lt;a href="https://www.youtube.com/channel/UCib793mnUOhWymCh2VJKplQ"&gt;Akita&lt;/a&gt; que vocês puderem!&lt;/p&gt;

&lt;p&gt;Se chegou até aqui, obrigado, de verdade :)&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>career</category>
    </item>
  </channel>
</rss>
