<?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>Forem: Juliane Pires</title>
    <description>The latest articles on Forem by Juliane Pires (@julianepires).</description>
    <link>https://forem.com/julianepires</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%2F512966%2Fc816d2d3-7cbd-4b90-826e-991dd7ba7be7.jpg</url>
      <title>Forem: Juliane Pires</title>
      <link>https://forem.com/julianepires</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/julianepires"/>
    <language>en</language>
    <item>
      <title>Design Patterns - 1 - Strategy (C#)</title>
      <dc:creator>Juliane Pires</dc:creator>
      <pubDate>Thu, 13 Oct 2022 23:28:36 +0000</pubDate>
      <link>https://forem.com/julianepires/design-patterns-1-strategy-c-4co1</link>
      <guid>https://forem.com/julianepires/design-patterns-1-strategy-c-4co1</guid>
      <description>&lt;p&gt;Padrões de projeto, ou design patterns, são bem importantes para escrever códigos limpos, manuteníveis, legíveis e bem estruturados de acordo com cada situação, ou seja, para trazer soluções elegantes para problemas recorrentes. &lt;/p&gt;

&lt;p&gt;Para iniciar o estudo desses padrões, temos o padrão &lt;em&gt;Strategy&lt;/em&gt;, um padrão comportamental que traz uma estratégia para lidar com a repetição e reaproveitamento de algoritmos em comum a diversas classes. Para isto, utilizamos interfaces que possuem uma definição desses métodos comuns e um conjunto de classes que implementam essa interface, concentrando toda a manipulação desse método no objeto e não tendo que criar código repetido em cada classe criada.&lt;/p&gt;

&lt;p&gt;Para que fique mais claro, temos como exemplo uma calculadora de impostos, onde os métodos de cada imposto tem uma mesma estrutura, mudando apenas a taxa de acordo com o imposto escolhido. Para evitar que crie-se uma estrutura gigantesca com várias condicionais ou métodos, separamos os impostos em classes e criamos uma interface com a definição do método de cálculo do imposto recebendo o orçamento como parâmetro. As classes então implementariam a interface, sendo possível criar um único método na CalculadoraDeImpostos, lidando com o valor de acordo com a variância do método com o imposto definido.&lt;/p&gt;

&lt;p&gt;Temos então a definição das classes de Impostos:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ICMS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
namespace DesignPatterns.Impostos
{
    public class ICMS : Imposto
    {
        public double Calcula(Orcamento orcamento)
        {
            return orcamento.Valor * 0.1;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;ISS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
namespace DesignPatterns.Impostos
{
    public class ISS : Imposto
    {
        public double Calcula(Orcamento orcamento)
        {
            return orcamento.Valor * 0.6;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Concentradas em um diretório de impostos para manter a organização e facilitar a leitura/manipulação.&lt;/p&gt;

&lt;p&gt;A interface &lt;strong&gt;Imposto&lt;/strong&gt; traz então a definição do método Calcula, comum entre os diversos impostos:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Imposto&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
namespace DesignPatterns
{
    public interface Imposto
    {
        double Calcula(Orcamento orcamento);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Na classe da calculadora de impostos, temos o método que recebe o orçamento e o tipo de imposto e chama o método Calcula informando o orçamento como parâmetro.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CalculadorDeImpostos&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using DesignPatterns.Impostos;

namespace DesignPatterns
{
    public class CalculadoraDeImpostos
    {
        public void RealizaCalculo(Orcamento orcamento, Imposto imposto)
        {
            double valor = imposto.Calcula(orcamento);
            Console.WriteLine(valor);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Na classe orçamento, que recebe o valor,  temos:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Orçamento&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
namespace DesignPatterns
{
    public class Orcamento
   {
        public double Valor { get; private set; }

        public Orcamento(double valor)
        {
            this.Valor = valor;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E então na classe Program, instanciamos um orçamento e um imposto e calculamos e realizamos o calculo informando essas propriedades:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Program&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// See https://aka.ms/new-console-template for more information
using DesignPatterns;
using DesignPatterns.Impostos;

Orcamento orcamento = new Orcamento(500.00);

Imposto imposto = new ICMS();

CalculadorDeImpostos calculador = new CalculadorDeImpostos();

calculador.RealizaCalculo(orcamento, imposto);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A resposta no terminal será: 50.00.&lt;/p&gt;

&lt;p&gt;Então, o padrão comportamental Strategy permite que uma família de algoritmos similares se conversem, mas sejam separados em classes, tornando o código desacoplado e bem distribuído.&lt;/p&gt;

</description>
      <category>designpatterns</category>
      <category>csharp</category>
      <category>codequality</category>
      <category>refactorit</category>
    </item>
    <item>
      <title>Clean Code e a assimetria entre objetos e estruturas de dados</title>
      <dc:creator>Juliane Pires</dc:creator>
      <pubDate>Sat, 01 Oct 2022 14:24:10 +0000</pubDate>
      <link>https://forem.com/julianepires/clean-code-e-a-assimetria-entre-objetos-e-estruturas-de-dados-4pii</link>
      <guid>https://forem.com/julianepires/clean-code-e-a-assimetria-entre-objetos-e-estruturas-de-dados-4pii</guid>
      <description>&lt;p&gt;Talvez nós desenvolvedores tenhamos ouvido ou até reproduzido bastante a afirmação de que tudo na programação é objeto. O capítulo 6 do livro Clean Code, escrito pelo Robert C. Martin (também conhecido como &lt;em&gt;Uncle Bob&lt;/em&gt;, ou tio Bob), explica porque nem sempre precisamos de objetos, às vezes precisamos somente de simples estruturas de dados e qual a diferença entre os dois conceitos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;O capítulo começa questionando o porquê dos desenvolvedores exporem variáveis privadas como se fossem públicas através de métodos acessores (&lt;em&gt;gets&lt;/em&gt; and &lt;em&gt;sets&lt;/em&gt;), mesmo quando se quer preservar essas variáveis para que não gere dependência.&lt;/p&gt;

&lt;h2&gt;
  
  
  Abstração de Dados
&lt;/h2&gt;

&lt;p&gt;A abstração de dados é super importante para que ocultemos os detalhes de nossos dados. Para isso, não utilizamos meramente métodos de escrita e leitura dos dados, isso faria com que ficassem expostos, nem tão somente trata-se de manipulação de métodos e funções. É necessário um entendimento da melhor maneira de manipular a &lt;em&gt;essência&lt;/em&gt; dos dados que um objeto contenha, de maneira em que a implementação deste permaneça oculta.&lt;/p&gt;

&lt;h2&gt;
  
  
  Antissimetria data/objeto
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Objetos ocultam seus dados através de abstrações e expõem métodos que manipulam esses dados.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Estruturas de dados expõem seus dados, mas suas funções não são significativas.&lt;/p&gt;

&lt;p&gt;Ou seja, basicamente, as definições de objeto e estrutura de dados são quase que complementares.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Em resumo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Em estruturas de dados, temos facilidade de adição de novas funções sem precisar alterar as estruturas de dados existentes, enquanto no código orientado a objeto, a facilidade está em adicionar novas classes sem alterar os métodos existentes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Em estruturas de dados, temos dificuldade em adicionar novas estruturas de dados, pois demandaria a alteração de todas as funções. Enquanto que na programação orientada a objeto, a dificuldade está em adicionar novos métodos, pois demandaria a alteração das classes existentes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O que é difícil em orientação a objeto é fácil para estruturas de dados e vice-versa. Assim, podemos tratar cada caso de acordo com o que for cabível e adequado.&lt;/p&gt;

&lt;p&gt;Em casos em que desejamos adicionar novos tipos de dados sem alterar a função, o ideal seria utilizar a orientação a objeto, enquanto em casos em que desejamos adicionar novas funções mantendo os dados preservados, então estruturas de dados são mais adequadas.&lt;/p&gt;

&lt;p&gt;Isso acaba respondendo o que foi questionado no início e desmistificando a afirmação de que em programação tudo é um objeto. Muitas vezes temos e desejamos estruturas de dados simples com funções operando sobre elas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lei de Demeter
&lt;/h2&gt;

&lt;p&gt;A lei de Demeter é uma heurística (heurística: &lt;em&gt;método que utiliza a pesquisa e prática para descobrir novos conceitos e provar fatos em busca de resposta para questões complexas&lt;/em&gt;) que afirma que um módulo não deve enxergar o interior dos objetos que ele manipula. Objetos abstraem os dados e expõem as operações sobre eles, ou seja, devem ocultar sua estrutura externa e não expô-la através de métodos acessores.&lt;/p&gt;

&lt;p&gt;Mais precisamente, se temos uma função f em uma classe C, este só deve chamar métodos de:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;C&lt;/li&gt;
&lt;li&gt;Um objeto criado por f&lt;/li&gt;
&lt;li&gt;Um objeto passado por parâmetro para f&lt;/li&gt;
&lt;li&gt;Um objeto dentro de uma variável de instância C&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Train Wrecks
&lt;/h2&gt;

&lt;p&gt;Quando temos um código com métodos acoplados, como por exemplo:&lt;/p&gt;

&lt;p&gt;const cep = ctx.getPessoa().getEndereco().getCep()&lt;/p&gt;

&lt;p&gt;Chamamos de &lt;em&gt;Train Wreck&lt;/em&gt;, pois a estrutura se comporta como um conjunto de vagões acoplados, se assemelhando a um trem. Esse tipo de código é considerado descuidado e inapropriado. O ideal seria escrevermos dessa maneira:&lt;/p&gt;

&lt;p&gt;const pessoa = ctx.getPessoa();&lt;/p&gt;

&lt;p&gt;const endereco = pessoa.getEndereco();&lt;/p&gt;

&lt;p&gt;const cep = endereco.getCep();&lt;/p&gt;

&lt;p&gt;A função getCep() possui acesso a muita informação em níveis aos quais não deveria ter acesso, certamente tem conhecimento de que o objeto &lt;em&gt;ctx&lt;/em&gt; possui &lt;em&gt;pessoas&lt;/em&gt;, que por sua vez possuem objetos do tipo &lt;em&gt;endereco&lt;/em&gt; e, por consequência, possuem objetos do tipo &lt;em&gt;cep&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Se isso é uma violação da lei de Demeter, dependerá se &lt;em&gt;ctx&lt;/em&gt;, &lt;em&gt;pessoa&lt;/em&gt;, &lt;em&gt;endereco&lt;/em&gt; e &lt;em&gt;cep&lt;/em&gt; são simples estruturas de dados ou objetos. Caso sejam objetos, não deveriam estar expondo sua estrutura interna, esta deveria estar oculta. Portanto, a informação sobre o seu interior viola a heurística. Por outro lado, caso sejam estruturas de dados simples, sua implementação interna é naturalmente exposta, não violando essa lei.&lt;/p&gt;

&lt;p&gt;Esse questionamento acaba sendo menos confuso quando estruturas de dados simplesmente tem variáveis públicas e nenhuma função, enquanto objetos tem apenas variáveis privadas e funções públicas. Porém existem frameworks e padrões (como, por exemplo, o padrão &lt;em&gt;beans&lt;/em&gt;) que demandam métodos acessores e de alteração, mesmo em estruturas de dados simples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Híbridos
&lt;/h2&gt;

&lt;p&gt;Estruturas híbridas são compostas por parte objeto e parte estruturas de dados. Essa configuração é ruim pois acaba expondo variáveis internas, fazendo com que funções externas tenham acesso a essas variáveis como numa estrutura de dados, assim como funções significativas e exposição de métodos acessores. O que dificulta tanto a adição de novas funções como a criação de novas estruturas de dados. São estruturas confusas, que não possuem coerência e devem ser evitadas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Estruturas Ocultas
&lt;/h2&gt;

&lt;p&gt;Devemos evitar que estruturas internas sejam expostas dentro de um objeto, ou que este não acabe se sobrecarregando de métodos para tratar informações. Para isso, utilizamos estruturas ocultas, métodos que lidem com a manipulação dessa estrutura sem expô-la ou comprometer a sua abstração.&lt;/p&gt;

&lt;h2&gt;
  
  
  Objetos de Transferência de Dados
&lt;/h2&gt;

&lt;p&gt;Os DTO’s, ou objetos de transferência de dados, são basicamente classes que possuem variáveis públicas e nenhuma função. São estruturas úteis, especialmente para se comunicar com banco de dados ou analisar sintaticamente mensagens provenientes de sockets. São úteis para converter dados brutos vindos do banco de dados em objetos no código do aplicativo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Active Record
&lt;/h2&gt;

&lt;p&gt;Active Records são formas especiais de DTOs. São estruturas de dados com variáveis públicas, mas tipicamente possuem métodos de navegação como &lt;em&gt;find&lt;/em&gt; e &lt;em&gt;save.&lt;/em&gt; Os Active Records são traduções diretas das tabelas de bancos ou outras fontes de dados.&lt;/p&gt;

&lt;p&gt;A solução para evitar que essas estruturas sejam tratadas como objetos, criando um híbrido entre uma estrutura de dados e um objeto, é tratar o Record Active como uma estrutura de dados e criar objetos separados que contenham as regras de negócio e ocultem seus dados internos.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Objetos expõem ações e ocultam seus dados, facilitando a adição de novos tipos de objetos sem modificar os métodos existentes e dificulta a inclusão de novas atividades em objetos existentes.&lt;/li&gt;
&lt;li&gt;Estruturas de dados expõem dados e não possuem ações significativas, facilitando a adição de novos métodos sem afetar os dados existentes e dificultando a adição de novas estruturas em funções existentes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Em um sistema, é desejável que haja flexibilidade para adicionar novos tipos de dados, para isso prefere-se o uso de objetos. Em outras ocasiões, queremos flexibilidade para adicionar novas ações, sendo preferível optar pela estrutura de dados e procedimentos. Portanto, cabe a nós desenvolvedores entendermos e decidirmos pela melhor estrutura aplicável no momento.&lt;/p&gt;

</description>
      <category>cleancode</category>
      <category>datastructure</category>
      <category>oop</category>
    </item>
    <item>
      <title>Event Bubbling</title>
      <dc:creator>Juliane Pires</dc:creator>
      <pubDate>Tue, 28 Jun 2022 18:41:06 +0000</pubDate>
      <link>https://forem.com/julianepires/event-bubbling-3m3p</link>
      <guid>https://forem.com/julianepires/event-bubbling-3m3p</guid>
      <description>&lt;h2&gt;
  
  
  Referência
&lt;/h2&gt;

&lt;p&gt;Você já reparou no comportamento de uma garrafa ou copo de refrigerante? Percebeu como as bolhas se deslocam do fundo até o topo do copo?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o1tydmER--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x5vycbng9luttpkyac7t.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o1tydmER--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x5vycbng9luttpkyac7t.gif" alt="soda bubbling" width="220" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O event bubbling no javascript funciona de maneira similar, quando alguma ação ou interação com o HTML é feita por um componente filho, o evento que é causado por efeito colateral é propagado como uma "bolha" até o elemento pai, que lida com o mesmo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prática
&lt;/h2&gt;

&lt;p&gt;Podemos observar os seguintes elementos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="utf-8" /&amp;gt;
    &amp;lt;meta http-equiv="X-UA-Compatible" content="IE=edge" /&amp;gt;
    &amp;lt;title&amp;gt;Page Title&amp;lt;/title&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1" /&amp;gt;
    &amp;lt;link rel="stylesheet" type="text/css" media="screen" href="main.css" /&amp;gt;
    &amp;lt;script src="main.js"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;div onclick="alert('elemento pai')"&amp;gt;
      FORM
      &amp;lt;div onclick="alert('elemento filho')"&amp;gt;
        DIV
        &amp;lt;div onclick="alert('elemento neto')"&amp;gt;P&amp;lt;/div &amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao clicarmos no &lt;em&gt;elemento neto&lt;/em&gt; temos o efeito bubbling e o evento será propagado e acionado nos demais elementos ancestrais, ou seja, ocorrerão três alertas:&lt;/p&gt;

&lt;p&gt;alerta 1 “elemento neto”&lt;/p&gt;

&lt;p&gt;alerta 2 “elemento filho”&lt;/p&gt;

&lt;p&gt;alerta 3 “elemento pai”&lt;/p&gt;

&lt;p&gt;Como essa propagação só ocorre entre os ancestrais, esse movimento nos três elementos só funciona partindo do elemento neto. Caso o clique seja aplicado no elemento filho, a propagação trará o seguinte resultado:&lt;/p&gt;

&lt;p&gt;alerta 1 “elemento filho”&lt;/p&gt;

&lt;p&gt;alerta 2 “elemento pai”&lt;/p&gt;

&lt;p&gt;Podemos verificar o comportamento:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/julianepires/embed/NWyQzdx?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Interromper Propagação
&lt;/h2&gt;

&lt;p&gt;Para que a propagação seja interrompida, devemos utilizar o stopPropagation. Assim, quem lidará com o evento será o próprio elemento e não chegará aos elementos ancestrais.&lt;/p&gt;

&lt;p&gt;Podemos observar então esse comportamento:&lt;br&gt;
&lt;iframe height="600" src="https://codepen.io/julianepires/embed/OJvJjxQ?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Ao clicarmos no elemento filho, a propagação não irá ocorrer para o elemento pai porque foi interrompida, o mesmo não ocorrerá para o elemento neto pois a propagação só funciona para elementos ascendentes.&lt;/p&gt;

&lt;p&gt;Também podemos observar que, após o clique no elemento neto, o evento se propaga para o elemento filho e para nele, interrompendo a propagação.&lt;/p&gt;

&lt;p&gt;É isto!&lt;/p&gt;

&lt;p&gt;Para mais informações, aqui fica o artigo de inspiração &lt;a href="https://javascript.info/bubbling-and-capturing"&gt;eventBubbling Javascript&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>eventbubbling</category>
    </item>
  </channel>
</rss>
