<?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: Yan Borowski</title>
    <description>The latest articles on DEV Community by Yan Borowski (@yanborowski).</description>
    <link>https://dev.to/yanborowski</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%2F324595%2F593c8eff-83e0-45c2-8809-543e71911f09.jpg</url>
      <title>DEV Community: Yan Borowski</title>
      <link>https://dev.to/yanborowski</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yanborowski"/>
    <language>en</language>
    <item>
      <title>Os 12 mandamentos das aplicações Cloud-Native</title>
      <dc:creator>Yan Borowski</dc:creator>
      <pubDate>Mon, 25 Oct 2021 19:14:19 +0000</pubDate>
      <link>https://dev.to/yanborowski/os-12-mandamentos-das-aplicacoes-cloud-native-pcm</link>
      <guid>https://dev.to/yanborowski/os-12-mandamentos-das-aplicacoes-cloud-native-pcm</guid>
      <description>&lt;p&gt;Fala pessoal!&lt;/p&gt;

&lt;p&gt;Temos ouvido falar muito hoje em dia sobre aplicações em nuvem, software como serviço (SaaS), sistemas distribuídos, conteinerização, orquestração, além de muitos outros assuntos relacionados. &lt;/p&gt;

&lt;p&gt;Mas e ai? Precisamos saber de tudo? Por onde eu começo?&lt;/p&gt;

&lt;p&gt;Há alguns anos, Adam Wiggins publicou uma metodologia, junto com seus colegas da Heroku, conhecida como "The Twelve-Factor App",  para auxiliar todo mundo que está desenvolvendo software como serviço. Todos esses pontos estão 100% alinhados com o desenvolvimento das famosas aplicações Cloud-Native.&lt;/p&gt;

&lt;p&gt;Antes de entrar no "Twelve-Factor App", vale contextualizarmos a todos de que:&lt;/p&gt;

&lt;p&gt;A arquitetura Cloud-Native é uma abordagem de design para que possamos construir e operar, facilmente, nossos sistemas em ambientes de nuvem, aproveitando todos os benefícios da mesma, sem utilizá-la como um Datacenter. Muitas pessoas hoje continuam utilizando a nuvem como um Datacenter, onde podem crescer seus ambientes de infraestrutura "Ao infinito e além!" (LIGHTYEAR, Buzz). Esse tópico sozinho merece um post separado (EM BREVE O LINK).&lt;/p&gt;

&lt;p&gt;Voltando ao assunto do Twelve-Factor App, ele dita alguns pontos, observados pelo time do Adam, que vão nos auxiliar a entregar softwares melhores, reduzindo problemas conhecidos em cenários complexos. &lt;/p&gt;

&lt;p&gt;Senta que lá vem história:&lt;/p&gt;

&lt;p&gt;1) Base de Código&lt;/p&gt;

&lt;p&gt;O primeiro pilar se refere a sempre utilizarmos a mesma base de código, com isso sempre utilizaremos a mesma versão para publicação dos nossos sistemas, pelos nossos diversos ambientes  (Desenvolvimento, QA, Pre-Produção, Produção, etc).&lt;/p&gt;

&lt;p&gt;Para cada repositório de código, devemos ter apenas um sistema, que respeitará o restante dos outros 11 pilares. Colocar mais de um sistema no mesmo repositório é uma violação do Twelve-Factor App.&lt;/p&gt;

&lt;p&gt;2) Dependências&lt;/p&gt;

&lt;p&gt;O segundo pilar fala sobre o empacotamento de nossas dependências. Nossas dependências devem ser isoladas e devidamente declaradas através de um manifesto de dependências. &lt;/p&gt;

&lt;p&gt;Ex.: quando utilizamos o Nuget com o .NET para declarar nossa árvore de dependências. Isso faz com que cada versão do nosso código não precise ocupar disco com todo pacote de dependências, facilitando a criação de novas ramificações e cópias locais do nosso código, dentre outros benefícios. &lt;/p&gt;

&lt;p&gt;3) Configurações&lt;/p&gt;

&lt;p&gt;Na minha opinião esse é um dos pontos mais críticos do Twelve-Factor App. &lt;br&gt;
Com o advento dos contêineres e seus orquestradores, precisamos que TODOS os nossos sistemas não tenham configurações de AMBIENTE diretamente no código.&lt;/p&gt;

