<?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: Rafael</title>
    <description>The latest articles on DEV Community by Rafael (@rs_marinheiro).</description>
    <link>https://dev.to/rs_marinheiro</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%2F555052%2Fb8654288-5d5c-4240-887c-3be893abb2f2.jpg</url>
      <title>DEV Community: Rafael</title>
      <link>https://dev.to/rs_marinheiro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rs_marinheiro"/>
    <language>en</language>
    <item>
      <title>Lazy/Eager - Carregamento de Entidades utilizando JPA com SpringBoot</title>
      <dc:creator>Rafael</dc:creator>
      <pubDate>Wed, 11 May 2022 20:44:19 +0000</pubDate>
      <link>https://dev.to/rs_marinheiro/lazyeager-carregamento-de-entidades-utilizando-jpa-com-springboot-46hp</link>
      <guid>https://dev.to/rs_marinheiro/lazyeager-carregamento-de-entidades-utilizando-jpa-com-springboot-46hp</guid>
      <description>&lt;p&gt;Um dos pontos mais importante na construção de um software é a performance, portanto entender as queries e otimizá-las ao máximo que puder pode resultar num belo ganho de desempenho.&lt;/p&gt;

&lt;p&gt;Partindo dessa premissa e por mais que utilizamos frameworks como SpringBoot que otimizam todo esse processo  entender o funcionamento do lazy e do eager da JPA(Java Persistence API) é fundamental para o desempenho de um APP, pois o uso de maneira errada pode resultar em grandes perdas de performance e forçar a aplicação a realizar diversas queries desnecessárias no banco de dados (podendo ocasionar assim o tão famoso problema das N+1 consultas).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lazy - Carregamento Preguiçoso&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vamos começar nossos estudos entendendo o lazy que é o carregamento default da JPA quando você não especifica nada. O lazy não faz o carregamento de determinados objetos até que você precise deles(daí vem a tradução de preguiçoso) ele ocorre quando temos entidades associadas para muitos isto é quando temos algum relacionamento OneToMany na nossa entidade.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Eager - Carregamento Ansioso/Guloso&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Oposto ao Lazy o eager ja traz do banco os objetos mesmo que você não vá utiliza-los, ele ocorre quando temos entidade associadas para um, isto é quando temos algum relacionamento ManyToOne na nossa entidade.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplificando&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vamos supor que no meu domínio de negócio eu tenho duas classes que se relacionam da seguinte maneira:&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%2Fbha69usmx2jqpu0sgneo.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%2Fbha69usmx2jqpu0sgneo.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reparem que no exemplo acima eu tenho um relacionamento um-para-muitos, já que um team pode conter muitos palyers e muitos players podem pertencer a um time.&lt;/p&gt;

&lt;p&gt;Pelo padrão da JPA quando eu busco um Player a JPA  já traz do banco o team  ao qual ele pertence(Eager), já quando eu busco o team a JPA não traz do banco os jogadores pertencentes ao time (Lazy)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vendo o Funcionamento na Pratica o Funcionamento do Eager&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para vermos como isso ocorre na pratica construí uma API com base no modelo apresentado acima(o link do projeto no GitHub estará ao final do artigo).&lt;/p&gt;

&lt;p&gt;Na minha API tenho as seguinte classes mapeadas:&lt;br&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%2F0z25mjdfjj87f4gjtqbg.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%2F0z25mjdfjj87f4gjtqbg.png" alt="Image description"&gt;&lt;/a&gt;&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%2Fhf43dgkiqne58veobsrh.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%2Fhf43dgkiqne58veobsrh.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No pacote Resource da minha API eu criei um controller com a seguinte  configuração:&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%2Frpsusg0jxs1tncxxxgho.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%2Frpsusg0jxs1tncxxxgho.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reparem que nesse controller eu chamo um service que irá buscar os dados do player pelo id e do resultado jogo num DTO que eu chamei PlayerDTO, portanto quando faço pelo browser/Postman/Insonia a seguinte chamada  (localhost:8080/player/1) a API retorna os seguintes dados do player:&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%2Fvexjde3xwpdryq4n440p.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%2Fvexjde3xwpdryq4n440p.PNG" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bem se habilitarmos o sql lá no nosso application.properties, para vermos as queries que a API faz lá no console veremos o seguinte detalhe:&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%2Fy5xkutfknc1ljiw7tv82.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%2Fy5xkutfknc1ljiw7tv82.PNG" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vejam que mesmo não precisando dos dados do team a JPA faz um join (desnecessário nesse caso já que eu só quero os dados do player) na minha tabela team conforme destacado em amarelo, já que como vimos acima por padrão toda vez que a entidade  tem uma associação para um o carregamento e eager.&lt;/p&gt;

&lt;p&gt;Agora você deve se está se perguntando então como eu faço para customizar essa busca, isto é quero evitar esse join desnecessário?&lt;/p&gt;

