<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Cássio Leodegario - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Aprenda a codificar - de graça. Tutoriais de programação em Python, JavaScript, Linux e muito mais. ]]>
        </description>
        <link>https://www.freecodecamp.org/portuguese/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Cássio Leodegario - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/portuguese/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 23 May 2026 08:28:33 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/portuguese/news/author/cassio/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Princípios de programação orientada a objetos em Java: Conceitos de POO para iniciantes ]]>
                </title>
                <description>
                    <![CDATA[ > A programação orientada à objetos oferece uma forma sustentável de escrever código espaguete. Ela permite que você escreva programas como se fosse uma colcha de retalhos. ― Paul Graham Princípios de programação orientada a objetos  A programação orientada a objetos é um paradigma de programação onde tudo é ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/principios-de-programacao-orientada-a-objetos-em-java-conceitos-de-poo-para-iniciantes/</link>
                <guid isPermaLink="false">62c2ea08a3520206e79cfe3a</guid>
                
                    <category>
                        <![CDATA[ Programação orientada a objetos ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Cássio Leodegario ]]>
                </dc:creator>
                <pubDate>Thu, 15 Sep 2022 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Love-Home.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/java-object-oriented-programming-system-principles-oops-concepts-for-beginners/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Object-Oriented Programming Principles  in Java:  OOP Concepts for Beginners</a>
      </p><blockquote><em>A programação orientada à objetos<em> </em>oferece uma forma sustentável de escrever código espaguete<em>. </em>Ela permite que você escreva programas como se fosse uma colcha de retalhos<em>.</em></em><br><em><em>― Paul Graham</em></em></blockquote><h2 id="princ-pios-de-programa-o-orientada-a-objetos"><strong>Princípios de programação orientada a objetos </strong></h2><p>A programação orientada a objetos é um paradigma de programação onde tudo é representado como um objeto.</p><p>Objetos passam mensagens uns para os outros. Cada objeto decide o que fazer com uma mensagem recebida. A POO (em inglês, <em>OOP</em> - <em>Object Oriented Programming</em>) foca nos estados e comportamentos de cada objeto.</p><h3 id="o-que-s-o-objetos"><strong>O que são objetos?</strong></h3><p><strong>Um objeto é uma entidade que possui estados e comportamentos.</strong></p><p>Por exemplo, cão, gato e veículo. Para ilustrar, um cão possui estados como idade, cor, nome e comportamentos como comer, dormir e correr.</p><p>Os estados nos dizem como o objeto se parece ou quais propriedades ele possui.</p><p>O comportamento nos diz o que o objeto faz.</p><p>Podemos representar um cão do mundo real em um programa como um objeto de software definindo seus estados e comportamentos.</p><p>Objetos de software são uma representação de um objeto do mundo real. É alocado espaço em memória sempre que um objeto lógico é criado.</p><p>Um objeto pode também ser referenciado como uma instância de uma classe. Instanciar uma classe significa a mesma coisa que criar um objeto.</p><p>Algo importante de se lembrar quando estamos criando um objeto é: o tipo de referência deve ser <strong>do mesmo tipo</strong> ou um <strong>supertipo</strong> do tipo do objeto. Veremos o que é um tipo de referência mais a frente neste artigo.</p><h3 id="o-que-s-o-classes"><strong>O que são classes?</strong></h3><p><strong>Uma classe é um <em>template </em>- algo como a "planta" de uma construção - a partir do qual os objetos são criados<strong>.</strong></strong></p><p>Imagine uma classe como um cortador de biscoitos e os objetos como os próprios biscoitos.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/cookie-cutter.jpg" class="kg-image" alt="cookie-cutter" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/cookie-cutter.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/cookie-cutter.jpg 910w" sizes="(min-width: 720px) 720px" width="910" height="607" loading="lazy"><figcaption>Figura 1: ilustra a relação entre classe e objeto por meio do cortador de biscoitos e dos biscoitos em si. <a href="https://www.piqsels.com/en/public-domain-photo-sswme" rel="noopener">Fonte da imagem</a>.</figcaption></figure><p>Classes definem estados como variáveis de instância e comportamentos como métodos de instância.</p><p>Variáveis de instância também são conhecidas como "variáveis membro".</p><p>Classes não consomem espaço em memória.</p><p>Para dar uma ideia sobre classes e objetos, vamos criar uma classe Cat (Gato) que representa estados e comportamentos de um gato no mundo real.</p><pre><code class="language-java">public class Cat {
    /*
    Variáveis de instancia: Estados do gato
     */
    String name;
    int age;
    String color;
    String breed;

    /*
    Métodos de instancia: Comportamento do gato
     */
    void sleep(){
        System.out.println("Dormindo");
    }
    void play(){
        System.out.println("Brincando");
    }
    void feed(){
        System.out.println("Comendo");
    }

}</code></pre><p>Agora que definimos um <em>template </em>de gatos, vamos dizer que temos dois gatos, chamados Thor e Rambo.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Russian-Blue_01.jpg" class="kg-image" alt="Russian-Blue_01" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Russian-Blue_01.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Russian-Blue_01.jpg 970w" sizes="(min-width: 720px) 720px" width="970" height="505" loading="lazy"><figcaption>Figura 2: Thor está dormindo. <a href="https://www.petfinder.com/cat-breeds/collections/cutest-cat-breeds/" rel="noopener">Fonte da imagem</a></figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Maine-Coon_02.jpg" class="kg-image" alt="Maine-Coon_02" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Maine-Coon_02.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Maine-Coon_02.jpg 970w" sizes="(min-width: 720px) 720px" width="970" height="505" loading="lazy"><figcaption>Figura 3: Rambo está brincando. <a href="https://www.petfinder.com/cat-breeds/collections/cutest-cat-breeds/" rel="noopener">Fonte da imagem</a></figcaption></figure><p>Como podemos defini-los em nossos programas?</p><p>Primeiro, precisamos criar dois objetos da classe Cat.</p><pre><code class="language-java">public class Main {
    public static void main(String[] args) {
       Cat thor = new Cat();
       Cat rambo = new Cat();
    }
}</code></pre><p>Agora, vamos definir seus estados e comportamentos.</p><pre><code class="language-java">public class Main {

    public static void main(String[] args) {
       /*
       Criando os objetos
        */
       Cat thor = new Cat();
       Cat rambo = new Cat();

       /*
       Definindo o gato Thor
        */
       thor.name = "Thor";
       thor.age = 3;
       thor.breed = "Azul russo";
       thor.color = "Marrom";

       thor.sleep();

       /*
       Definindo o gato Rambo
        */
       rambo.name = "Rambo";
       rambo.age = 4;
       rambo.breed = "Maine Coon";
       rambo.color = "Marrom";

       rambo.play();
    }

}</code></pre><p>Como nos exemplos de código acima, podemos definir nossas classes, instanciá-las (criar objetos) e especificar os estados e comportamentos para esses objetos.</p><p>Até aqui já cobrimos o básico de orientação a objetos. Vamos avançar para os princípios da orientação a objetos.</p><h2 id="princ-pios-da-programa-o-orientada-a-objetos"><strong>Princípios da programação orientada a objetos</strong></h2><p>Esses são os quatro princípios fundamentais do paradigma de programação orientada a objetos. Entendê-los é essencial para se tornar um programador de sucesso.</p><ol><li>Encapsulamento</li><li>Herança</li><li>Abstração</li><li>Polimorfismo</li></ol><p>Agora, vamos dar uma olhada neles com mais detalhes.</p><h2 id="encapsulamento"><strong>Encapsulamento</strong></h2><p><strong>Encapsulamento é um processo de envolver dados e código em uma única unidade<strong>.</strong></strong></p><p>É como uma capsula que possui uma mistura de diversos medicamentos, é uma técnica que ajuda a manter as variáveis de instância protegidas.</p><p>Essa proteção pode ser conquistada utilizando o modificador de acesso <code>private</code>, que indica que a variável ou dado não pode ser acessado de fora da classe. Para acessar estados privados de modo seguro, temos que providenciar métodos <em>getters </em>e <em>setters </em>públicos (em Java, esses métodos devem seguir os padrões de nomenclatura "JavaBeans").</p><p>Digamos que existe uma loja de discos que vende álbuns de músicas de diferentes artistas e um estoque para o gerenciamento.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/classDiagramWithoutEncapsulation.png" class="kg-image" alt="classDiagramWithoutEncapsulation" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/classDiagramWithoutEncapsulation.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/classDiagramWithoutEncapsulation.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/classDiagramWithoutEncapsulation.png 1331w" sizes="(min-width: 1200px) 1200px" width="1331" height="291" loading="lazy"><figcaption>Figura 4: diagrama de classes sem encapsulamento</figcaption></figure><p>Se você observar a figura 4, a classe <code>StockKeeper</code> pode acessar os estados da classe <code>Album</code> diretamente, já que os atributos da classe <code>Album</code> estão definidos como <code>public</code> (sinal de +).</p><p>Se o gerenciador de estoque criar um álbum e definir seus estados como negativos, ele pode acabar fazendo isso mesmo que sem intenção.</p><p>Para ilustrar, vamos ver um exemplo de um programa em Java que explica o diagrama e a afirmação acima.</p><p>Classe Album:</p><pre><code class="language-java">public class Album {
    public String name;
    public String artist;
    public double price;
    public int numberOfCopies;
    public void sellCopies(){
        if(numberOfCopies &gt; 0){
            numberOfCopies--;
            System.out.println("Um album foi vendido!");
        }
        else{
            System.out.println("Não há albuns disponíveis!");
        }
    }
    public void orderCopies(int num){
        numberOfCopies += num;
    }
}</code></pre><p>Classe StockKeeper:</p><pre><code class="language-java">public class StockKeeper {
    public String name;
    public StockKeeper(String name){
        this.name = name;
    }
    public void manageAlbum(Album album, String name, String artist, double price, int numberOfCopies){
      /*
       Definindo os estados e comportamentos para album
       */
        album.name = name;
        album.artist = artist;
        album.price = price;
        album.numberOfCopies = numberOfCopies;

       /*
       Imprimindo os detalhes do album
        */
        System.out.println("Album gerenciado por :"+ this.name);
        System.out.println("Detalhes do album::::::::::");
        System.out.println("Nome do album: " + album.name);
        System.out.println("Artista do Album : " + album.artist);
        System.out.println("Preço do Album : " + album.price);
        System.out.println("Número de cópias do album : " + album.numberOfCopies);
    }
}</code></pre><p>Classe Main:</p><pre><code class="language-java">public class Main {
    public static void main(String[] args) {
       StockKeeper johnDoe = new StockKeeper("John Doe");
       /*
       O gerenciador de estoque cria um album e atribui valores negativos para o preço e o numero de cópias disponíveis
        */
       johnDoe.manageAlbum(new Album(), "Slippery When Wet", "Bon Jovi", -1000.00, -50);
    }
}</code></pre><p>Saída:</p><pre><code class="language-java">Album gerenciado por :John Doe
Detalhes do album::::::::::
Nome do album : Slippery When Wet
Artista do Album : Bon Jovi
Preço do Album :  -1000.0
Número de cópias do album : -50</code></pre><p>O preço do álbum e número de cópias não podem ser valores negativos. Como podemos evitar essa situação? Aqui é onde usamos o encapsulamento.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/classDiagramWithEncapsulation-1.png" class="kg-image" alt="classDiagramWithEncapsulation-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/classDiagramWithEncapsulation-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/classDiagramWithEncapsulation-1.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/classDiagramWithEncapsulation-1.png 1331w" sizes="(min-width: 1200px) 1200px" width="1331" height="291" loading="lazy"><figcaption>Figura 5: diagrama de classes com encapsulamento</figcaption></figure><p>Neste cenário, podemos impedir o gerenciador de estoque de atribuir valores negativos. Se ele tentar atribuir valores negativos para o preço e o número de cópias do álbum, definiremos 0.0 como o valor e 0 como o número de cópias.</p><p>Classe Album:</p><pre><code class="language-java">public class Album {
    private String name;
    private String artist;
    private double price;
    private int numberOfCopies;
    public void sellCopies(){
        if(numberOfCopies &gt; 0){
            numberOfCopies--;
            System.out.println("Um álbum foi vendido!");
        }
        else{
            System.out.println("Nenhum álbum disponível!");
        }
    }
    public void orderCopies(int num){
        numberOfCopies += num;
    }
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   public String getArtist() {
      return artist;
   }
   public void setArtist(String artist) {
      this.artist = artist;
   }
   public double getPrice() {
      return price;
   }
   public void setPrice(double price) {
      if(price &gt; 0) {
         this.price = price;          
      }
      else {
         this.price = 0.0;
      }
   }
   public int getNumberOfCopies() {
      return numberOfCopies;
   }
   public void setNumberOfCopies(int numberOfCopies) {
      if(numberOfCopies &gt; 0) {
         this.numberOfCopies = numberOfCopies;        
      }
      else {
         this.numberOfCopies = 0;
      }
   }
}</code></pre><p>Classe StockKeeper:</p><pre><code class="language-java">public class StockKeeper {
    private String name;
    StockKeeper(String name){
        setName(name);
    }
    public void manageAlbum(Album album, String name, String artist, double price, int numberOfCopies){
         /*
          Definindo estados e comportamentos para o album
          */
        album.setName(name);
        album.setArtist(artist);
        album.setPrice(price);
        album.setNumberOfCopies(numberOfCopies);
          /*
          Imprimindo os detalhes do album
           */
        System.out.println("Album gerenciado por :"+ getName());
        System.out.println("Detalhes do album::::::::::");
        System.out.println("Nome do album : " + album.getName());
        System.out.println("Artista do Album : " + album.getArtist());
        System.out.println("Preço do Album : " + album.getPrice());
        System.out.println("Número de cópias do album : " + album.getNumberOfCopies());
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}</code></pre><p>Classe Main:</p><pre><code class="language-java">public class Main {
    public static void main(String[] args) {
       StockKeeper johnDoe = new StockKeeper("John Doe");
       /*
       Gerenciador de estoque cria um album e atribui valores negativos para o preço e o número de cópias disponíveis do album
        */
       johnDoe.manageAlbum(new Album(), "Slippery When Wet", "Bon Jovi", -1000.00, -50);
    }
}</code></pre><p>Saída:</p><pre><code class="language-java">Album gerenciado por :John Doe
Detalhes do album::::::::::
Nome do album : Slippery When Wet
Artista do Album : Bon Jovi
Preço do Album : 0.0
Número de cópias do album : 0</code></pre><p>Com o encapsulamento, impedimos nosso gerenciador de estoque de definir valores negativos, o que significa que temos o controle sobre as informações.</p><h3 id="vantagens-do-encapsulamento-em-java"><strong>Vantagens do encapsulamento em Java</strong></h3><ol><li>Podemos fazer uma classe <strong>somente leitura </strong>ou<strong> somente escrita.</strong> Para uma classe somente leitura, temos que informar apenas os métodos <em>getters</em>. Para uma classe somente escrita, devemos informar apenas os métodos <em>setters</em>.</li><li>Controle sobre os dados: podemos controlar os dados adicionando lógica nos métodos <em>setters</em>, assim como fizemos para evitar que o gerenciador de estoques definisse valores negativos nos exemplos acima.</li><li>Proteção dos dados: outras classes não podem acessar membros privados de uma classe diretamente.</li></ol><h2 id="heran-a"><strong>Herança</strong></h2><p>Consideremos que a loja de discos que falamos anteriormente também venda filmes em Blu-ray.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/classDiagramForMovie.png" class="kg-image" alt="classDiagramForMovie" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/classDiagramForMovie.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/classDiagramForMovie.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/classDiagramForMovie.png 1351w" sizes="(min-width: 1200px) 1200px" width="1351" height="291" loading="lazy"><figcaption>Figura 6: diagrama de classes para Movie (filme) e StockKeeper (gerenciador de estoque)</figcaption></figure><p>Como você pode ver no diagrama acima, existem muitos estados e comportamentos em comum (código duplicado) entre <code>Album</code> e <code>Movie</code>.</p><p>Quando for transformar esse diagrama de classes em código, você vai reescrever/copiar todo o código novamente para <code>Movie</code>? Caso você faça isso, você estará se repetindo. Como você pode evitar a duplicação de código?</p><p>Aqui é onde usamos a herança.</p><p><strong>Herança é um mecanismo onde um objeto recebe todos os comportamentos e estados de um objeto pai.</strong></p><p>A herança utiliza um relacionamento de pais e filhos (relacionamento "É um" ).</p><h3 id="ent-o-o-que-exatamente-herdado"><strong>Então o que exatamente é herdado?</strong></h3><p><strong>Visibilidade/modificadores de acesso </strong>impacta o que pode ser herdado de uma classe para a outra.</p><p>Em Java, como <strong>regra fundamental</strong>,<strong> </strong>tornamos as varáveis de instância <code>private</code> e os métodos de instância <code>public</code>.</p><p>Neste caso, certamente podemos dizer que o seguinte será herdado:</p><ol><li>métodos públicos de instância.</li><li>variáveis de instância privadas (que podem ser acessadas apenas por meio de métodos <em>getters </em>e <em>setters </em>públicos) .</li></ol><h3 id="tipos-de-heran-a-no-java"><strong>Tipos de herança no Java</strong></h3><p>Existem cinco tipos diferentes de herança no Java. Elas são: &nbsp;simples, multinível, hierárquica, múltipla e híbrida.</p><p>Classes permitem heranças simples, multinível e hierárquicas. Interfaces permitem heranças múltiplas e híbridas.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/InheritanceTypes.jpg" class="kg-image" alt="InheritanceTypes" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/InheritanceTypes.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/InheritanceTypes.jpg 721w" sizes="(min-width: 720px) 720px" width="721" height="681" loading="lazy"><figcaption>Figura 7: tipos de herança no Java</figcaption></figure><p>Uma classe pode estender apenas uma classe. Entretanto, não há limite para a implementação de interfaces. Uma interface pode estender mais de uma interface.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/inheritanceKeywords.jpg" class="kg-image" alt="inheritanceKeywords" width="481" height="281" loading="lazy"><figcaption>Figura 8: palavras-chaves para herança no Java</figcaption></figure><h3 id="relacionamentos"><strong>Relacionamentos</strong></h3><p><strong><strong>I. </strong>Relacionamento É UM</strong></p><p>Um relacionamento É UM refere-se à herança ou implementação.</p><h4 id="a-generaliza-o"><strong><strong>a. </strong>Generalização</strong></h4><p>Generalização usa um relacionamento É UM de uma classe especializada para uma classe generalizada.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/generalization.jpg" class="kg-image" alt="generalization" width="121" height="221" loading="lazy"><figcaption>Figura 9: diagrama de generalização (recursos especiais para recursos gerais)</figcaption></figure><h4 id="ii-relacionamento-tem-um"><strong><strong>II. </strong>Relacionamento TEM UM</strong></h4><p>Uma instância de uma classe TEM UMA referência para uma instância de outra classe.</p><h4 id="a-agrega-o"><strong><strong>a. </strong>Agregação</strong></h4><p>Neste relacionamento, a existência de uma classe A e B não são dependentes umas das outras.</p><p>Para essa parte de agregação, vamos ver um exemplo da classe <code>Student</code> e da classe <code>ContactInfo</code>.</p><pre><code class="language-java">class ContactInfo {
    private String homeAddress;
    private String emailAddress;
    private int telephoneNumber; //12025550156
}
public class Student {
    private String name;
    private int age;
    private int grade;
    private ContactInfo contactInfo;//Student TEM UM ContactInfo
    public void study() {
        System.out.println("Study");
    }
}</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/aggregation-1.png" class="kg-image" alt="aggregation-1" width="531" height="171" loading="lazy"><figcaption>Figura 10: o diagrama de classes mostra um relacionamento de generalização</figcaption></figure><p><code>Student</code> (aluno) TEM UMA <code>ContactInfo</code> (informação de contato). <code>ContactInfo</code> pode ser usado em outros lugares – por exemplo, uma classe <code>Employee</code> (funcionário) de um companhia também poderia utilizar a classe <code>ContactInfo</code>. Assim, <code>Student</code> pode existir sem <code>ContactInfo</code> e <code>ContactInfo</code> pode existir sem <code>Student</code>. Este tipo de relacionamento é conhecido como agregação.</p><h4 id="b-composi-o"><strong><strong>b. </strong>Composição</strong></h4><p>Neste relacionamento, a classe B não pode existir sem uma classe A – mas a classe A <strong>pode</strong> existir sem a classe B.</p><p>Para dar uma ideia sobre composição, vamos ver esse exemplo da classe <code>Student</code> e a classe <code>StudentId</code>.</p><pre><code class="language-java">class StudentId {
    private String idNumber;//A-123456789
    private String bloodGroup;
    private String accountNumber;
}
public class Student {
    private String name;
    private int age;
    private int grade;
    private StudentId studentId;//Student TEM UM StudentId
    public void study() {
        System.out.println("Study");
    }
}</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/composition--1-.png" class="kg-image" alt="composition--1-" width="531" height="171" loading="lazy"><figcaption>Figura 11: diagrama de classes mostra o relacionamento de composição</figcaption></figure><p><code>Student</code> TEM UM <code>StudentId</code>. <code>Student</code> pode existir sem <code>StudentId</code>, mas <code>StudentId</code> não pode existir sem <code>Student</code>. Esse tipo de relacionamento é conhecido como composição.</p><p>Agora, vamos voltar para nosso exemplo da loja de discos que discutimos acima.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/classDiagramWithInheritance.png" class="kg-image" alt="classDiagramWithInheritance" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/classDiagramWithInheritance.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/classDiagramWithInheritance.png 861w" sizes="(min-width: 720px) 720px" width="861" height="761" loading="lazy"><figcaption>Figura 12: diagrama de classes com herança</figcaption></figure><p>Podemos implementar esse diagrama em Java para evitar duplicação de código.</p><h4 id="vantagens-de-se-usar-heran-a"><strong>Vantagens de se usar herança</strong></h4><ol><li>Reaproveitamento de código: as classes filhas herdam todos os membros de instância da classe pai.</li><li>Você tem mais flexibilidade de mudar o código: mudar o código em um lugar é o suficiente.</li><li>Você pode usar polimorfismo: a sobrescrita de métodos requer um relacionamento É UM.</li></ol><h2 id="abstra-o"><strong>Abstração</strong></h2><p><strong>Abstração é o processo de esconder os detalhes de implementação e exibir apenas as funcionalidades para o usuário<strong>.</strong></strong></p><p>Um exemplo comum de abstração é o acelerador do carro: pisando mais forte, você aumenta a velocidade. Os motoristas, no entanto, não sabem como essa ação altera a velocidade – eles não precisam saber.</p><p>Tecnicamente, abstrato significa algo incompleto ou a ser finalizado no futuro.</p><p>Em Java, podemos obter abstração de duas maneiras: classes abstratas (0% a 100%) e interfaces (100%).</p><p>A palavra-chave <code>abstract</code> pode ser aplicada à classes e métodos. <code>abstract</code> e <code>final</code> ou <code>static</code> nunca podem estar juntas.</p><h4 id="i-classes-abstratas"><strong><strong>I. </strong>Classes abstratas</strong></h4><p>Uma classe é abstrata quando ela contém a palavra reservada <code>abstract</code>.</p><p>Classes abstratas não podem ser instanciadas &nbsp;(não é possível criar objetos de classes abstratas). Elas podem ter construtores, métodos estáticos e métodos finais.</p><h4 id="ii-m-todos-abstratos"><strong><strong>II. </strong>Métodos abstratos</strong></h4><p>Um método é abstrato quando ele contém a palavra chave <code>abstract</code>.</p><p>Um método abstrato não possui implementação (não possui um corpo e termina com ponto e virgula). Métodos abstratos não devem ser marcados como <code>private</code>.</p><h4 id="iii-classes-abstratas-e-m-todos-abstratos"><strong><strong>III. </strong>Classes a<strong>bstra</strong>tas<strong> </strong>e métodos a<strong>bstra</strong>tos</strong></h4><ul><li>Se pelo menos um método for abstrato dentro de uma classe, então toda a classe deve ser abstrata.</li><li>É possível ter uma classe abstrata sem nenhum método abstrato.</li><li>Podemos ter qualquer quantidade de métodos abstratos e não abstratos ao mesmo tempo na mesma classe.</li><li>A primeira classe concreta que herde de uma classe abstrata deve prover implementação para <strong>todos</strong> os métodos abstratos.</li><li>Caso a subclasse não implemente os métodos abstratos da superclasse, ela deve também ser marcada como abstrata.</li></ul><p>Em um cenário real, a implementação vai ser feita por alguém desconhecido ao usuário final. Usuários não conhecem a classe de implementação nem os detalhes da implementação.</p><p>Vamos considerar um exemplo de uso do conceito de classes abstratas.</p><pre><code class="language-java">abstract class Shape {
    public abstract void draw();
}
class Circle extends Shape{
    public void draw() {
        System.out.println("Círculo!");
    }
}
public class Test {
    public static void main(String[] args) {
        Shape circle = new Circle();
        circle.draw();
    }
}</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/abstraction.png" class="kg-image" alt="abstraction" width="211" height="331" loading="lazy"><figcaption>Figura 13: diagrama de classes que mostra o relacionamento entre uma classe abstrata (Shape - ou forma em português) e uma classe concreta (Circle - ou círculo, em português)</figcaption></figure><h4 id="quando-vamos-querer-marcar-uma-classe-como-abstrata"><strong>Quando vamos querer marcar uma classe como abstrata?</strong></h4><ol><li>Para forçar subclasses a implementar métodos abstratos.</li><li>Para impedir que existam objetos daquela classe.</li><li>Para manter a referência à uma classe.</li><li>Para manter código comum.</li></ol><h3 id="interface"><strong><strong>Interface</strong></strong></h3><p><strong>Uma interface é um <em>template</em> (ou uma "planta" de construção) de uma <strong>class</strong>e<strong>.</strong></strong></p><p>Uma interface é 100 abstrata. Construtores não são permitidos aqui. A interface representa o relacionamento "É UM".</p><p><strong>Observação<strong>: </strong></strong>interfaces apenas definem quais os métodos necessários. Não podemos manter código comum.</p><p>Uma interface possui apenas métodos abstratos, não possui métodos concretos. Os métodos da interface são, por padrão, <code>public</code> e <code>abstract</code>. Então, dentro da interface, não precisamos especificar as palavras-chaves <code>public</code> e <code>abstract</code>.</p><p>Então, quando uma classe implementa um método da interface sem especificar os modificadores de acesso daquele método, o compilador vai lançar uma exceção dizendo <code>"Cannot reduce the visibility of the inherited method from interface"</code> (Não é possível reduzir a visibilidade de um método herdado de uma interface). Sendo assim, o modificador de acesso de um método implementado de uma interface deve ser <code>public</code>.</p><p>Por padrão, as variáveis de interface são <code>public</code>, <code>static</code> e <code>final</code>.</p><p>Por exemplo:</p><pre><code class="language-java">interface Runnable {
    int a = 10; //equivale a: public static final int a = 10;
    void run(); //equivale a: public abstract void run();
}
public class InterfaceChecker implements Runnable{
    public static void main(String[] args) {
        Runnable.a = 5;//o valor do campo final Runnable.a não pode ser reatribuido.
    }
}</code></pre><p>Vamos ver um exemplo que explica o conceito de interface:</p><pre><code class="language-java">interface Drawable {
    void draw();
}
class Circle implements Drawable{
    public void draw() {
        System.out.println("Círculo!");
    }
}
public class InterfaceChecker {
    public static void main(String[] args) {
        Drawable circle = new Circle();
        circle.draw();
    }
}</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/interface.png" class="kg-image" alt="interface" width="251" height="371" loading="lazy"><figcaption>Figura 14: diagrama de classes que mostra o relacionamento entre uma interface e uma classe concreta (Drawable - ou desenhável, em português e Circle - ou círculo, em português)</figcaption></figure><h4 id="m-todos-default-e-m-todos-est-ticos-nas-interfaces"><strong>Métodos default e métodos estáticos nas <strong>Interfaces</strong></strong></h4><p>Normalmente, implementamos os métodos de uma interface em classes separadas. Digamos que seja necessário adicionar um novo método à interface. Então, deveremos implementar esse método em todas as outras classes que implementam essa interface também.</p><p>Para evitar esse tipo de problema, a partir do Java, 8 foi introduzida a possibilidade de implementar métodos default e estáticos dentro de uma interface, além dos métodos abstratos.</p><ul><li><strong>Método default</strong></li></ul><pre><code class="language-java">public interface DefaultInterface {
    void sleep();
    default void run() {
        System.out.println("Estou correndo!");
    }
}
public class InterfaceCheckers implements DefaultInterface{
    public void sleep() {
        System.out.println("Dormindo...");
    }
    public static void main(String[] args) {
        InterfaceCheckers checker = new InterfaceCheckers();
        checker.run();
        checker.sleep();
    }
}
/*
Saída:
Estou correndo!
Dormindo...
 */</code></pre><ul><li><strong>Métodos estáticos</strong></li></ul><p>Assim como métodos estáticos de classes, nós podemos chamá-los usando o nome da interface.</p><pre><code class="language-java">public interface DefaultInterface {
    void sleep();
    static void run() {
        System.out.println("Estou correndo!");
    }
}
public class InterfaceCheckers implements DefaultInterface{
    public void sleep() {
        System.out.println("Dormindo...");
    }
    public static void main(String[] args) {
        InterfaceCheckers checker = new InterfaceCheckers();
        DefaultInterface.run();
        checker.sleep();
    }
}
/*
Saída:
Estou correndo!
Dormindo...
 */</code></pre><ul><li><strong>I<strong>nterface</strong> de marcação</strong></li></ul><p>São interfaces vazias. Por exemplo as interfaces <em>Serializable</em>, <em>Cloneable </em>e <em>Remote</em>.</p><pre><code class="language-java">public interface Serializable 
{
  //Sem campos ou métodos
}</code></pre><h3 id="vantagens-das-interfaces"><strong>Vantagens das interfaces</strong></h3><ul><li>Nos ajudam a utilizar herança múltipla no Java.</li><li>Elas fornecem abstração.</li><li>Elas fornecem baixo acoplamento: os objetos são independentes uns dos outros.</li></ul><h3 id="quando-vamos-querer-mudar-de-uma-classe-para-uma-interface"><strong>Quando vamos querer mudar de uma classe para uma interface?</strong></h3><ol><li>Para forçar subclasses a implementar métodos abstratos.</li><li>Para evitar a criação de objetos dessa classe.</li><li>Para manter a referência à uma classe.</li></ol><p><strong>Observação<strong>: </strong></strong>lembre-se de que não podemos manter código comum dentro de uma interface.</p><p>Caso você queira definir métodos que podem ser necessários e código comum, use uma <strong>classe abstrata</strong>.</p><p>Caso queira apenas definir métodos necessários, use uma <strong><strong>interface</strong></strong>.</p><h2 id="polimorfismo"><strong>Polimorfismo</strong></h2><p><strong>Polimorfismo é a habilidade de um objeto de assumir diversas formas<strong>.</strong></strong></p><p>Polimorfismo em POO acontece quando uma superclasse faz referência a um objeto de uma subclasse.</p><p>Todos os objetos do Java são considerados polimórficos já que eles compartilham mais de um relacionamento É UM (pelo menos, todos os objetos vão passar no teste É UM para seu próprio tipo e para a classe <em>Object</em>).</p><p>Podemos acessar um objeto através de uma variável de referência. Uma variável de referência pode ser apenas de um tipo. Após declarada, o tipo da variável de referência não pode ser alterado.</p><p>Uma variável de referência pode ter uma classe ou uma interface como tipo.</p><p>Um único objeto pode ser referenciado por variáveis de referência de diversos tipos (desde que esses tipos estejam na mesma hierarquia), sendo o objeto do mesmo tipo da variável de referência ou de uma superclasse.</p><h3 id="sobrecarga-de-m-todos"><strong>Sobrecarga de métodos</strong></h3><p><strong>Se uma classe possui vários métodos, que possuem o mesmo nome mas parâmetros diferentes, isso é conhecido como sobrecarga de métodos (<em>method overload</em>)<strong>.</strong></strong></p><p>Regras da sobrecarga de métodos:</p><ol><li>Precisa ter uma lista de parâmetros diferente.</li><li>Pode possuir tipos de retorno diferentes.</li><li>Pode possuir modificadores de acesso diferentes.</li><li>Pode lançar exceções diferentes.</li></ol><pre><code class="language-java">class JavaProgrammer{
    public void code() {
        System.out.println("Programando em C++");
    }
    public void code(String language) {
        System.out.println("Programando em " + language);
    }
}
public class MethodOverloader {
    public static void main(String[] args) {
        JavaProgrammer gosling = new JavaProgrammer();
        gosling.code();
        gosling.code("Java");
    }
}
/*
Saída:
Programando em C++
Programando em Java
 */</code></pre><p><strong>Observação<strong>: </strong></strong>métodos estáticos também podem sofrer sobrecarga.</p><pre><code class="language-java">class Addition {
    public static int add(int a,int b) {
        return a+b;
    }
    public static int add(int a,int b,int c) {
        return a+b+c;
    }
}
public class PolyTest {
    public static void main(String[] args) {
        System.out.println(Addition.add(5, 5));
        System.out.println(Addition.add(2, 4, 6));
    }
}</code></pre><p><strong>Observação<strong>: </strong></strong>podemos sobrecarregar o método <em>main</em>(), mas a JVM (<em>Java Virtual Machine</em>) vai chamar o método <em>main</em>() que recebe um <em>array </em>de <em>strings </em>como parâmetro.</p><pre><code class="language-java">public class PolyTest {
    public static void main() {
        System.out.println("main()");
    }
    public static void main(String args) {
        System.out.println("String args");
    }
    public static void main(String[] args) {
        System.out.println("String[] args");
    }
}
//Saída: String[] args</code></pre><h3 id="regras-a-seguir-para-o-polimorfismo"><strong>Regras a seguir para o polimorfismo</strong></h3><h4 id="regras-de-tempo-de-compila-o"><strong>Regras de tempo de compilação</strong></h4><ol><li>O compilador conhece apenas tipos de referência.</li><li>Ele só pode procurar métodos em tipos de referência.</li><li>Gera uma assinatura de método.</li></ol><h4 id="regras-de-tempo-de-execu-o"><strong>Regras de tempo de execução</strong></h4><ol><li>Em tempo de execução, a JVM segue o tipo de tempo de execução exato (<strong>tipo de objeto</strong>) para localizar o método.</li><li>Deve corresponder a assinatura do método de tempo de compilação ao método na classe real do objeto. </li></ol><h3 id="sobrescrita-de-m-todos"><strong>Sobrescrita de métodos</strong></h3><p><strong>Se uma subclasse tem o mesmo método que foi declarado na superclasse, isso é conhecido como sobrescrita de métodos (method <em>override</em>)<strong>.</strong></strong></p><p>Regras da sobrescrita de métodos:</p><ol><li>Deve possuir a mesma lista de parâmetros.</li><li>Deve possuir o mesmo tipo de retorno: embora um retorno covariante nos permita alterar o tipo de retorno do método sobrescrito.</li><li>Não pode possuir um modificador de acesso mais restritivo: deve possuir um modificador de acesso menos restritivo.</li><li>Não deve lançar uma exceção verificada (<em>checked exception</em>) nova ou mais ampla: pode lançar exceções verificadas mais restritas e pode lançar qualquer exceção não verificada.</li><li>Apenas métodos herdados podem ser sobrescritos (é necessário um relacionamento É UM).</li></ol><p>Exemplo de sobrescrita de método:</p><pre><code class="language-java">public class Programmer {
    public void code() {
        System.out.println("Programando em C++");
    }
}
public class JavaProgrammer extends Programmer{
    public void code() {
        System.out.println("Programando em Java");
    }
}
public class MethodOverridder {
    public static void main(String[] args) {
        Programmer ben = new JavaProgrammer();
        ben.code();
    }
}
/*
Saída:
Programando em Java
 */</code></pre><p><strong>Observação<strong>: </strong></strong>métodos estáticos não podem ser sobrescritos porque métodos são sobrescritos em tempo de execução (<em>runtime</em>). Métodos estáticos são associados com classes, enquanto métodos de instância são associados com objetos. Então, em Java, o método <code>main()</code> não pode ser sobrescrito.</p><p><strong>Observação<strong>:</strong></strong> construtores podem ser sobrecarregados mas não podem ser sobrescritos.</p><h3 id="tipos-de-objeto-e-tipos-de-refer-ncia"><strong>Tipos de objeto e tipos de referência</strong></h3><pre><code class="language-java">class Person{
    void eat() {
        System.out.println("A pessoa está comendo");
    }
}
class Student extends Person{
    void study() {
        System.out.println("O estudante está estudando");
    }
}
public class InheritanceChecker {
    public static void main(String[] args) {
        Person alex = new Person();//New Person "É UMA" Person
        alex.eat();
        Student jane = new Student();//New Student "É UM" Student
        jane.eat();
        jane.study();
        Person mary = new Student();//New Student "É UM" Person
        mary.eat();
        //Student chris = new Person(); //New Person não É UM Student.
    }
}</code></pre><p>Em <code>Person mary = new Student();</code> esse modo de criar o objeto está correto.</p><p><code>mary</code> é uma variável de referência do tipo <code>Person</code> e <code>new Student()</code> criará um novo objeto do tipo <code>Student</code>.</p><p><code>mary</code> não pode acessar <code>study()</code> em tempo de compilação porque o compilador conhece apenas o tipo de referência. Já que <code>study()</code> não existe na classe do tipo de referência, não é possível acessá-lo. Em tempo de execução, no entanto, <code>mary</code> será do tipo <code>Student</code> (tipo de tempo de execução/tipo de objeto).</p><p>Veja esse <a href="https://coderanch.com/t/394210/java/compile-time-runtime-type" rel="noopener">artigo</a> (texto em inglês) para entender melhor sobre tipos de tempo de execução.</p><p>Neste caso, podemos convencer o compilador dizendo "em tempo de execução, <code>mary</code> será do tipo <code>Student</code>, então permita-me chamar o método study()". Como podemos convencer o compilador a fazer isso? Aqui é onde usaremos o <em>casting</em>.</p><p>Podemos converter <code>mary</code> ao tipo <code>Student</code> em tempo de compilação e chamar <code>study()</code> se utilizarmos o <em>casting</em>.</p><pre><code class="language-java">((Student)mary).study();</code></pre><p>Aprenderemos sobre <em>casting </em>a seguir.</p><h3 id="casting-de-tipos-de-objeto"><strong><em>C<strong>asting</strong> </em>de tipos de objeto</strong></h3><p>O <em>casting </em>no Java é classificado em dois tipos:</p><ol><li><em>Casting </em>de ampliação (<em>widening casting</em>, implícito): conversão automática de tipos.</li><li><em>Casting </em>de restrição (<em>narrowing casting</em>, explícito): precisa de uma conversão explícita.</li></ol><p>Com primitivos, <code>long</code> é um tipo mais abrangente que <code>int</code>. Assim como ocorre com os objetos, a classe mãe é mais abrangente que a classe filha.</p><p>A variável de referência apenas faz referência a um objeto. Utilizar <em>casting </em>em uma variável de referência não muda o tipo do objeto em memória, mas rotula o mesmo objeto de uma outra maneira para se ter acesso aos membros de instância.</p><p><strong><strong>I. Widening casting</strong> (<em>casting </em>de ampliação)</strong></p><pre><code class="language-java">Superclass superRef = new Subclass();</code></pre><p><strong><strong>II. Narrowing casting</strong> (<em>casting </em>de restrição)</strong></p><pre><code class="language-java">Subclass ref = (Subclass) superRef;</code></pre><p>Temos que tomar cuidado quando utilizamos um <em>casting </em>restritivo. Quando utilizamos o <em>casting </em>restritivo, convencemos o compilador a compilar sem erros. Caso estejamos errados, receberemos um erro em tempo de execução (geralmente, <code>ClassCastException</code>).</p><p>Para executar um <em>casting </em>restritivo corretamente, usamos o operador <code>instanceof</code>. Com ele, podemos verificar se o relacionamento é do tipo É UM.</p><pre><code class="language-java">class A {
    public void display(){
        System.out.println("Class A");
    }
}