&lt;p&gt;Image a seguinte situação: &lt;br&gt;
Estamos desenvolvendo um sistema com uma esteira de DevOps que transitará a mesma versão do código do ambiente de Desenvolvimento para o ambientes de testes. Após a aprovação no ambiente de testes nosso sistema precisa ir para Produção. Nesse caso, não podemos depender de intervenção manual para gerar um novo pacote com strings de conexão com banco, serviços de mensagens, endpoints de APIs, além de outros. &lt;br&gt;
A cultura de DevOps prega automação de processos.. não podemos automatizar algo de ponta a ponta se precisamos realizar intervenções manuais. &lt;br&gt;
Toda nossa configuração deve estar em variáveis dentro de cada um desses ambientes (ou serem empacotadas através de um pipeline de deploy junto com o compilado do sistema).&lt;br&gt;
Com o Kubernetes conseguimos armazenar configurações em Segredos, podemos passar variáveis de ambiente para os nossos contêineres, isso deixa nosso processo limpo e automatizável. Utilizamos uma mesma imagem de contêiner para todos os ambientes. &lt;/p&gt;

&lt;p&gt;Acabou o "Works on my Machine"!&lt;/p&gt;

&lt;p&gt;Quem nunca esqueceu de copiar novas configs do Config de Dev para Produção naquele deploy manual?&lt;/p&gt;

&lt;p&gt;4) Serviços de Apoio&lt;/p&gt;

&lt;p&gt;Quando falamos de serviços de apoio, estamos falando de serviços como Bancos de Dados, Armazenamento, APIs, serviços de E-mail, etc. &lt;/p&gt;

&lt;p&gt;Todos esses serviços devem ser utilizamos com uma camada que permita a troca, por outro compatível, sem mudanças no código da nossa aplicação, somente ajustando nossos arquivos de configuração.&lt;/p&gt;

&lt;p&gt;5) Build, Release, Run&lt;/p&gt;

&lt;p&gt;Como falamos no item 3, precisamos automatizar nossos processos de publicação. Para isso, a transição do nosso código (pipeline) em desenvolvimento para um ambiente produtivo precisa passar por alguns pontos.&lt;/p&gt;

&lt;p&gt;Precisamos de um passo onde nosso código será preparado para publicação. Por exemplo, se nosso projeto for .net, iremos rodar ferramentas de análise, compactação, compilação, montagem de uma imagem para contêiner, além de outros, dependendo dos processos adotados no nosso projeto.&lt;/p&gt;

&lt;p&gt;Após a compilação, precisamos executar outro passo que fará a publicação do nosso sistema, juntamente com as configurações (se elas forem injetadas de alguma maneira através do pipeline de cada ambiente). &lt;/p&gt;

&lt;p&gt;Com o passo de publicação feito, temos o último processo que se encarregará de fazer uma verificação se os processos estão rodando de forma conforme no ambiente de destino.&lt;/p&gt;

&lt;p&gt;6) Processos&lt;/p&gt;

&lt;p&gt;Esse ponto prega que nossas aplicações devem ser publicadas em forma de um ou mais serviços Stateless, onde a persistência do estado deses serviços é feita através de Serviços de Apoio (nosso 4º Pilar). Com isso, garantimos, por exemplo, que um contêiner que está travado, por algum motivo, possa ser deletado, fazendo com que, quando uma nova instância desse contêiner fique disponível novamente, ela continue o processo com os dados que estão no serviço de apoio. &lt;/p&gt;

&lt;p&gt;7) Portas&lt;/p&gt;

&lt;p&gt;O sétimo pilar nos guia a expor nossos serviços de forma autônoma, sem injeções em tempo de execução. Eles devem estar disponíveis através de portas, onde outros serviços farão uso dos mesmos. &lt;/p&gt;

&lt;p&gt;Como exemplo, podemos citar um contêiner que possui um sistema desenvolvido em ASP.NET exposto através da porta 5000. Esse container, dentro do nosso Kubernetes, será acessado através de um proxy reverso (um Nginx por exemplo), que tem seu endereço de rede mapeado em DNS, configurado na porta 80 desse mesmo proxy. &lt;br&gt;
Nosso Kubernetes fará então o meio de campo para redirecionar as requisições da porta 80 do nosso proxy para a porta 5000 do nosso contêiner. Se tivermos outro frontend rodando em outro contêiner na porta 2000, esse mesmo proxy pode redirecionar uma rota específica, na porta 80, para o segundo contêiner na porta 2000.&lt;/p&gt;

&lt;p&gt;8) Concorrência&lt;/p&gt;

&lt;p&gt;Esse pilar é de grande importância no que tange a resiliência e disponibilidade dos nossos serviços. Devemos projetar nossos serviços para escala de componentes individuais. &lt;/p&gt;

&lt;p&gt;Por exemplo, se temos um processo de leitura de uma fila de mensagem, que precisa ler uma mensagem quase que instantaneamente, devemos separar esse processo de forma que ele possa ser escalado de forma individual, garantindo a resposta de processamento através de realocação de recursos com processos como escalas horizontal e/ou vertical.  &lt;/p&gt;

&lt;p&gt;9) Encerramento&lt;/p&gt;