&lt;p&gt;Bem uma forma e você definir um fetch na mão(muita cautela ao fazer isso pois você pode estar piorando a performance em outros endpoints dependendo do contexto do negócio) da seguinte maneira:&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%2Fc1e06q2cip2qhvessbqa.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%2Fc1e06q2cip2qhvessbqa.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao rodarmos a consulta novamente veremos na console a seguinte query:&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%2Febwp6ltg6d93vvjmy6ql.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%2Febwp6ltg6d93vvjmy6ql.PNG" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reparem que desta vez ele não fez join la na minha tabela team e tudo funcionou de boa.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vendo o Funcionamento na Prática do Lazy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Continuando no estudo da nossa API vamos vê agora o funcionamento do Lazy, para isto no meu pacote resource criei o seguinte controller&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%2Frp6060cyacoe21ngwi9m.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%2Frp6060cyacoe21ngwi9m.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reparem que nesse controller eu chamo um service que irá buscar os dados do team pelo id e do resultado jogo num DTO que eu chamei TeamDTO, portanto quando faço pelo browser/Postman/Insonia a seguinte chamada  (localhost:8080/team/1) a API retorna os seguintes dados do team:&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%2Fw62xnjsuy5vm3yna0rae.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%2Fw62xnjsuy5vm3yna0rae.PNG" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora se dermos uma olhada novamente no console veremos as seguintes queries:&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%2Fdavfssrvfz0cmxo90srj.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%2Fdavfssrvfz0cmxo90srj.PNG" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reparem que quando executamos essa chamada o JPA faz duas queries na primeira ele busca os dados do player e na segunda de team.&lt;br&gt;
Bem agora você deve esta se fazendo uma outra pergunta, Ué mas como ele fez essa mágica?&lt;/p&gt;

&lt;p&gt;Isso só ocorreu pois lá no TeamService eu faço a seguinte chamada conforme vemos abaixo:&lt;/p&gt;

&lt;p&gt;result.get().getPlayers()&lt;/p&gt;

&lt;p&gt;O getPlayers() que usei disparou outra consulta no banco para buscar os dados do player. Portanto  conforme vimos acima por padrão toda vez que a entidade  tem uma associação para muitos o carregamento é Lazy(preguiçoso) a JPA não traz o objeto até que você precise dele.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Considerações Finais&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O objetivo deste artigo foi justamente apresentar aos leitores os conceitos do Fetch/Eager tão utilizados na JPA. O bom entendimento desses conceitos pode acarretar em ganhos de performance na sua aplicação desde que você adote a melhor prática baseado no seu modelo de negócio.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links/Referencias Bibliográficas&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Repositório do Git da demo: &lt;a href="https://github.com/rmarinheiro/demolazyeager" rel="noopener noreferrer"&gt;https://github.com/rmarinheiro/demolazyeager&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.baeldung.com/hibernate-lazy-eager-loading" rel="noopener noreferrer"&gt;https://www.baeldung.com/hibernate-lazy-eager-loading&lt;/a&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>java</category>
    </item>
    <item>
      <title>Desenvolvimento em Camadas utilizando DTO
</title>
      <dc:creator>Rafael</dc:creator>
      <pubDate>Wed, 23 Feb 2022 00:14:18 +0000</pubDate>
      <link>https://dev.to/rs_marinheiro/desenvolvimento-em-camadas-utilizando-dto-3n5i</link>
      <guid>https://dev.to/rs_marinheiro/desenvolvimento-em-camadas-utilizando-dto-3n5i</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DoWns6eA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9g4ldzi4yckahb4gf98w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DoWns6eA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9g4ldzi4yckahb4gf98w.png" alt="Image description" width="380" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Durante a construção de um sistema em java é comum dividirmos nossa aplicação num modelo que chamamos de camadas, o grande “barato” desse modelo é a possibilidade de separarmos componentes de acordo com as suas responsabilidades.&lt;/p&gt;

&lt;p&gt;Muitos desenvolvedores principalmente a galera que tá começando agora acha bobagem isso(é só mais um processo burocrático que a galera do Java inventou), mas se formos pensar em grandes projetos de software onde há uma grande quantidade de desenvolvedores atuando em torno do mesmo projeto, não arquitetar o sistema em camadas pode implicar em códigos ilegíveis e confusos, dificultando e muito a vida de novos devs que venham no futuro a dar manutenção no sistema em questão.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplificando&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vamos supor que tenhamos a seguinte arquitetura de camadas no nosso projeto:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mMoZfvtK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/696xwqr0811a2g1qlbqa.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mMoZfvtK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/696xwqr0811a2g1qlbqa.jpg" alt="Image description" width="645" height="671"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;No Item 1 temos a nossa aplicação web se comunicando com o nosso controller por meio de chamadas Http passando objetos JSON;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No Item 2 temos o nosso controller(que é componente responsável pelas interações com a camada web), recebendo as solicitações vindas da  web e chamando o service passando um objeto do tipo DTO (ja vamos falar dele mais abaixo).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No Item 3 o nosso service(que é o componente responsável em executar as partes lógicas e regras de negócio da nossa aplicação) pega esse objeto DTO transforma para o padrão entidade mais popularmente conhecido como ORM(Mapeamento Objeto Relacional) e passa esse objeto que ele acabou de converter para o repository.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No Item 4 o repository( que é a camada responsável pelo acesso a dados) vai até o Banco de Dados e executa a consulta.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reparem que após a execução da consulta no banco o repository retorna  o objeto ORM para a camada service, esse por sua vez transforma novamente para o padrão DTO e devolve esse DTO para a camada controller e esse por sua vez devolve novo DTO obtido para camada web.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mas Afinal o que é esse tal DTO que tanto foi falado acima?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O DTO(Data Transfer Object) como o próprio nome já diz é um padrão de projeto onde tem como intuito transferir dados de um local para o outro da aplicação sem nenhum tipo de regra de negócio embutida no meio,possibilitando assim que façamos uma ordenação dos dados antes de exibirmos na nossa aplicação e uma diminuição no tráfego de rede,já que não há mais necessidade de retornar uma entidade com uma paulada de atributos.&lt;/p&gt;