class B extends A{
    public void display(){
        System.out.println("Class B");
    }
}

public class Test {
    public static void main(String[] args) {
        A objA = new B();
        if(objA instanceof B){
            ((B)objA).display();
        }
    }
}
/**
 * Saída: Class B
 */
</code></pre><p>Como eu disse anteriormente, devemos sempre nos lembrar de uma coisa muito importante quando criamos um objeto utilizando a palavra-chave <code>new</code>: o tipo de referência deve ser <strong>do mesmo tipo </strong>ou de um <strong>supertipo</strong> do objeto sendo criado.</p><h2 id="conclus-o"><strong>Conclusão</strong></h2><p>Obrigado por ler este artigo. Espero que ele tenha ajudado.</p><p>Recomendo fortemente a leitura de mais artigos relacionados à POO.</p><p>Confira, também, a série original de artigos do autor no medium: <a href="https://medium.com/@mvthanoshan9/object-oriented-programming-principles-in-java-820919dced1a">Princípios de orientação a objetos em Java</a> (texto em inglês).</p><blockquote>Sonhos não são o que você vê quando está dormindo. Eles são o que não deixa você dormir.<br>― <strong><strong>A P J Abdul Kalam, </strong>Asas de fogo<strong>: </strong>autobiografia</strong></blockquote><p>Obrigado.</p><p><strong>Bons estudos<strong><strong><strong><strong><strong><strong><strong>!</strong></strong></strong></strong></strong></strong></strong></strong></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como eu passei na prova AZ-900 do Microsoft Azure Fundamentals ]]>
                </title>
                <description>
                    <![CDATA[ Você provavelmente já ouviu falar da Amazon Web Services e do desafio #AWSCertified. Mas você sabia que a Microsoft também é uma cloud provider? Após passar em 3 certificações da AWS [https://www.freecodecamp.org/news/how-i-passed-the-aws-certified-developer-associate-exam/] , eu queria aprender novas coisas e começar com um novo cloud provider: o Azure. Meus objetivos eram ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-eu-passei-na-prova-az-900-do-microsoft-azure-fundamentals/</link>
                <guid isPermaLink="false">62afec4187787706fc0fea8c</guid>
                
                    <category>
                        <![CDATA[ Azure ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Cássio Leodegario ]]>
                </dc:creator>
                <pubDate>Tue, 05 Jul 2022 17:04:43 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/07/5f9c9acc740569d1a4ca27cd.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/how-i-passed-the-az-900-microsoft-azure-fundamentals-exam/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How I Passed the AZ-900 Microsoft Azure Fundamentals Exam</a>
      </p><p>Você provavelmente já ouviu falar da Amazon Web Services e do desafio #AWSCertified. Mas você sabia que a Microsoft também é uma <em>cloud provider</em>?</p><p>Após passar em <a href="https://www.freecodecamp.org/news/how-i-passed-the-aws-certified-developer-associate-exam/">3 certificações da AWS</a>, eu queria aprender novas coisas e começar com um novo <em>cloud provider</em>: o Azure.</p><p>Meus objetivos eram compreender como o Azure funciona e também obter uma nova certificação. Eu resolvi fazer a primeira prova, AZ-900: Microsoft Azure Fundamentals, para ter uma transição tranquila da AWS para o Azure.</p><p>Neste artigo, eu vou explicar as certificações Azure e também como obter uma certificação Microsoft.</p><p>Vamos começar.</p><h2 id="o-que-azure"><strong>O que é Azure<strong>?</strong></strong></h2><p>Antes de explicar as certificações Microsoft, farei uma breve introdução ao Azure.</p><p>Azure é a plataforma de computação em nuvem da Microsoft. Com ela, você tem a liberdade de construir, gerenciar e publicar aplicações em uma gigantesca rede mundial usando suas ferramentas e frameworks preferidos.</p><p>As capacidades do Azure podem ser divididas em 8 principais categorias:</p><ol><li><em>Compute Services</em> (Serviços de computação)</li><li><em>Cloud Storage</em> (Armazenamento em nuvem) </li><li><em>Networking </em>(Redes)</li><li><em>App Hosting</em> (Hospedagem de aplicativos)</li><li><em>Artificial Intelligence</em> (Inteligência artificial)</li><li><em>Internet of Things</em> (Internet das coisas)</li><li><em>Integration</em> (Integrações)</li><li><em>Security</em> (Segurança)</li></ol><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/07/image-121.png" class="kg-image" alt="image-121" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/07/image-121.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/07/image-121.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/07/image-121.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/07/image-121.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="1125" loading="lazy"><figcaption>Visão geral dos serviços e funcionalidades disponíveis no Azure</figcaption></figure><h2 id="certifica-es-microsoft"><strong>Certificações <strong>Microsoft</strong></strong></h2><p>A Microsoft oferece certificações em diversos produtos: Azure, Dynamics 365, Microsoft 365, Office, Power Platform, SQL Server e Windows.</p><p>Se considerarmos apenas o Azure, nós temos 13 certificações diferentes, agrupadas em duas categorias:</p><ul><li>Aplicativos e Infraestrutura</li><li>Dados e Inteligência Artificial</li></ul><p>Referentes aos seguintes cargos técnicos:</p><ul><li>Administração</li><li>Engenharia de IA</li><li>Engenharia de Dados</li><li>Ciência de Dados</li><li>Administração de Base de Dados</li><li>Desenvolvimento</li><li>Engenharia DevOps </li><li>Engenharia de Segurança</li><li>Arquitetura de soluções</li></ul><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/07/certs.png" class="kg-image" alt="certs" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/07/certs.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/07/certs.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/07/certs.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/07/certs.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="948" loading="lazy"><figcaption>Certificações Microsoft Azure</figcaption></figure><h3 id="trilha-de-certifica-o-developer"><strong>Trilha de Certificação <em>d<strong>eveloper</strong></em></strong></h3><p>Para cada certificação, você pode encontrar a trilha associada na <a href="https://docs.microsoft.com/en-us/learn/certifications/">documentação</a>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/07/Capture-d-e-cran-2020-05-16-a--14.41.05.png" class="kg-image" alt="Capture-d-e-cran-2020-05-16-a--14.41.05" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/07/Capture-d-e-cran-2020-05-16-a--14.41.05.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/07/Capture-d-e-cran-2020-05-16-a--14.41.05.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/07/Capture-d-e-cran-2020-05-16-a--14.41.05.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/07/Capture-d-e-cran-2020-05-16-a--14.41.05.png 1768w" sizes="(min-width: 720px) 720px" width="1768" height="464" loading="lazy"></figure><p>A trilha de certificação <em>developer </em>requer dois exames:</p><ol><li>Exame AZ-900: Microsoft Azure Fundamentals (opcional)</li><li>Exame AZ-204: Developing Solutions for Microsoft Azure</li></ol><h3 id="trilha-de-certifica-o-solutions-architect"><strong>Trilha de certificação <strong><em>Solutions Architect</em></strong></strong></h3><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/07/Capture-d-e-cran-2020-05-16-a--14.47.49.png" class="kg-image" alt="Capture-d-e-cran-2020-05-16-a--14.47.49" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/07/Capture-d-e-cran-2020-05-16-a--14.47.49.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/07/Capture-d-e-cran-2020-05-16-a--14.47.49.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/07/Capture-d-e-cran-2020-05-16-a--14.47.49.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/07/Capture-d-e-cran-2020-05-16-a--14.47.49.png 1770w" sizes="(min-width: 720px) 720px" width="1770" height="460" loading="lazy"></figure><p>A trilha de certificação <em>Solutions Architect</em> requer três exames:</p><ul><li>Exame AZ-900: Microsoft Azure Fundamentals (opcional)</li><li>Exame AZ-300: Microsoft Azure Architect Technologies</li><li>Exame AZ-301: Microsoft Azure Architect Design</li></ul><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/07/Capture-d-e-cran-2020-05-16-a--14.26.16-1.png" class="kg-image" alt="Capture-d-e-cran-2020-05-16-a--14.26.16-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/07/Capture-d-e-cran-2020-05-16-a--14.26.16-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/07/Capture-d-e-cran-2020-05-16-a--14.26.16-1.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/07/Capture-d-e-cran-2020-05-16-a--14.26.16-1.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/07/Capture-d-e-cran-2020-05-16-a--14.26.16-1.png 1888w" sizes="(min-width: 720px) 720px" width="1888" height="1280" loading="lazy"></figure><p>Caso você esteja familiarizado com os exames da AWS, você provavelmente notou que, no Azure, não há o nível associado para o papel de arquiteto de soluções. Na tabela abaixo, eu mostro quais seriam os exames equivalentes entre a AWS e o Azure:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/07/Capture-d-e-cran-2020-05-16-a--14.31.12.png" class="kg-image" alt="Capture-d-e-cran-2020-05-16-a--14.31.12" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/07/Capture-d-e-cran-2020-05-16-a--14.31.12.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/07/Capture-d-e-cran-2020-05-16-a--14.31.12.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/07/Capture-d-e-cran-2020-05-16-a--14.31.12.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/07/Capture-d-e-cran-2020-05-16-a--14.31.12.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="748" loading="lazy"><figcaption>Comparação entre os exames da AWS e do Azure</figcaption></figure><h2 id="foco-na-az-900-microsoft-azure-fundamentals"><strong>Foco na <strong>AZ-900: Microsoft Azure Fundamentals</strong></strong></h2><p>A Microsoft diz que o objetivo deste exame é demonstrar um nível de conhecimento básico sobre serviços em nuvem e sobre como o Azure disponibiliza esses serviços.</p><p>Não é necessário ter experiência em TI pra fazer o exame. Tanto pessoas com experiência técnica, quanto pessoas sem experiência técnica podem fazer esse exame.</p><h2 id="quais-habilidades-s-o-avaliadas-durante-o-exame"><strong>Quais habilidades são avaliadas durante o exame?</strong></h2><p>De acordo com a ementa da prova, as habilidades que serão testadas são as seguintes:</p><h3 id="descrever-os-conceitos-de-nuvem-15-20-"><strong>Descrever os conceitos de nuvem <strong>(15-20%)</strong></strong></h3><ul><li>Descreva os benefícios e considerações de se utilizar serviços de nuvem</li><li>Descreva as diferenças entre <em>Infrastructure-as-a-Service</em> (IaaS), <em>Platform-as-a-Service</em> (PaaS) e <em>Software-as-a-Service</em> (SaaS)</li><li>Descreva a diferença entre os modelos de nuvem Pública, Privada e Híbrida</li></ul><h3 id="descrever-os-principais-servi-os-do-azure-30-35-"><strong>Descrever os principais serviços do Azure <strong>(30-35%)</strong></strong></h3><ul><li>Descreva os principais componentes arquiteturais do Azure</li><li>Descreva alguns dos principais produtos disponibilizados pelo Azure</li><li>Descreva algumas soluções disponibilizadas pelo Azure</li><li>Descreva as ferramentas de gestão do Azure</li></ul><h3 id="descrever-seguran-a-privacidade-conformidade-e-confian-a-25-30-"><strong>Descrever segurança, privacidade, conformidade e confiança<strong> (25-30%)</strong></strong></h3><ul><li>Descreva a proteção de conectividade de rede no Azure</li><li>Descreva os principais serviços de Identidade do Azure</li><li>Descreva as ferramentas e funcionalidade de segurança do Azure</li><li>Descreva as metodologias de governança do Azure</li><li>Descreva as opções de relatórios e monitoramento do Azure</li><li>Descreva privacidade, conformidade e padrões de proteção de dados do Azure</li></ul><h3 id="descreva-os-pre-os-contratos-de-n-vel-de-servi-o-e-os-ciclos-de-vida-do-azure-20-25-"><strong>Descreva os preços, contratos de nível de serviço e os ciclos de vida<strong> </strong>do Azure <strong>(20-25%)</strong></strong></h3><ul><li>Descreva as assinaturas do Azure</li><li>Descreva o planejamento e gerenciamento de custos</li><li>Descreva os contratos de nível de serviço - <em>Service Level Agreements</em> (SLAs)</li><li>Compreenda o ciclo de vida dos serviços no Azure</li></ul><h2 id="quanto-custa-o-exame"><strong>Quanto custa o exame<strong>?</strong></strong></h2><p>Caso você tenha dado sorte de participar de algum <em>Microsoft Azure Virtual Training Day: Fundamentals</em>, você provavelmente ganhou um voucher que permite realizar a prova gratuitamente.</p><p>Caso contrário, atualmente, a prova custa US$ 60,00* (60 dólares americanos), e você pode agendar o <a href="https://docs.microsoft.com/pt-br/learn/certifications/exams/az-900">exame utilizando a Pearson VUE</a>. <br>* O preço é baseado no país ou na região em que o exame é realizado.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/07/Capture-d-e-cran-2020-05-16-a--18.02.49.png" class="kg-image" alt="Capture-d-e-cran-2020-05-16-a--18.02.49" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/07/Capture-d-e-cran-2020-05-16-a--18.02.49.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/07/Capture-d-e-cran-2020-05-16-a--18.02.49.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/07/Capture-d-e-cran-2020-05-16-a--18.02.49.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/07/Capture-d-e-cran-2020-05-16-a--18.02.49.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="961" loading="lazy"></figure><h3 id="como-o-exame"><strong>Como é o exame?</strong></h3><p>De acordo com o <a href="https://www.microsoft.com/en-us/learning/certification-exam-policies.aspx">FAQ</a>, você terá 60 minutos para responder entre 40 e 60 questões. Eu, no entanto, tive apenas 32 questões no meu exame. Foi uma bela surpresa!</p><p>O exame contém diversos <a href="https://docs.microsoft.com/pt-br/learn/certifications/certification-process-overview">tipos de questões</a>:</p><ul><li>Diversas formas de múltipla escolha: uma resposta correta e três erradas, selecione a descrição correta, duas ou mais respostas corretas dentre cinco ou mais opções</li><li>Arraste e solte: selecione a resposta e arraste para a descrição correta</li><li>Área quente: responda as perguntas de uma maneira gráfica (capturas de tela, imagens ou diagramas)</li></ul><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/07/image-118.png" class="kg-image" alt="image-118" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/07/image-118.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/07/image-118.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/07/image-118.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/07/image-118.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="909" loading="lazy"></figure><h2 id="como-se-preparar-para-a-prova"><strong>Como se preparar para a prova?</strong></h2><p>Existem diversos recursos para ajudar você durante a preparação para a prova. A Microsoft recomenda utilizar sua plataforma on-line, o Microsoft Learn, onde são disponibilizadas diversas trilhas de aprendizados e módulos que você pode ler no seu ritmo gratuitamente.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/07/Capture-d-e-cran-2020-05-17-a--10.45.43-1.png" class="kg-image" alt="Capture-d-e-cran-2020-05-17-a--10.45.43-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/07/Capture-d-e-cran-2020-05-17-a--10.45.43-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/07/Capture-d-e-cran-2020-05-17-a--10.45.43-1.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/07/Capture-d-e-cran-2020-05-17-a--10.45.43-1.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/07/Capture-d-e-cran-2020-05-17-a--10.45.43-1.png 1840w" sizes="(min-width: 720px) 720px" width="1840" height="1170" loading="lazy"></figure><p>A trilha de aprendizado <a href="https://docs.microsoft.com/en-us/learn/paths/azure-fundamentals/">Azure fundamentals</a> é o curso recomendado para se preparar para o exame AZ-900. É um curso de 10 horas que contém 12 módulos:</p><ol><li>Conceitos de Nuvem - Princípios de computação em nuvem</li><li>Criando uma conta no Azure</li><li>Principais Serviços de Nuvem - Introdução ao Azure</li><li>Principais Serviços de Nuvem - Arquitetura do Azure e garantias de serviço</li><li>Principais Serviços de Nuvem - Gerencie serviços com o portal do Azure</li><li>Principais Serviços de Nuvem - Opções de computação no Azure</li><li>Principais Serviços de Nuvem - Opções de armazenamento de dados no Azure </li><li>Principais Serviços de Nuvem - Opções de rede no Azure</li><li>Segurança, responsabilidade e confiabilidade no Azure</li><li>Aplique e monitore padrões de infraestrutura com as políticas do Azure</li><li>Controle e organize os serviços do Azure com o Azure Resource Manager</li><li>Preveja custos e otimize seus gastos com o Azure</li></ol><p>Se você costuma assistir os cursos de Andrew Brown, vai se desapontar com o Microsoft Learn. Os módulos são texto puro sem nenhum vídeo. Esteja pronto para ler e fazer anotações!</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/07/Capture-d-e-cran-2020-05-17-a--11.10.45.png" class="kg-image" alt="Capture-d-e-cran-2020-05-17-a--11.10.45" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/07/Capture-d-e-cran-2020-05-17-a--11.10.45.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/07/Capture-d-e-cran-2020-05-17-a--11.10.45.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/07/Capture-d-e-cran-2020-05-17-a--11.10.45.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/07/Capture-d-e-cran-2020-05-17-a--11.10.45.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="1064" loading="lazy"></figure><p>Eu recomendo fortemente que você:</p><ol><li>Crie uma <a href="https://azure.microsoft.com/en-us/">conta gratuita</a></li><li>Leia a visão geral dos serviços Azure</li><li>Pratique por conta própria no Azure <em>quickstarts</em></li><li>Monitore seu progresso com o <em>skills outline</em></li><li>Faça exames práticos</li></ol><p>A Microsoft explica o que você precisa saber para cada serviço em sua documentação. As explicações incluem, entre outras coisas, uma visão geral do serviço e <em>quickstarts </em>onde você pode experimentar para ter uma melhor visão do serviço.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/07/Capture-d-e-cran-2020-05-17-a--11.57.13.png" class="kg-image" alt="Capture-d-e-cran-2020-05-17-a--11.57.13" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/07/Capture-d-e-cran-2020-05-17-a--11.57.13.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/07/Capture-d-e-cran-2020-05-17-a--11.57.13.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/07/Capture-d-e-cran-2020-05-17-a--11.57.13.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/07/Capture-d-e-cran-2020-05-17-a--11.57.13.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="911" loading="lazy"></figure><p>Observação: utilizar o portal do Azure é o suficiente para praticar, já que esse não é um exame muito aprofundado.</p><p>Todos esses passos são suficientes para me fazer passar na AZ-900?</p><figure class="kg-card kg-embed-card"><blockquote class="twitter-tweet" data-width="550"><p lang="en" dir="ltr">Officially Microsoft Certified!!! I took my Microsoft <a href="https://twitter.com/Azure?ref_src=twsrc%5Etfw">@Azure</a> Fundamentals exam this morning, and I passed!!! 🎉<br><br>Of course, I will share my feedback in a <a href="https://twitter.com/freeCodeCamp?ref_src=twsrc%5Etfw">@freecodecamp</a> article ✍️<a href="https://twitter.com/hashtag/AzureCertified?src=hash&amp;ref_src=twsrc%5Etfw">#AzureCertified</a> <a href="https://twitter.com/hashtag/Azure?src=hash&amp;ref_src=twsrc%5Etfw">#Azure</a> <a href="https://t.co/rvhJbz8av6">pic.twitter.com/rvhJbz8av6</a></p>— Johan Rin (@johanrin) <a href="https://twitter.com/johanrin/status/1265221875183038464?ref_src=twsrc%5Etfw">May 26, 2020</a></blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</figure><p>Esse exame não é difícil de passar! É preciso tempo e prática para se preparar, mas nada é impossível. O ponto chave é encontrar uma boa rotina de aprendizado e progredir passo a passo.</p><h2 id="diferen-as-do-exame-aws-certified-cloud-practitioner"><strong>Diferenças do exame <strong>AWS Certified Cloud Practitioner</strong></strong></h2><p>Você não deve subestimar o quanto de preparação é necessário só porque você já passou no exame AWS Certified Cloud Practitioner.</p><p>Você deve começar do começo porque 80% do exame valida o ecossistema do Azure, que é bem diferente daquele do AWS.</p><p>Não quero que você cometa os mesmos erros que eu cometi. Não compare cada novo serviço que você aprende com os da AWS. Isso vai deixar você mais confuso do que ajudar. Alguns serviços do Azure não possuem um equivalente na AWS e vice-versa.</p><p>Esqueça a AWS (enquanto estiver estudando) para aprender o Azure!</p><p>Alguma dúvida? Fique à vontade para conversar com o autor no <a href="https://twitter.com/johanrin" rel="noopener nofollow">Twitter</a> ou diretamente no canal do Discord do freeCodeCamp. Ele ajudará você da melhor maneira possível.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como habilitar o live-reload em aplicações do Docker utilizando volumes ]]>
                </title>
                <description>
                    <![CDATA[ Neste artigo, você vai aprender como configurar um ambiente de desenvolvimento com o live-reload habilitado. Com isso, você poderá fazer com que aplicações legadas usem Docker, volumes do Docker e o docker-compose. Alguns desenvolvedores torcem o nariz quando o assunto é utilizar o Docker em seus ambientes de desenvolvimento. Eles ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-habilitar-o-live-reload-em-aplicacoes-do-docker-utilizando-volumes/</link>
                <guid isPermaLink="false">62ac9a40253a6406db9bb7ec</guid>
                
                    <category>
                        <![CDATA[ Docker ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Cássio Leodegario ]]>
                </dc:creator>
                <pubDate>Tue, 21 Jun 2022 14:30:48 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/06/5f9c9a0f740569d1a4ca233c.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-enable-live-reload-on-docker-based-applications/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Enable Live-reload on Docker-based Applications with Docker Volumes</a>
      </p><p>Neste artigo, você vai aprender como configurar um ambiente de desenvolvimento com o <em>live-reload</em> habilitado. Com isso, você poderá fazer com que aplicações legadas usem Docker, volumes do Docker e o docker-compose.</p><p>Alguns desenvolvedores torcem o nariz quando o assunto é utilizar o Docker em seus ambientes de desenvolvimento. Eles dizem que o Docker não é bom para desenvolvimento, pois é preciso reconstruir a imagem toda hora para refletir as novas alterações. Isso torna o trabalho improdutivo e lento.</p><p>Neste artigo, nosso objetivo é combater esse pensamento, demonstrando como algumas configurações simples podem trazer muitos benefícios, como a possibilidade de ter um ambiente confiável, tanto em produção, como em desenvolvimento.</p><p>Ao final deste artigo, você terá aprendido a:</p><ul><li>Configurar aplicações legadas para rodar em contêineres do Docker;</li><li>Habilitar o cache de dependências em módulos do <em>Node.js</em>;</li><li>Habilitar o <em>live-reload</em> utilizando volumes do Docker;</li><li>Agregar todos os serviços utilizando o docker-compose.</li></ul><h2 id="requisitos"><strong>Requisitos</strong></h2><p>Nos próximos passos, você vai clonar um projeto existente para executar todos os exemplos deste artigo. Antes de começar a escrever código, certifique-se de que você possui as seguintes ferramentas instaladas no seu computador:</p><ul><li><a href="https://docs.docker.com/desktop/">Docker</a> e <a href="https://docs.docker.com/compose/">Docker compose</a></li><li><a href="https://nodejs.org/en/download/current/">Node.js 1</a>0+</li><li><a href="https://code.visualstudio.com/download">Git</a></li></ul><h2 id="por-que-usar-o-docker"><strong>Por que usar o Docker<strong><strong><strong>?</strong></strong></strong></strong></h2><p>A todo momento, vemos na internet o surgimento de novas tecnologias de ponta. Elas são estáveis, e é divertido trabalhar com coisas novas, mas elas não são tão previsíveis quando estamos trabalhando nos mais diversos ambientes. Então, um grupo de desenvolvedores criou o Docker para reduzir as chances de possíveis erros nestes cenários de mudança de ambiente.</p><p>O Docker é uma das minhas ferramentas favoritas e eu o utilizo para trabalhar com aplicações desktop, web ou IoT. Agora, eu tenho o poder de mover minhas aplicações para os mais diversos ambientes, podendo também manter meu ambiente local sempre limpo.</p><p>Desenvolvedores que trabalham com tecnologias de ponta estão sempre mexendo com algo novo. Mas, e quanto às aplicações legadas? Deveríamos simplesmente reescrever tudo com uma nova tecnologia? Eu sei que isso não é tão simples quanto parece. Nós devemos trabalhar com coisas novas, mas também devemos sempre manter e aprimorar as aplicações existentes.</p><p>Vamos dizer que você decidiu trocar de servidores baseados em Windows para servidores baseados em Unix. Como isso deveria ser feito? Você sabe todas as dependências que seu aplicativo precisa para funcionar?</p><h2 id="como-um-ambiente-de-desenvolvimento-deveria-ser"><strong>Como um ambiente de desenvolvimento deveria ser?</strong></h2><p>Desenvolvedores estão sempre tentando ser mais produtivos. Para isso, muitas vezes, tentamos adicionar <em>plugins, boilerplates</em> e bases de códigos prontas em nossas IDEs/editores/terminais. Na minha opinião, porém, o ambiente de desenvolvimento ideal deveria ser:</p><ol><li>Fácil de executar e testar;</li><li>Agnóstico ao ambiente;</li><li>Rápido de avaliar/testar modificações;</li><li>Fácil de replicar em qualquer computador.</li></ol><p>Nas próximas seções deste artigo, nós configuraremos uma aplicação que tem como base os princípios citados acima. Caso você ainda não tenha ouvido falar de <em>live-reload</em> (ou <em>hot reload</em>), sua tradução literal seria "atualização em tempo real", que nada mais é do que uma funcionalidade que fica observando as modificações que são feitas no código e reinicia a aplicação automaticamente. Com isso, você não precisa ficar toda hora fazendo o <em>build </em>e reiniciando sua aplicação.</p><h2 id="come-ando"><strong>Começando</strong></h2><p>Primeiro, você vai precisar de uma pasta vazia chamada <code>post-docker-livereload</code>, que será nosso local de trabalho. Acesse este <a href="https://github.com/ErickWendel/nodejs-with-mongodb-api-example">repositório do Github</a> e faça um clone dentro dele na pasta post-docker-live-reload.</p><p>Após clonar o repositório no seu ambiente local, vamos analisar quais os requerimentos da aplicação. Dando uma rápida olhada no arquivo README.md, podemos ver algumas instruções de como executar a aplicação, como mostra a imagem abaixo:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/06/Screen-Shot-2020-06-24-at-18.10.43-1.png" class="kg-image" alt="Screen-Shot-2020-06-24-at-18.10.43-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/06/Screen-Shot-2020-06-24-at-18.10.43-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/06/Screen-Shot-2020-06-24-at-18.10.43-1.png 889w" sizes="(min-width: 720px) 720px" width="889" height="530" loading="lazy"></figure><p>É necessário ter o Node.js na versão 10 ou superior e o MongoDB. Ao invés de fazermos uma instalação do MongoDB no seu ambiente local, vamos instalá-lo utilizando o Docker. Você vai expor o MongoDB em localhost:27017. Assim, mesmo aplicações executadas fora do Docker poderão acessá-lo sem a necessidade de conhecer o IP interno que é utilizado no Docker.</p><p>Copie o comando abaixo e cole no seu terminal:</p><pre><code class="language-bash">docker run --name mongodb -p 27017:27017 -d mongo:4</code></pre><p>Com o comando acima, você baixará e executará uma instância do MongoDB. Observe que, caso você já tenha uma instância com o mesmo nome, o comando lançará um erro de nome inválido.</p><p>Caso ocorra o erro, você pode remover a instalação anterior rodando o comando <code>docker rm mongodb</code>. Com isso, você removerá qualquer instância anterior e poderá rodar o comando <code>docker run</code> novamente.</p><h2 id="explorando-a-aplica-o"><strong>Explorando a aplicação</strong></h2><p>O arquivo README.md diz que, antes de rodar sua aplicação, você precisará de uma instância do MongoDB, juntamente com o Node.js.</p><p>Se você já tiver instalado o Node.js, vá para a pasta <code>nodejs-with-mongodb-api-example</code> e execute os seguintes comandos:</p><pre><code class="language-bash">npm i 
npm run build 
npm start</code></pre><p>Após executar esses comandos, vá até o navegador e acesse <a href="http://localhost:3000/">http://localhost:3000</a>. Assim, você poderá visualizar a aplicação sendo executada, como mostra a imagem abaixo:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/06/01-start.gif" class="kg-image" alt="01-start" width="1920" height="1080" loading="lazy"></figure><p>Tenha em mente que a aplicação já possui um comando para habilitar o <em>live-reload</em> que é o <code>npm run dev:watch</code>. O fluxo deve seguir os seguintes passos:</p><ol><li>O desenvolvedor muda um arquivo Typescript;</li><li>Os arquivos Typescript são transpilados (convertidos) para JavaScript;</li><li>O servidor identifica as modificações nos arquivos JavaScript e reinicia o servidor Node.js.</li></ol><p>Então, fazendo um espelhamento dos arquivos para os contêineres Docker, essas alterações serão refletidas para o contêiner também. O comando <code>npm run build:watch</code> vai capturar as alterações e gerar novos arquivos na pasta <em>lib. </em>Então, todas as vezes que o comando <code>npm run dev:run</code> for disparado, o servidor será reiniciado.</p><h2 id="dockerizando-a-aplica-o"><strong>Dockerizando a aplicação</strong></h2><p>Caso o Docker seja um mundo completamente novo para você, não tenha medo! Você fará essa configuração do zero. Você vai precisar criar apenas alguns arquivos para começar:</p><ol><li><code>Dockerfile</code> - é como uma receita onde será descrito como instalar sua aplicação;</li><li><code>.dockerignore</code> - um arquivo onde listamos quais arquivos não irão para a instância do contêiner.</li></ol><h3 id="criando-o-dockerfile"><strong>Criando o Dockerfile</strong></h3><p>Dockerfile é o conceito chave aqui. Nele, você especifica os passos e dependências para preparar e executar a aplicação. Desde que você tenha lido o arquivo README.md, será muito fácil de implementar o arquivo de "receita".</p><p>Vou colocar todo arquivo aqui e, mais para a frente, vamos explorá-lo mais a fundo. Na sua pasta <code>nodejs-with-mongodb-api-example</code>, crie um arquivo com o nome <code>Dockerfile</code><em><em> </em></em>e cole o código abaixo.</p><pre><code class="language-dockerfile">FROM node:14-alpine

WORKDIR /src

ADD package.json /src 

RUN npm i --silent

ADD . /src 

RUN npm run build 

CMD npm start</code></pre><p>O que estamos fazendo no Dockerfile?</p><ul><li>Na primeira linha - utilizamos uma imagem base do Node.js 14 - versão alpine; </li><li>Da linha 2 até a linha 4 - é feita a cópia e instalação das dependências do Node.js do host para o contêiner. Note que a ordem aqui é importante. Adicionar o package.json para a pasta src antes de restaurar as dependências vai criar um <em>cache </em>e evitar que toda a vez que você fizer o <em>build </em>da imagem os pacotes sejam baixados novamente;</li><li>Da linha 6 até a linha 7 - é feita a compilação e logo após a execução do programa como mencionado no arquivo README.md;</li></ul><h3 id="ignorando-arquivos-desnecess-rios-com-o-dockerignore"><strong>Ignorando arquivos desnecessários com o <strong>.dockerignore</strong></strong></h3><p>Atualmente, eu estou trabalhando com um sistema operacional baseado em OSX. O contêiner Docker vai executar em um sistema operacional baseado em Alpine Linux. Quando você executar o comando <code>npm install</code>,<em><em> </em></em>serão baixadas as dependências para o ambiente específico.</p><p>Agora, você vai criar um arquivo para ignorar o código gerado no seu ambiente local - por exemplo, a pasta <em>node_modules</em> e a pasta <em>lib<em>.</em></em> Assim, garantimos que, quando você fizer a cópia dos arquivos do seu diretório atual para o contêiner, nenhuma dependência indesejada seja copiada também.</p><p>Na pasta <code>nodejs-with-mongodb-api-example</code>, crie um arquivo com o nome <code>.dockerignore</code><em><em> </em></em>e cole o código abaixo:</p><pre><code class="language-txt">node_modules/
lib/</code></pre><h3 id="construindo-a-imagem-docker"><strong>Construindo a imagem Docker</strong></h3><p>Eu prefiro executar essa aplicação a partir da pasta raiz. Volte para a pasta <code>post-docker-live-reload</code> e execute os comandos a seguir para preparar a imagem para a utilizarmos mais adiante:</p><pre><code class="language-shell">docker build -t app nodejs-with-mongodb-api-example</code></pre><p>Repare que o comando acima utiliza a <em>flag </em><code>-t</code> para definir o nome da imagem. Logo depois disso, é informada a pasta que contém o arquivo <code>Dockerfile</code>.</p><h3 id="trabalhando-com-volumes"><strong>Trabalhando com<strong> volumes</strong></strong></h3><p>Antes de executar a aplicação, vamos fazer alguns "<em>hacks</em>" para melhorar nossa experiência com os contêineres do Docker.</p><p>Os volumes no Docker nos permitem espelhar arquivos da nossa máquina local para o ambiente do Docker. Você também pode compartilhar volumes entre diversos contêineres e reaproveitá-los para criar um <em>cache </em>das dependências.</p><p>Nosso objetivo aqui é observar qualquer mudança nos nossos arquivos <code>.ts</code> do ambiente local e espelhar essas mudanças para o contêiner, mesmo que os arquivos e a pasta <code>node_modules</code> estejam no mesmo diretório.</p><p>Você se lembra quando eu disse que as dependências podem ser diferentes dependendo do sistema operacional? Para ter certeza que nosso ambiente local não vai afetar o ambiente do Docker quando espelharmos os arquivos, nós vamos isolar a pasta <code>node_modules</code> do container em um volume separado.</p><p>Consequentemente, quando a pasta <code>node_modules</code> for criada no contêiner, ela não será criada na nosso ambiente local. Execute o comando abaixo no terminal para criar o volume:</p><pre><code>docker volume create --name nodemodules
</code></pre><h3 id="executando-e-habilitando-o-live-reload"><strong>Executando e habilitando o <strong><em>live-reload</em></strong></strong></h3><p>Como você já sabe, o comando <code>npm run dev:watch</code> especificado no arquivo README.md mostra como habilitar o <em>live-reload</em>. O problema é que você está programando em sua máquina local e suas alterações devem se refletir no contêiner.</p><p>Executando o comando abaixo, você vai conectar seu ambiente local com o contêiner do Docker. Assim, qualquer alteração na pasta <code><code>nodejs-with-mongodb-api-example</code></code> será refletida na pasta <code>src</code> do contêiner.</p><pre><code class="language-shell">docker run \
    --name app \
    --link mongodb \
    -e MONGO_URL=mongodb \
    -e PORT=4000 \
    -p 4000:4000 \
    -v `pwd`/nodejs-with-mongodb-api-example:/src \
    -v nodemodules:/src/node_modules \
    app npm run dev:watch</code></pre><p>Vamos nos aprofundar no que está sendo feito aqui:</p><ul><li><code>--link</code> - dá a permissão para a aplicação acessar a instância do MongoDB;</li><li><code>-e</code> - são as variáveis de ambiente. Como mencionado no arquivo README.md, você pode especificar a <em>string </em>de conexão da instância do MongoDB a qual você quer se conectar sobrescrevendo a variável <code>MONGO_URL</code>. Sobrescreva a variável <code>PORT</code>, caso queira que a aplicação seja executada em uma porta diferente. Observe que o valor de <code>mongodb</code> é o mesmo que usamos para criar a nossa instância do MongoDB nas seções anteriores. Este valor também é um apelido para o IP interno da instância do MongoDB;</li><li><code>-v</code> - mapeia o diretório atual para o contêiner do Docker utilizando um volume virtual. Utilizando o comando <code>pwd</code>, você tem acesso ao caminho absoluto para seu diretório de trabalho atual e, em seguida, para a pasta que você gostaria de espelhar no contêiner do Docker, que, no caso, é o diretório <code>:/src</code>. A pasta <code>src</code> representa a instrução <code>WORKDIR</code>, definida no arquivo <code>Dockerfile</code>, para que possamos espelhar nosso diretório local para a pasta src do contêiner do Docker;</li><li><code>-v</code> - este segundo volume serve para espelhar a pasta <code>node_modules</code> do contêiner de maneira individual;</li><li><code>app</code> - é o nome da imagem;</li><li><code>npm run dev:watch</code> - este último comando vai sobrescrever o comando <code>CMD</code> que está no <code>Dockerfile</code>.</li></ul><p>Após executar o comando acima, você pode acessar o browser novamente e fazer algumas alterações no seu arquivo <code>index.ts</code> para ver os resultados (atente-se que utilizamos a porta 4000 no comando <em>shell</em>). O vídeo abaixo demonstra esses passos:</p><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.17977528089888%;" class="fluid-width-video-wrapper">
            <iframe width="356" height="200" src="https://www.youtube.com/embed/O9vEQhU_JEM?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" title="Example of live reload working - freeCodeCamp post" name="fitvid0"></iframe>
          </div>
        </div>
      </figure><h2 id="finalizando"><strong>Finalizando</strong></h2><p>Você sabe que trabalhar com comandos <em>shell </em>funciona. Não é muito comum , no entanto, usá-los aqui. Também não é muito produtivo executar todos esses comandos, construir as imagens e gerenciar as instâncias manualmente. Então, vamos fazer uma composição!</p><p>O Docker Compose é uma forma de simplificar a agregação e a conexão entre os serviços. Você pode especificar os bancos de dados, os logs, as aplicações, os volumes, as redes e assim por diante.</p><p>Primeiro, será preciso remover todas as instâncias inativas para evitar conflito nas portas expostas. Execute o seguinte comando no seu terminal para remover os volumes, serviços e contêineres:</p><pre><code class="language-bash">docker rm app 
docker volume rm nodemodules
docker stop $(docker ps -aq)
docker rm $(docker ps -aq)</code></pre><h3 id="o-arquivo-docker-compose"><strong>O arquivo <strong>docker-compose</strong></strong></h3><p>Crie um arquivo <code>docker-compose.yml</code> na sua pasta <code>post-docker-livereload</code> usando as informações abaixo:</p><pre><code class="language-yaml">version: '3'
services:
    mongodb:
        image: mongo:4
        ports:
            - 27017:27017
    app:
        build: nodejs-with-mongodb-api-example
        command: npm run dev:watch
        ports:
            - 4000:4000
        environment: 
            MONGO_URL: mongodb
            PORT: 4000
        volumes:
            - ./nodejs-with-mongodb-api-example:/src/
            - nodemodules:/src/node_modules
        links:
            - mongodb
        depends_on: 
            - mongodb

volumes:
    nodemodules: {}</code></pre><p>O arquivo acima especifica os recursos por seções. Repare que, nele, você possui as seções <code>links</code> e <code>depends_on</code>. O campo <em>links</em> representa a mesma <em>flag </em>que você utilizou no comando <em>shell</em>. O campo <code>depends_on</code> vai garantir que o MongoDB é uma dependência necessária para executar a aplicação. Isso fará com que o MongoDB seja executado antes da aplicação magicamente!</p><p>Voltando ao terminal, para iniciar os serviços, construir a imagem do Docker, criar os volumes e os links, execute o seguinte comando:</p><pre><code class="language-shell">docker-compose up --build</code></pre><p>Caso você precise remover todos os serviços criados anteriormente pelo <code>Dockerfile</code>, também pode executar o comando <code>docker-compose down</code>.</p><h2 id="o-docker-seu-amigo-"><strong>O Docker é seu amigo<strong>!</strong></strong></h2><p>É isso, meu amigo. O Docker pode te ajudar a prevenir muitos erros. Você pode utilizá-lo tanto em aplicações <em>front-end </em>como em aplicações <em>back-end</em>. Até mesmo com IoT, quando é necessário controlar um <em>hardware</em>, você pode especificar políticas utilizando o Docker.</p><p>Como um próximo passo, eu recomendo fortemente que você dê uma olhada em ferramentas de orquestração de contêineres, como o Kubernetes e o Docker swarm. Elas podem melhorar ainda mais suas aplicações existentes e ajudar você a atingir um outro nível.</p><h2 id="muito-obrigado-por-ler-at-aqui"><strong>Muito obrigado por ler até aqui</strong></h2><p>Eu fico muito grato por esse tempo que passamos juntos. Espero que esse conteúdo seja mais do que apenas texto. Espero que ele ajude você a se tornar um pensador melhor e também um programador melhor. Siga-me no <a href="https://twitter.com/erickwendel_">Twitter</a> e confira meu <a href="https://erickwendel.com/">blog pessoal</a>, onde eu compartilho muitos conteúdos especiais.</p><p>Até mais!</p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