&lt;p&gt;Quando falamos de sistemas conteinerizados, uma das primeiras coisas que pensamos é na disponibilidade horizontal. Subir novas instâncias dos nossos serviços, matar instâncias sem uso para realocar recurso computacional para outro processo, etc. &lt;/p&gt;

&lt;p&gt;Para isso, precisamos garantir que nossos serviços não demorem uma eternidade para serem desligados (ou ligados). Com isso, garantimos que em uma necessidade de escala horizontal, nosso sistema contará com novas instâncias de algum processo de forma rápida.&lt;/p&gt;

&lt;p&gt;10) Paridade entre os ambientes de Desenvolvimento e Produção&lt;/p&gt;

&lt;p&gt;Nossos ambientes precisam ser o mais próximos possível. Claro que vamos ter algumas disparidades de recursos computacionais por conta de custos. &lt;/p&gt;

&lt;p&gt;O ponto aqui é: com menos variáveis, conseguimos identificar problemas de forma mais rápida.&lt;/p&gt;

&lt;p&gt;11) Logs&lt;/p&gt;

&lt;p&gt;Nossas aplicações precisam gerar logs centralizados, de forma que possamos identificar os eventos que estão acontecendo nas mesmas. Com isso, conseguimos, de forma eficiente, analisar problemas de execução dos nossos serviços, tendo em vista que na maioria das vezes podemos não ter mais acesso ao ambiente de execução de cada instância (se estivermos usando um contêiner, por exemplo).&lt;/p&gt;

&lt;p&gt;12) Processos Administrativos&lt;/p&gt;

&lt;p&gt;Todo processo administrativo, que precise ser executado em nosso ambiente, deve ser versionado na nossa Base de Código e empacotado junto com a aplicação.&lt;/p&gt;

&lt;p&gt;Como exemplo, podemos citar a aplicação de novos scripts de banco de dados em um sistema que utiliza o Entity Framework Code-First. Um processo verifica a versão do banco de dados e atualiza o mesmo com os campos da nova versão.&lt;/p&gt;




&lt;p&gt;Com todos esses "mandamentos" já podemos começar a desenvolver aplicações melhores, concordam?&lt;/p&gt;

&lt;p&gt;Espero que este post dispare gatilhos sempre que alguém for "chumbar" uma string no código! :D&lt;/p&gt;

&lt;p&gt;Grande abraço e até a próxima pessoal!&lt;/p&gt;

&lt;p&gt;Yan.&lt;/p&gt;

</description>
      <category>cloudnative</category>
      <category>cloud</category>
      <category>architecture</category>
      <category>12factor</category>
    </item>
    <item>
      <title>Princípios básicos da Programação Orientação a Objetos (POO)</title>
      <dc:creator>Yan Borowski</dc:creator>
      <pubDate>Mon, 25 Oct 2021 12:16:11 +0000</pubDate>
      <link>https://dev.to/yanborowski/principios-basicos-da-programacao-orientacao-a-objetos-poo-49o3</link>
      <guid>https://dev.to/yanborowski/principios-basicos-da-programacao-orientacao-a-objetos-poo-49o3</guid>
      <description>&lt;p&gt;Fala pessoal! Quem nunca se deparou com um código Orientado a Cebola (É só abrir o código que dá vontade de chorar)? &lt;/p&gt;

&lt;p&gt;Hoje em dia, muitas pessoas dizem que programam orientado a objetos, mas na verdade estão somente trabalhando com o conceito de Classes, criando diversos objetos cheios de parâmetros e acabam esquecendo alguns dos conceitos básicos da POO. &lt;/p&gt;

&lt;p&gt;Conceitos Básicos&lt;/p&gt;

&lt;p&gt;A Orientação a Objetos é um paradigma de computação que nos auxilia a efetuar abstrações de objetos e outras coisas imateriais do mundo real. Essas abstrações serão escritas em forma de estruturas de fácil compreensão, estruturas essas que servirão de modelo para criação de nossos dados dentro dos sistemas.&lt;/p&gt;

&lt;p&gt;A Programação orientada a Objetos baseia-se nos seguintes pilares:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encapsulamento&lt;/li&gt;
&lt;li&gt;Herança&lt;/li&gt;
&lt;li&gt;Polimorfismo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vamos detalhar um pouco mais sobre cada uma das partes principais da POO abaixo:&lt;/p&gt;

&lt;p&gt;1) Classes&lt;br&gt;
São abstrações de objetos do mundo real, essas abstrações funcionam como um modelo para criação de instâncias de objetos que serão manipuladas pelo nosso programa.&lt;br&gt;
As classes são especificadas através de métodos e propriedades, que permitirão que interações sejam feitas com objetos que sejam desse tipo.&lt;/p&gt;