&lt;p&gt;Vamos supor que tenhamos na nossa aplicação a seguinte classe:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eNsoH4x5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0m61b1q58dy24wm82k0w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eNsoH4x5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0m61b1q58dy24wm82k0w.png" alt="Image description" width="722" height="598"&gt;&lt;/a&gt;&lt;br&gt;
Repare que a minha classe User eu possuo algumas informações sigilosas como password e id(que é a forma como a informação é armazenada no banco de dados), por questões de segurança não gostaríamos de exibir essas informações através de um serviço rest. Se optarmos por utilizar diretamente essa classe User no retorno dos nossos métodos dentro da nossa classe controller iremos expor essas informações e não é isso que queremos,para resolver esse problema podemos criar uma classe chamada UsuarioDTO  e ao invés de retornar nos nossos métodos todos os atributos da entidade vamos retornar o DTO com os atributos que queremos isto é   “omitimos” as informações que  queremos exibir, conforme podemos vê no exemplo abaixo:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bUr1eblR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lljgfas0ihepcccfp9gd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bUr1eblR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lljgfas0ihepcccfp9gd.png" alt="Image description" width="856" height="782"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Repare que no código acima e estou definindo que o meu UsuarioDTO só vai ter os atributos nome e email os demais eu estou "omitindo".&lt;/p&gt;

&lt;p&gt;Um outro ponto a se observar no código acima é que utilizamos um método construtor que tem a finalidade de converter uma entidade no nosso caso User em um objeto do tipo DTO que no nosso caso se chamará UsuarioDTO.&lt;/p&gt;

&lt;p&gt;Portanto toda vez que a nossa camada service estiver devolvendo dados para o controller precisaremos chamar este construtor conforme podemos ver no exemplo abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vc-CfOAn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/njja8wx5aqfgiop6tdsl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vc-CfOAn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/njja8wx5aqfgiop6tdsl.png" alt="Image description" width="880" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Caso queiramos fazer o inverso isto é converter de DTO para entidade poderíamos criar um método privado dentro da classe UserService onde faríamos essa conversão conforme podemos ver no exemplo abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1uWTzBfm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oh42zn9tmbuz08kn0jv4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1uWTzBfm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oh42zn9tmbuz08kn0jv4.png" alt="Image description" width="880" height="627"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lembrando que esta é apenas uma das formas que a galera usa para fazer conversão de DTOs para entidades e vice e versa, existem algumas ferramentas com &lt;a href="http://modelmapper.org/"&gt;modelmapper&lt;/a&gt; que facilita a vida nesse processo de conversão.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Considerações Finais&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A ideia deste artigo foi mostrar aos leitores a idéia central  acerca do padrão de projeto DTO, mostrando sua real utilidade na forma como podemos proteger dados sensíveis, além de mostrar a você leitor o real ganho de qualidade e de organização de código  quando adotamos uma arquitetura baseada em camadas.&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>java</category>
    </item>
    <item>
      <title>Documente sua API SpringBoot com Swagger
</title>
      <dc:creator>Rafael</dc:creator>
      <pubDate>Thu, 02 Sep 2021 01:27:23 +0000</pubDate>
      <link>https://dev.to/rs_marinheiro/documente-sua-api-springboot-com-swagger-cni</link>
      <guid>https://dev.to/rs_marinheiro/documente-sua-api-springboot-com-swagger-cni</guid>
      <description>&lt;p&gt;Documentação é um ponto essencial e chave para qualquer projeto de softwares  eu costumo dizer que a documentação é o coração de qualquer projeto, afinal uma aplicação que está mal documentada ou com nenhum tipo de documentação pode dificultar o entendimento por parte da equipe e de usuários sobre o comportamento da mesma.&lt;br&gt;