&lt;p&gt;2) Herança&lt;br&gt;
A herança funciona para que possamos efetuar uma especialização de nossas classes, permitindo que tenhamos códigos limpos e mais reutilizáveis. Por exemplo, ao abstrairmos um classe “Humano”, podemos ter duas classes especializadas “Homem” e “Mulher”. Essas duas classes filhas herdarão todas as propriedades e métodos que a classe Humano possuir, como braços, pernas, métodos para Andar(), Respirar(), dentre outros.&lt;br&gt;
Nossa classe Mulher poderia ter propriedades adicionais como “ovários”, “útero”, além de métodos como Gestação (), Amamentar (), etc.&lt;/p&gt;

&lt;p&gt;3) Objetos&lt;br&gt;
Pensando no exemplo anterior, Eu (Yan) sou um objeto da classe “Homem”, que herda todas as propriedades e métodos específicos dessa classe, além de tudo que estiver especificado na classe “Humano”. Esse objeto será identificado por valores específicos que estarão atribuídos aos atributos desse objeto, na hora da criação do mesmo, e durante todo ciclo de vida do mesmo.&lt;/p&gt;

&lt;p&gt;4) Encapsulamento&lt;br&gt;
É uma propriedade da Orientação a Objetos que descreve a ação de efetuar um fluxo de informação dentro da classe. Como exemplo podemos usar o método Andar() da nossa classe Humano. Esse método chama internamente outros métodos como MoverPernaDireta() e MoverPernaEsquerda(), além de trocar propriedades como Peso, etc.&lt;/p&gt;

&lt;p&gt;5) Polimorfismo&lt;br&gt;
É uma ferramenta da Orientação a Objetos que permite termos mais de um método, em uma mesma classe, com o mesmo nome, contanto que ele possua uma passagem de parâmetros diferente, ou que sobrescreva o Método de uma classe pai.&lt;br&gt;
Por exemplo, nossa classe Humano possui um método PerderPeso(). Este método pode ser implementado na nossa classe Humano recebendo um valor para que seja descontado da propriedade Peso. Em nossas classes Homem e Mulher, podemos especializar este método colocando fórmulas e recebendo mais parâmetros, pois a perda de peso ocorre de maneiras diferentes em cada gênero.&lt;/p&gt;

&lt;p&gt;6) Classes Abstratas&lt;br&gt;
São classes que não podem ser diretamente instanciadas. Elas servem como modelo para que outras classes conheçam a classe, sem depender dela.&lt;/p&gt;

&lt;p&gt;7) Interfaces&lt;br&gt;
Interfaces funcionam como contratos, onde a estrutura de uma classe é exposta. Com interfaces, podemos utilizar outro recurso da orientação a objetos como a IoC (Inversion of Control).&lt;/p&gt;

&lt;p&gt;8) Inversão de Controle e Injeção de dependência&lt;br&gt;
A inversão de controle é uma padrão de desenvolvimento, onde a responsabilidade de chamada de métodos é delegada a uma infraestrutura de software, não diretamente pelo programador. Para isso, podemos citar a Injeção de Dependência como ferramenta para tal. Com ela, podemos referenciar contratos e efetuar chamadas a métodos especificados nessas interfaces, a injeção de dependência (que conhece o link entre os contratos e as classes) fará o link, desacoplando e reduzindo a complexidade do nosso código.&lt;/p&gt;

&lt;p&gt;9) S.O.L.I.D.&lt;br&gt;
O SOLID refere-se aos cinco pilares que nos auxiliam a criar códigos mais flexíveis, de fácil manutenção e entendimento.&lt;br&gt;
Esses pilares nos guiam a utilizar todos os itens anteriores de maneira acertiva. O SOLID por si só, merece um dia de aula para exemplos e conceitos. Ele continua tão atual que diversos Padrões de Desenvolvimento novos representam por si só uma única letra, como o “S” que diz que classes devem ter uma única responsabilidade (como o Serverless, FaaS — Function as a Service).&lt;/p&gt;

&lt;p&gt;10) DDD — Domain Driven Design&lt;br&gt;
Uma das abordagens mais utilizada para modelagem de nossas classes, no desenvolvimento do core de nossas aplicação, é o DDD. Esse modelo de desenvolvimento foca no domínio de nosso problema, fazendo com que sigamos os principios do SOLID, evitando dar responsabilidade de mais a nossas estruturas, modelando nosso Software focando em linguagem oblíqua, que é nada mais nada menos que uma linguagem falada pelo usuário do nosso sistema como “EfetuarTransferencia()”, “DepositarCheque()”, etc.&lt;/p&gt;

&lt;p&gt;Nos próximos posts abordarei mais a fundo conceitos que precisam estar entranhados em nossos subconscientes como SOLID (Muita atenção nesse cara), YAGNI, KISS, DRY, DDD, Design Patterns, dentre outros.&lt;/p&gt;

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

</description>
    </item>
  </channel>
</rss>