Portanto neste artigo iremos mostrar uma poderosa ferramenta que tem como intuito ajudar desenvolvedores nessa tarefa de criar boas documentações de suas APIs de forma rápida e automatizada.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O que é SWAGGER?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Swagger é um framework opensource composto por diversas ferramentas, que auxilia o desenvolvedor na descrição, no consumo e na visualização de uma API REST,no entanto para realizar tais tarefas o Swagger se utiliza de uma especificação chamada OPENAPI que define um padrão padronizado de uma requisição JSON.&lt;br&gt;
Como já dissemos anteriormete o swagger é composto por diversas ferramentas mas as principais são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Swagger Editor - sua função principal é ajudar o desenvolvedor a definir uma estrutura  de uma API no inicio de um projeto(&lt;a href="https://editor.swagger.io/" rel="noopener noreferrer"&gt;https://editor.swagger.io/&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Swagger Codegen - sua função principal é criar todo o “esqueleto” da API a partir de uma descrição em YAML.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Swagger UI - sua função principal é criar uma documentação elegante,por meio de uma interface gráfica, onde usuários podem descrever suas APIs e realizar testes nas mesmas sem que haja qualquer tipo de dano aplicação em ambiente de produção.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neste artigo vamos mostrar como integrar uma aplicação java utilizando o Swagger UI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adicionando a Lib SpringFox numa API com Spring Boot&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Com a aplicação criada e com os endpoints funcionando,adicione no pom.xml essas duas dependências:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;io.springfox&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;springfox-swagger2&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;2.9.2&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;

&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;io.springfox&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;springfox-swagger-ui&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;2.9.2&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com as dependências recém colocadas na aplicação chegou a hora de habilitar o swagger, para isto no pacote principal da aplicação dentro da classe  Application(classe esta que dá o start na aplicação e inicializa todos os beans) ou se preferir você pode criar uma classe  de configuração SwaggerConfig conforme podemos vê abaixo:&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%2Ff0gg12g4mhnn3k749o1w.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%2Ff0gg12g4mhnn3k749o1w.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Neste método estamos definindo que nosso bean que chamamos de Docket terá acesso a  todos os endpoints da aplicação, além disso criamos um método privado que retorna um objeto do tipo ApiInfo &lt;br&gt;
que tem como objetivo criar informações customizadas acerca dos nossos endpoints.Com isso através de reflection a lib já consegue obter os endpoints que estão disponíveis na aplicação. &lt;br&gt;
Para acessar o Swagger UI é necessário digitar(&lt;a href="http://localhost:8080/swagger-ui.html" rel="noopener noreferrer"&gt;http://localhost:8080/swagger-ui.html&lt;/a&gt;) o resultado será semelhante ao da figura abaixo:&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%2Fqal14gvzetne6m3f4scj.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%2Fqal14gvzetne6m3f4scj.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Personalizando Mensagens Globais:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Caso você precise personalizar todos os códigos de retorno que um endpoint retorne você precisará utilizar dentro do  nosso bean Docket o método globalMessage recebendo como parâmetro um método http e uma lista de ResponseMessage conforme podemos ve abaixo(no meu caso eu fui definindo atributos final do tipo ResponseMessage e na chamada do globlaResponseMessage fui colocando esses atributos dentro de um array)&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%2F32ijdi2df3mvnfeoxwf1.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%2F32ijdi2df3mvnfeoxwf1.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Utilizando Autenticação no Swagger&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Caso sua aplicação utilize algum tipo de autenticação é necessário configurarmos no SpringFox, para isto utilizamos  dois métodos o securityContext e SecurityScheme. No primeiro método defino o tipo de autenticação( se é ApiKey,BasichAuth,OAuth) e o segundo defino particularidades da autenticação.&lt;/p&gt;

&lt;p&gt;No exemplo abaixo definimos uma autenticação do tipo ApiKey dentro do nosso bean Docket e definimos que o endpoint pedido deverá ter uma autenticação:&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%2F9uvincji6255mmbmjvmz.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%2F9uvincji6255mmbmjvmz.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após isso, rode novamente e ao acessar novamente a tela do Swagger-UI você verá no canto direito o botão Authorize conforme podemos vê na imagem abaixo:&lt;/p&gt;

&lt;p&gt;Ao clicar nele ele pedirá que você informe seu token    &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%2Fduff4cr04de30n396n5j.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%2Fduff4cr04de30n396n5j.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após informar seu token já será possível realizar consultas nos endpoints que exijam autenticação&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>java</category>
    </item>
    <item>
      <title>Fundamentos de Teste Automatizados
</title>
      <dc:creator>Rafael</dc:creator>
      <pubDate>Sun, 04 Jul 2021 00:56:17 +0000</pubDate>
      <link>https://dev.to/rs_marinheiro/fundamentos-de-teste-automatizados-43a7</link>
      <guid>https://dev.to/rs_marinheiro/fundamentos-de-teste-automatizados-43a7</guid>
      <description>&lt;p&gt;Por mais que se planeje a construção de um software,fazendo o uso de tecnologias de ponta do mercado, adotando as melhores práticas no desenvolvimento de uma aplicação, erros são passíveis de ocorrer, o que acaba gerando grandes dores de cabeça para usuários  projetistas e  prejuízos astronômicos para empresas principalmente se for uma aplicação com alta criticidade.&lt;br&gt;
    Quem já passou por isso sabe o quão desagradável é ficar na mão quando um programa fecha de forma inesperada devido a um bug no sistema, este fato poderia ter sido evitado caso a equipe em questão estivesse como hábito a utilização das ferramentas de teste apropriadas para a detecção do bug.&lt;br&gt;
Portanto um dos benefícios quando temos o hábito de testar um software é detectar de forma rápida se determinada mudança acaba violando determinada regra e qual impacto que essa mudança pode trazer para quem está utilizando o software, simulando casos reais e avaliando se todas as funcionalidades entregues estão funcionando de forma correta e segura, em outras palavras é no teste que podemos avaliar se o programa está funcionando de forma esperada. Justamente por todos esses argumentos já citados que equipes e empresas gastam tempo e recursos na adoção de ferramentas e metodologias de teste.&lt;br&gt;
    Atualmente existem diversos tipos de testes para detectarmos os mais variados cenários(daria até para fazer um livro) mas o enfoque do artigo será nos testes automatizados.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O que é um teste automatizado?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No decorrer do desenvolvimento e na manutenção de um sistema a complexidade tende a aumentar, projetista e desenvolvedores passam a ter dificuldades em avaliar se os recursos estão funcionais ou não  pois o software que antes contemplava poucos cenários agora passa a atender um número muito maior de casos deixando sua complexidade "N" vezes maior..&lt;br&gt;
Para auxiliar os times de alta performance na avaliação de softwares é que utilizamos os testes automatizados que nada mais é que um software escrito por alguém que tem intuito de avaliar o seu sistema.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3 tipos de testes automatizados&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Os testes funcionais podem ser feitos de diversas maneiras, mas as 3 abordagens que o mercado mais utiliza que tem como intuito detectar bugs no menor tempo possível sem comprometer a qualidade do sistema são:&lt;/p&gt;

&lt;p&gt;1.Teste Unitário&lt;br&gt;
    É o teste feito pelo desenvolvedor tem como intuito validar o comportamento funcional do código, em outras palavras estamos testando os métodos de uma classe, com base numa  determinada entrada qual resposta que esperamos que aconteça.&lt;br&gt;
Nesse tipo de teste não podemos acessar outros componentes(isto é não podemos criar objetos de outras classes), ou recursos externos(como bd,rede, web services e etc).&lt;br&gt;
Caso haja necessidade de instanciar  objetos de outras classes ou simularmos o retorno de algum webservice  para executarmos um teste unitário por exemplo utilizamos de um artifício que é mocar um objeto ou serviço(isto é criar um objeto fake ) para podermos simular o resultado esperado. Utilizamos uma ferramenta muito popular usada para realizarmos o mock é o mockito.&lt;br&gt;
Nos testes unitários também utilizamos uma ferramenta muito famosa chamada Junit.&lt;/p&gt;

&lt;p&gt;2.Integração&lt;br&gt;
  Também conhecido como teste de web service/API é o teste voltado em verificar a  comunicação entre componentes/módulos e recursos externos de uma aplicação. O objetivo deste teste é verificar se a interação entre os componentes e APIs está ocorrendo de forma correta. &lt;br&gt;
Geralmente neste tipo de teste utilizamos ferramentas já conhecida por desenvolvedores como SoapUI e PostMan.&lt;/p&gt;

&lt;p&gt;3.Funcional&lt;br&gt;
É o teste do ponto de vista do usuário final  que tem como finalidade verificar se uma determinada funcionalidade tá sendo executada da forma esperadacomo foi planejada, em outras palavras estamos testando os nossos casos de uso.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefícios em Utilizar Teste Automatizados&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Como já dito acima um dos benefícios em utilizar testes automatizados em um projeto é detectar de forma mais rápida se determinadas mudanças violam regras de negócio.&lt;/li&gt;
&lt;li&gt;Além disso o uso testes automatizados é uma forma de documentar 
aplicação, já que quando estamos implementando os testes na nossa aplicação a lógica tende a ser a mais simples clara e objetiva possível,o comportamento dos métodos quais entrada/saídas e os resultados esperados.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Redução de custos de manutenção, pois num desenvolvimento de software a etapa de validação,homologação e até mesmo de manutenção é muito custosa, portanto se a sua aplicação estiver com uma boa cobertura de testes certamente você passará por essa etapa sem muitas dores no bolso.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Melhorias no design da solução, pois a cada feature nova a aplicação é testada, possibilitando mudanças na estrutura arquitetural de uma aplicação.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;TDD - Test Driven Development&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Antes de mais nada é importante esclarecermos que TDD é nada mais que um &lt;strong&gt;método de desenvolver testes&lt;/strong&gt; isso significa dizer que o TDD é uma definição da maneira como a equipe irá trabalhar na elaboração dos testes, não é o foco do TDD  avaliar se os testes estão sendo bem ou mal executados ou se o projeto tem ou não tem testes.Além disso não significa necessariamente que um software só por ter testes automatizados possa ser de cara já encaixado no padrão do TDD.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Principais Vantagens Na Utilização do TDD&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Foco nos requisitos isto é no TDD você começa primeiro pelos testes antes de sair de cara implementando algo. Neste momento você não está preocupado como o método será implementado e sim qual o comportamento e esperado dele após inserirmos uma determinada informação.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Melhora o design da aplicação pois o código desenvolvido passa a ser testado repetidas vezes, evitando que tenhamos que escrever códigos demasiadamente complexos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dá mais segurança ao desenvolvedor na hora de implementar novas &lt;br&gt;
funcionalidades, tendo assim mesmo chance de quebrar a aplicação devido alguma feature nova.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Processo Básico&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Bem já que falamos que o TDD é um metodologia para o desenvolvimento de testes abaixo vamos listar alguns itens básicos levados em consideração no TDD.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Como já dito acima o TDD prega a cultura de escrever primeiro os testes antes de sair desenvolvendo um método, nesta etapa a preocupação é descrever o comportamento do método baseado numa entrada(é natural que nesta etapa o seu teste ainda esteja falhando pois o componente ainda não foi implementado).&lt;/li&gt;
&lt;li&gt;Agora sim nessa etapa você deverá implementar o código, os casos de uso e os componentes necessários para que o teste passe.&lt;/li&gt;
&lt;li&gt;Essa etapa é opcional e avalia a necessidade de refatoração do código mediante a necessidade.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Boas Praticas e Padrão Quando Estamos Implementando Testes Automatizados&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Neste tópico vou procurar mostrar algumas das melhores praticas e padrões quando estamos desenvolvendo testes automatizados(eu sei que é um tema polêmico e não existe uma regra universal e cada equipe faz da forma que deseja), mais abaixo procuro demonstrar o que na visão de vários especialistas é importante:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nomenclatura de Teste (AÇÃO should EFEITO when CENÁRIO)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dado uma ação qual será o efeito(should efeito) dela mediante aquele cenário(when cenário) exemplos:&lt;/p&gt;

&lt;p&gt;Ação : Método Delete&lt;br&gt;
Efeito: Dado um determinado ID deverá excluir um determinado registro do BD.&lt;br&gt;
Cenário: Quando o ID existir&lt;/p&gt;

&lt;p&gt;Ação : Método Delete&lt;br&gt;
Efeito: Lançar uma exceção quando a aplicação não encontrar um ID Cenário: Quando o ID não existir&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Padrão AAA&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Arrange : Primeiro instancie os objetos necessários(de new nos objetos que você irá utilizar)&lt;/li&gt;
&lt;li&gt;Act: execute as ações necessárias isto é faça o que tem de ser feito no método isto é caso seja necessário  inserir/atualizar um  dado no Banco de Dados por exemplo&lt;/li&gt;
&lt;li&gt;Assert: declare o que deveria acontecer (resultado esperado).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Princípio da Inversão de Controle(SOLID)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Uma classe A jamais poderá depender da instância de uma classe B(se isso estiver sendo feito esse teste não pode ser chamado de teste unitário). Caso você precise acessar instâncias de outras classes precisaremos criar mocks(objetos fakes como já dito acima).&lt;br&gt;
Isso acaba ajudando na testabilidade do método garantindo assim o isolamento da unidade a ser testada.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Independência&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Um teste não pode depender de outro teste e  a ordem de como o teste será executado pouco importa, portanto é uma boa pratica que os testes sejam independentes um não pode ficar dependendo de dados do outro.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cenário Único&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cada teste deve ter um cenário especifico, e sua lógica deve ser a mais simples possível sem o uso de loops ou operadores condicionais.&lt;br&gt;
Se você reparou no exemplo acima foi criado um cenário onde um ID existia e um outro cenário onde não existia o ID.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Previsibilidade&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O resultado de um teste deve ser sempre o mesmo para os mesmos dados,evite que o seu teste faça depender de coisas que variam como: timeStamp atual(new Date,instant.now) e valores aleatórios (como random).&lt;/p&gt;

</description>
      <category>tdd</category>
      <category>java</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Manual de Sobrevivencia:Git/GitHub    </title>
      <dc:creator>Rafael</dc:creator>
      <pubDate>Fri, 25 Jun 2021 22:10:26 +0000</pubDate>
      <link>https://dev.to/rs_marinheiro/manual-de-sobrevivencia-git-github-13cp</link>
      <guid>https://dev.to/rs_marinheiro/manual-de-sobrevivencia-git-github-13cp</guid>
      <description>&lt;p&gt;100 em cada 100 desenvolvedores preferem utilizar o Git/GitHub para controle e hospedagem dos arquivos fontes(se você não leu o artigo anterior onde apresento e dou uma breve explicada sobre controle e versionamento de código corre lá [&lt;a href="https://dev.to/rs_marinheiro/controle-de-versao-versionamento-de-codigo-1hg"&gt;https://dev.to/rs_marinheiro/controle-de-versao-versionamento-de-codigo-1hg&lt;/a&gt;].&lt;br&gt;
Criado por Linus Trovalds em 2005(isso mesmo o mesmo cara que criou o Linux) o git acabou se tornando a ferramenta de versionamento open-source mais utilizada por empresas e desenvolvedores ao redor do mundo, além de funcionar bem em várias IDEs ,Sistemas Operacionais, permite integração com softwares de terceiros como Jira por exemplo.&lt;br&gt;
Este artigo tem como objetivo de apresentar ao leitor  esta poderosa ferramenta,de versionamento de código,e mostrar aos leitores comandos essenciais do dia a dia para quem deseja sair do ponto inicial.&lt;/p&gt;

&lt;p&gt;Como já mencionamos no artigo anterior o Git trabalha de forma distribuída e por trabalhar de forma distribuída o git se divide em 4 áreas diferentes conforme podemos ver na figura abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Jz4iR5aW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/quedqvznla1qfnra302x.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Jz4iR5aW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/quedqvznla1qfnra302x.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Working Directory(Diretório Trabalho) : como o próprio nome já diz é o diretório onde você utiliza para trabalho, sem correr o risco de estragar nada, é como se você estivesse usando um localHost da vida para editar seus arquivos.&lt;/p&gt;

&lt;p&gt;Stagging Area(Area de Estagiamento): é o cara que faz o meio de campo entre seu diretório local e o repositório local,é nessa área onde ficam os arquivos que estão aptos a serem salvos no repositório local.De forma análoga é como se estivéssemos usando esta área para colocar numa caixa aquilo que desejamos subir para produção.&lt;/p&gt;

&lt;p&gt;LocalRepo(RepositorioLocal): local onde os seus fontes ficam salvos, todas as alterações ficam em uma pasta compacta dentro do diretório .git.De forma análoga é como se estivéssemos fechando a caixa com os itens que colocamos no passo anterior.&lt;/p&gt;

&lt;p&gt;RemoteRepo(Repositorio Remoto):local responsável por centralizar em um só lugar todos os repositórios de todos os desenvolvedores envolvidos do projeto. Essa centralização é feita através do uso de servidores remotos como mais popular temos o GitHub.&lt;/p&gt;

&lt;p&gt;Agora que você conheceu um pouco a forma de funcionamento do git vamos por a mão na massa.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instalação&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Caso você ainda não tenha o git instalado a seguir disponibilizo link que te ajudara a instala-lo na sua máquina Linux/Windows/Mac (sua instalação é bem simples nada que faça você perder o sono)&lt;br&gt;
[&lt;a href="https://git-scm.com/"&gt;https://git-scm.com/&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;Após instalação abra o terminal de sua preferência(caso você esteja utilizando o Windows você pode utilizar o Git Bash Here vá em qualquer pasta com o botão direito abra o Git Bash Here) rode o seguinte comando &lt;strong&gt;git --version&lt;/strong&gt; com na imagem abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pdYCw8Kg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a2ktgvlo2wn0vtszqsf9.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pdYCw8Kg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a2ktgvlo2wn0vtszqsf9.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se o resultado for igual o da imagem parabéns o git foi instalado corretamente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configurações Iniciais&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Após a instalação do git é necessário que você configure seu usuário e coloque seu endereço de email afinal de contas as pessoas precisam saber quem é você e quem fez determinada alteração no código para isso no seu terminal digite o seguintes comandos:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;git config --global user.name “Seu Nome”&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;git config --global user.email “Email que você vai utilizar”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pronto após essa configuração o próximo passo será a criação de um repositório local para que possamos realizar nossos commits e em seguida possamos hospedar no github.&lt;br&gt;
Para isso na pasta  onde encontra-se o seu projeto rode o seguinte pela linha de comando o comando &lt;strong&gt;git init&lt;/strong&gt;.:&lt;/p&gt;

&lt;p&gt;Aqui vale uma ressalva ao rodar esse comando o git cria uma pasta oculta .git dentro do diretório  conforme imagem abaixo(caso você não esteja visualizando este arquivo na pasta onde foi rodado o comando é necessário habilitar a visualização de arquivos ocultos no Painel de Controle do Windows ou do sistema operacional que estiver usando)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NzDP6QWn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7yo59xlyiicl46jjn028.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NzDP6QWn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7yo59xlyiicl46jjn028.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comandos Básicos&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Após rodar o comando git init na pasta onde se encontra o seu projeto, você agora pode querer visualizar quais arquivos que estão no seu projeto e que você deseja coloca-los na área de stage(como já mencionamos acima) para isto pelo terminal  na pasta onde você criou seu repositório local rode o seguinte comando &lt;strong&gt;git status&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FhGJmVxt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rk1jem9of0vj8v1tqb1p.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FhGJmVxt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rk1jem9of0vj8v1tqb1p.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Verifique que após rodarmos esse comando foi possível visualizar que o arquivo que eu tinha acabado de adicionar no repositório(novo_documento.txt) ficou com a cor vermelha isto significa que este arquivo já está apto para ser colocado na área de stage, para isto vamos rodar o seguinte comando &lt;strong&gt;git add .&lt;/strong&gt; (como o próprio git nos sugere na imagem acima) e como podemos visualizar na imagem abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zFBKd7OT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lgl6bcqcz3zk8yvpbr8k.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zFBKd7OT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lgl6bcqcz3zk8yvpbr8k.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após rodarmos esse comando e dermos novamente um git status você verá o seguinte resultado:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jSmalfba--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b4ruvbqtbkebo3byfau0.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jSmalfba--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b4ruvbqtbkebo3byfau0.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O arquivo que eu criei que antes estava na cor vermelha agora aparece na cor verde isto significa que  este arquivo agora está pronto para ser commitado.&lt;/p&gt;

&lt;p&gt;Para commitarmos basta dar o seguinte o comando &lt;strong&gt;git commit -m “Comentário Qualquer”&lt;/strong&gt; conforme vemos na imagem:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Q2K0UQ29--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vtw8uc46l3jsb9f446ho.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Q2K0UQ29--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vtw8uc46l3jsb9f446ho.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OBSIMP:&lt;/strong&gt; Sempre procure ser o mais sucinto possível na hora de adicionar um comentário lembre-se que você está trabalhando em equipe e as pessoas precisam entender o que você fez ninguém trabalha por adivinhação.**&lt;/p&gt;

&lt;p&gt;Pronto você acaba de fechar o seu pacote de alterações/mudanças e agora você já pode mandar pro gitHub, mas caso você precise vê um log de tudo que foi feito no projeto você tem a opção de rodar o comando &lt;strong&gt;git log&lt;/strong&gt; conforme vemos na imagem a seguir.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dhAwgSi3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l7n8010ysy9ncxvxijfz.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dhAwgSi3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l7n8010ysy9ncxvxijfz.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aqui vale uma breve ressalva no destaque em amarelo mostra um código hash criado pelo git após realizarmos o commit. Esse código é criado pelo git toda vez que commitamos algo é através desse código hash que o git identifica  cada commit realizado no seu projeto.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Criação do Repositório Remoto&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nesse passo é necessário que você já esteja com a conta no GitHub criada, após a criação da conta clique na foto do seu perfil e selecione a opção Your Profile como podemos vê na figura.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XJuKbJyw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wrizrsvn66ka7znhs4rx.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XJuKbJyw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wrizrsvn66ka7znhs4rx.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E em seguida selecione a opção new conforme imagem abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5CrJX_xd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v01j7awzbks9bcc598sy.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5CrJX_xd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v01j7awzbks9bcc598sy.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na tela seguinte crie um nome para o seu repositório conforme destaque da  imagem &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oLPaaKdZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uhr6xigkabqmzzcuxqtv.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oLPaaKdZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uhr6xigkabqmzzcuxqtv.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aqui vale outra ressalva caso você queira deixar seu projeto privado e só marcar a opção private&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configurando o SSH&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Antes de subir o projeto para o servidor GitHub é necessário configurar as chaves SSH, mas afinal o que é isso?&lt;/p&gt;

&lt;p&gt;A chave ssh é um protocolo de segurança exigido pelo GitHub que permite que somente a maquina na qual você configurou tenha acesso aos repositórios remotos, isso quer dizer que se você tentar acessar algum repositório remoto de uma outra maquina diferente da que você configurou, o GitHub não permitirá &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OBSIMP:&lt;/strong&gt; Aqui vale um ponto de atenção desde o dia 13 de Agosto de 2021 o GitHub não permite mais que  usuários entre com usuário e senha via linha de comando, daí a necessidade de configurarmos a chave SSH.&lt;/p&gt;

&lt;p&gt;Pelo terminal do GitBash digite o seguinte comando:&lt;/p&gt;

&lt;p&gt;ssh-keygen -t ed25519 -C "&lt;a href="mailto:your_email@example.com"&gt;your_email@example.com&lt;/a&gt;"&lt;/p&gt;

&lt;p&gt;-Logo após que você digitar esse comando de enter até o fim no processo de geração das chaves. Após esse passo vá até a pasta onde as chaves foram gerada(no meu caso ele gerou na pasta .ssh dentro do diretório C:/Usuarios/rafael do windows), e copie o conteúdo contido no arquivo de extensão .pub.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adicionando a Chave no GitHub&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Acesse sua conta no GitHub e no canto superior clique na setinha ao lado da foto e escolha a opção settings;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No canto esquerdo selecione a opção(SSH and GPG Keys);&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;E depois clique no botão New SSH Key&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Na tela Seguinte coloque um nome qualquer para sua chave e no campo key cole a chave publica que você obteve no topico anterior e clique no botão Add SSH Key.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Logo na sequencia você verá a chave recém configurada na sua conta GitHub, porém se faz necessário reiniciar a maquina (principalmente se você estiver utilizando Windows para que o Windows consiga reconhecer suas credencias)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Enviando seu Arquivo Para o GitHub&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Bem agora chegou a hora de mandar os nosso pacotinho pro servidor remoto para isto você verá que após a criação do repositório remoto o git apresenta a seguinte tela que nada mais que é uma espécie de colinha para mandar seus fontes pro servidor remoto:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iQQuBnJ4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lf1bak7flnjqna87tmr8.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iQQuBnJ4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lf1bak7flnjqna87tmr8.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para isto basta roda no seu terminal os dois últimos comandos(fazendo uma breve explicação desses comandos podemos perceber):&lt;br&gt;
O comando &lt;strong&gt;git remote&lt;/strong&gt; associa o repositório remoto ao repositório local da sua maquina;&lt;br&gt;
O comando &lt;strong&gt;git push&lt;/strong&gt; de fato pega todos os commits que foram realizados e manda lá pra main(este é o nome que o git coloca para determina que este cara é o repositório principal do seu projeto).&lt;/p&gt;

&lt;p&gt;Após rodarmos esse comando e em seguida irmos lá no gitHub e clicarmos no nome do nosso repositório você já verá que as alterações já estão contidas dentro do servidor do gitHub conforme imagem abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oYS-fylf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f9rh0toqntyleaut4p78.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oYS-fylf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f9rh0toqntyleaut4p78.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bem pessoal essa foi uma pequena introdução de como trabalhar com git/github além de apresentar alguns comandos básicos do dia a dia para que você comece a sair da inércia. &lt;br&gt;
Nos próximos artigos iremos nos aprofundar um pouco mais no fluxo do git.&lt;/p&gt;

</description>
      <category>github</category>
      <category>git</category>
      <category>java</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Controle de Versão (Versionamento de Código)</title>
      <dc:creator>Rafael</dc:creator>
      <pubDate>Sat, 16 Jan 2021 21:14:06 +0000</pubDate>
      <link>https://dev.to/rs_marinheiro/controle-de-versao-versionamento-de-codigo-1hg</link>
      <guid>https://dev.to/rs_marinheiro/controle-de-versao-versionamento-de-codigo-1hg</guid>
      <description>&lt;p&gt;Este artigo tem como intuito apresentar um dos conceitos que muitos iniciantes na área de desenvolvimento de software se deparam quando começam a desenvolver softwares de forma colaborativa e paralela o versionamento de código também conhecido como controle de versão.&lt;br&gt;
    Não precisamos dizer que o código fonte é um “bem precioso”  que precisa ser guardado e bem gerenciado para que catástrofes não venham a acontecer e jogar por água abaixo anos de trabalho e conhecimento adquirido ao longo de desenvolvimento de um sistema. Além disso o versionamento de código acaba ajudando os times a rastrear alterações feitas ao longo do desenvolvimento de um produto, facilitando assim na resolução de bugs sem prejudicar as demais versões estáveis que estão rodando em produção. &lt;br&gt;
     Legal mas você deve estar se perguntando agora como funciona  esse controle de versão?&lt;br&gt;
    Antes de mais nada você precisa entender que o sistema de controle de versão trabalham de duas formas:&lt;/p&gt;

&lt;p&gt;• O centralizado modelo este utilizado pelo SVN(também conhecido como Subversion) ele trabalha com o modelo de arquitetura chamada cliente-servidor(conforme podemos ver na figura abaixo) ou seja você tem um servidor central responsável pela versão estável do sistema que está em produção(trunk) e diversas ramificações (branchs) onde os desenvolvedores utilizam para desenvolver novas features do sistema. &lt;br&gt;
Após essas features passarem por todo o processo de validação/testes é  necessário que a equipe de desenvolvimento realize o que chamamos de merge isto é juntar as alterações dos fontes feitas pelo desenvolvedor na branch que ele utilizou para desenvolver em conjunto com a última versão estável que está em produção.Como você já percebeu uma das desvantagens deste modelo de versionamento é a escalabilidade quando temos muitos desenvolvedores atuando no mesmo repositório, e também não há a possibilidade de trabalhar offline, já que é necessário sempre estar conectado ao servidor. A figura abaixo ilustra um pouco essa metodologia de trabalho&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qc-HlyBG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/todhi4nsztsf4cnkk5p8.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qc-HlyBG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/todhi4nsztsf4cnkk5p8.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;• Já o modelo distribuído muito utilizado pelo popular GIT trabalha de uma forma um pouco diferente, cada desenvolvedor tem seu próprio “servidor” portanto as operações de check-in e check-out são realizadas na própria máquina do desenvolvedor e diferentemente do modelo centralizado, neste modelo as maquinas do desenvolvedores comunicam-se entre si. Por ser um modelo muito complexo onde diversos desenvolvedores do mundo todo podem atuar num mesmo projeto, recomenda-se a utilização de um servidor remoto que tem como intuito hospedar o projeto afim de evitar perdas de código ao longo do desenvolvimento de um sistema, conforme podemos observar na figura abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tzkW_Ihd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3imantzy262evlmk6wn7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tzkW_Ihd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3imantzy262evlmk6wn7.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dentre os servidores remotos  mais famosos que trabalham de forma distribuída temos: o GitHub(o mais popular e muito utilizado pela galera de OpenSource acabou se tornando uma espécie de rede social dos desenvolvedores), e o BitBucket(utilizado em projetos onde você deseja ter uma privacidade maior).Como já falamos por se uma metodologia onde o “servidor está na máquina do próprio desenvolvedor” o sistema distribuído acaba sendo mais rápido em comparação ao centralizado porém exige do time em questão  um conhecimento mais apurado das ferramentas e comandos que rodam em linha de comando.&lt;/p&gt;

&lt;p&gt;Bem depois dessa breve apresentação no próximo artigo iremos falar mais sobre o GIT, como funciona, principais comandos para criação e manipulação de repositórios.&lt;/p&gt;

</description>
      <category>github</category>
      <category>git</category>
      <category>svn</category>
      <category>braziliandevs</category>
    </item>
  </channel>
</rss>
