<?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: Alexandre Antonio Juca</title>
    <description>The latest articles on DEV Community by Alexandre Antonio Juca (@alexjuca).</description>
    <link>https://dev.to/alexjuca</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%2F57424%2Fd220db33-486b-414f-a97d-55c02d7c242d.jpeg</url>
      <title>DEV Community: Alexandre Antonio Juca</title>
      <link>https://dev.to/alexjuca</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alexjuca"/>
    <language>en</language>
    <item>
      <title>How to dynamically load configurations for tests at runtime within Elixir libraries</title>
      <dc:creator>Alexandre Antonio Juca</dc:creator>
      <pubDate>Tue, 19 May 2020 15:19:14 +0000</pubDate>
      <link>https://dev.to/alexjuca/how-to-dynamically-load-configurations-for-tests-at-runtime-within-elixir-libraries-2ign</link>
      <guid>https://dev.to/alexjuca/how-to-dynamically-load-configurations-for-tests-at-runtime-within-elixir-libraries-2ign</guid>
      <description>&lt;p&gt;I recently started working with elixir and had the opportunity to create a library at &lt;a href="https://www.linkedin.com/company/next-solutions-lda/"&gt;Next Business Solutions&lt;/a&gt; called &lt;a href="https://github.com/nextbss/ex-okta-auth"&gt;ExOktaAuth&lt;/a&gt; that enables elixir applications to handle signup/sign-in flows using Okta's OAuth 2.0/OIDC service.&lt;/p&gt;

&lt;p&gt;Now while writing tests for the library, I faced an issue while trying to test a function that was dependent on application configuration that is usually defined in the config.ex file of the phoenix application that is using the library as a dependency.&lt;/p&gt;

&lt;p&gt;This is a snippet of the functions code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:ex_okta_auth&lt;/span&gt;
             &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Application&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch_env!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
             &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;validate_config!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:client_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
             &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;validate_config!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:client_secret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
             &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;validate_config!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:site&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
             &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;validate_config!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:redirect_uri&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


    &lt;span class="n"&gt;site&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Keyword&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:site&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="no"&gt;ExOAuth2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
      &lt;span class="ss"&gt;strategy:&lt;/span&gt; &lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;client_id:&lt;/span&gt; &lt;span class="no"&gt;Keyword&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:client_id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="ss"&gt;client_secret:&lt;/span&gt; &lt;span class="no"&gt;Keyword&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:client_secret&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="ss"&gt;site:&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;redirect_uri:&lt;/span&gt; &lt;span class="no"&gt;Keyword&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:redirect_uri&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="ss"&gt;authorize_url:&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"/v1/authorize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;token_url:&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"/v1/token"&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;ExOAuth2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;put_serializer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"application/json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Jason&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Essentially what this code does is load and validate configuration options that it acquires from the application's config.ex file and uses that to create an %ExOAuth2.Client struct that is responsible for setting up the definitions used for interactions with okta's API.&lt;/p&gt;

&lt;p&gt;This works all good and well but implementing a unit test for this function turned out to be quite difficult for me since I am new to elixir.&lt;/p&gt;

&lt;p&gt;Since the function was dependent on the configuration, I had to find a way to load a specific configuration at runtime so the function could acquire those configuration options during testing.&lt;/p&gt;

&lt;p&gt;I came up with the following solution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Define configuration to load during test
&lt;/h3&gt;

&lt;p&gt;Create a file named config.ex in the test/ folder of your library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="no"&gt;Config&lt;/span&gt;

&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="ss"&gt;:ex_okta_auth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;ExOktaAuth&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Okta&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;client_id:&lt;/span&gt; &lt;span class="s2"&gt;"isoaspoaisa"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;client_secret:&lt;/span&gt; &lt;span class="s2"&gt;"kajskaljs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;site:&lt;/span&gt; &lt;span class="s2"&gt;"http://127.0.0.1:4000/default"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;redirect_uri:&lt;/span&gt; &lt;span class="s2"&gt;"https://your-apps-callback-uri"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Load config dynamically during tests
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="no"&gt;Config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Reader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"test/config.ex"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Application&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;put_all_env&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here you can see how I used this solution in the context of a real test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;ExOktaAuthTest&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;ExUnit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Case&lt;/span&gt;
  &lt;span class="n"&gt;doctest&lt;/span&gt; &lt;span class="no"&gt;ExOktaAuth&lt;/span&gt;

  &lt;span class="n"&gt;setup_all&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;setup_config&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;state:&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;setup_config&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;Config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Reader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"test/config.ex"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Application&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;put_all_env&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="s2"&gt;"Should return a valid client"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="no"&gt;ExOktaAuth&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Okta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;Helpers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;valid_client&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I would love to know if there is a better solution for this problem and if my solution has any pitfalls, so please do critique and provide feedback.&lt;/p&gt;

&lt;p&gt;This was a post from Alexandre Juca, A software Engineer working at a wonderful company called Next Solutions based in Luanda/Angola.&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>softwareengineering</category>
      <category>tests</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>7 Lições aprendidas ao desenvolver bibliotecas</title>
      <dc:creator>Alexandre Antonio Juca</dc:creator>
      <pubDate>Tue, 05 Nov 2019 13:15:49 +0000</pubDate>
      <link>https://dev.to/alexjuca/7-licoes-aprendidas-ao-desenvolver-bibliotecas-59n7</link>
      <guid>https://dev.to/alexjuca/7-licoes-aprendidas-ao-desenvolver-bibliotecas-59n7</guid>
      <description>&lt;p&gt;Criar uma biblioteca open source é uma experiência prazerosa para muitos desenvolvedores. Pois, permite criar uma solução para um determinado problema que outros desenvolvedores têm ou que irão ter e poupar tempo e esforço. E há uma possibilidade que centenas ou milhares de pessoas ao redor do mundo usem a solução.&lt;/p&gt;

&lt;p&gt;É bem provável que já teve a oportunidade de usar muitas bibliotecas na sua carreira profissional mas será que já teve a oportunidade de criar uma biblioteca, gem, package etc? Quais são as coisas que um desenvolvedor pode fazer para criar uma biblioteca de boa qualidade e de fácil consumo? Como pode ajudar os consumidores da sua biblioteca a saber o que deu errado para corrigir? Quais são alguns princípios ou modelos mentais que possam ajudar você a criar algo que seja simples de usar? Como reduzir e lidar com a complexidade? Como lidar com mudanças que irão acontecer durante o ciclo de vida da sua biblioteca?&lt;br&gt;
Nesta série de artigos irei responder essas perguntas e dar dicas para ajudar você a criar bibliotecas com maior qualidade, flexibilidade e que sejam mais fáceis de consumir. Mas antes há uma pergunta importante que todos nós devemos fazer.&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Preciso mesmo de criar uma biblioteca?
&lt;/h2&gt;

&lt;p&gt;Antes de investir tempo e energia para criar uma biblioteca, pesquise para ver se já existem outros disponíveis para resolver o seu problema. Ian Summerville ao falar sobre fundamentos de engenharia de software no seu livro intitulado Engenharia de software 9a edição expressou um conselho digno da sua atenção:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Você deve fazer o melhor uso possível dos recursos existentes. Isso significa que, quando apropriado, você deve usar o software já desenvolvido, em vez de escrever um novo. — Ian Summerville”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Caso as bibliotecas existentes não sejam aptas para uso no seu projecto por razões de negócio, licenças, ou má qualidade, poderá seguir em frente. O tema a seguir mudou completamente a minha visão sobre desenvolvimento de software.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Pense no cliente
&lt;/h2&gt;

&lt;p&gt;É essencial pensar no cliente final que irá consumir a sua biblioteca, neste caso o desenvolvedor. Isso envolve ter ou mostrar empatia, mas antes precisamos definir claramente o que significa ter empatia e depois veremos como isso está relacionado ao desenvolvimento e engenharia de software. De acordo com o site &lt;a href="http://www.significados.com.br"&gt;www.significados.com.br&lt;/a&gt; empatia significa:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“A capacidade psicológica para sentir o que sentiria uma outra pessoa caso estivesse na mesma situação vivenciada por ela. Consiste em tentar compreender sentimentos e emoções, procurando experimentar de forma objetiva e racional o que sente outro indivíduo.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Daí poderá surgir uma pergunta da sua parte: Mas como isso está relacionado ao desenvolvimento de software?&lt;/p&gt;

&lt;p&gt;Visto que a empatia permite nos colocar no lugar de uma outra pessoa, seguir os princípios de desenvolvimento orientado a empatia permite criar software centrado ao desenvolvedor, no caso que estejamos a desenvolver uma biblioteca. Vai ajudar-nos a pensar nas dificuldades do consumidor e diminuir fricção com uma documentação clara e fácil de entender. Também, se aplicado corretamente permite-nos criar software que seja mais fácil de usar e com uma interface ou API mais simples e um produto final de maior qualidade.&lt;/p&gt;

&lt;p&gt;Como fazer na prática?&lt;/p&gt;

&lt;p&gt;Pense em como o consumidor vai usar a sua biblioteca e veja o que pode complicar o trabalho dele e diminuir a sua produtividade. Vamos usar como exemplo uma biblioteca desenvolvido na NEXT para interagir com a API da ProxyPay para efectuar pagamentos na rede multicaixa e outra exemplo fictício.&lt;br&gt;
A API poderia ser desenhado deste jeito:&lt;/p&gt;

&lt;p&gt;Exemplo A1&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;proxyPay&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ProxyPayPayment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;proxyPay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ProxyPayConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;proxyPay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;referenceRequest&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;
&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Antes de continuar a sua leitura, análise o código acima e procura problemas que um desenvolvedor pode encontrar.&lt;br&gt;
Exemplo B1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;makeNormal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Customer&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;o1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;OrderLine&lt;/span&gt; &lt;span class="n"&gt;line1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OrderLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TAL"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;o1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;OrderLine&lt;/span&gt; &lt;span class="n"&gt;line2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OrderLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"HPK"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;o1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;OrderLine&lt;/span&gt; &lt;span class="n"&gt;line3&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OrderLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"LGV"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;o1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;line2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setSkippable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;o1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setRush&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Em essência, criamos os vários objetos e os unimos. Se não podemos configurar tudo no construtor, precisamos criar variáveis temporárias para nos ajudar a construir o produto final — este é particularmente o caso em que você está adicionando itens nas coleções.&lt;/p&gt;

&lt;p&gt;Este é a forma mais convencional que tenho visto para juntar um conjunto de objectos. Conseguiu notar como pode ser muito trabalhoso para o desenvolvedor montar todos os objectos necessários para sua tarefa?&lt;br&gt;
Aplicando o princípio de empatia permite-nos achar uma maneira mais simples de lidar com o mesmo caso. Uma boa alternativa é usar um fluent interface e o Builder pattern.&lt;/p&gt;

&lt;p&gt;Solução para A1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;proxyPay&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ProxyPayPayment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addProxyPayConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ProxyPayConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addReferenceRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  

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



&lt;p&gt;Solução para B1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;makeFluent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Customer&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newOrder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"TAL"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"HPK"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;skippable&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"LGV"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;priorityRush&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Qual dessas opções deixa a intenção do código mais claro? É bem provável que a sua resposta seja os dois últimos e com boa razão visto que a API foi desenhada para ser legível e para fluir como um poema bem escrito. O preço de fazer isso é tirar mais tempo para pensar e construir a API mas com certeza o artefacto final será algo bem mais fácil para o cliente entender e consumir.&lt;/p&gt;

&lt;h3&gt;
  
  
  Em resumo
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Antes de começar a escrever uma única linha de código procura entender melhor o problema e colocar-se no lugar do cliente.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Desenhar como os vários componentes da biblioteca irão interagir.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Outro ponto essencial é desenhar a API e pensar em como o desenvolvedor vai usar a sua biblioteca e prever os possíveis problemas que possa encontrar ao usar a sua biblioteca.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  3. Assume sempre que o cliente seja “estúpido”
&lt;/h2&gt;

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

&lt;p&gt;Recentemente comprei uma cadeira para o meu escritório e tive o prazer de montá-lo. Todas as peças foram cuidadosamente colocadas e organizadas na sua caixa. O manual teve desenhos bem simples para ajudar-me a montar a cadeira sem ter que ligar um amigo (Quem quer ser milionário). O manual não tinha texto nenhum. Apenas números para apresentar os passos diferentes para montar a cadeira com sucesso. O que o fabricante da cadeira pensou antes de criar-lo? A equipe provavelmente pensou em como poderiam facilitar a vida de quem vai montar a cadeira e consequentemente poupar seu tempo. Eles assumiram que o cliente fosse “estúpido”. Quer dizer, diminuíram a complexidade para o benefício de quem vai montar.&lt;/p&gt;

&lt;p&gt;Por vezes como desenvolvedores gostamos de mostrar o quão inteligente nós somos por criar coisas demasiados complexos ou usar recursos da linguagem de programação que são poucos conhecidas ou “exotéricos”. Isso cria uma barreira para quem vai usar a sua biblioteca. Porquê? Lembra que o desenvolvedor está com tempo limitado e precisa fazer uma entrega o mais rápido possível e na melhor qualidade possível. Isso pode causar vários problemas, um deles que merece maior destaque é:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O desenvolvedor pode cometer um erro ao usar a sua biblioteca se for demasiado complexo usá-o.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Do mesmo jeito que alguém pode cometer um erro ao montar uma cadeira porque há muitas peças e o jeito de montar-lá é demasiado complexo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Como podemos reduzir complexidade?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O livro “The Laws of Simplicity” (As Leis da simplicidade) escrito por John Maeda diz algo que mudou o meu modo de pensar completamente e que é aplicável em quase tudo na vida incluindo desenvolvimento de software e tecnologia.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“A maneira mais simples de obter simplicidade&lt;br&gt;
é através da redução ponderada.- John Maeda”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O segredo consiste em reduzir em vez de aumentar. Elimina tudo que não for necessário. Simplifique o seu código, a sua interface e aplique o padrão de desenho melhor adequado para o seu problema.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Qual vai ser o resultado disso?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A sua biblioteca será mais fácil de manter e consumir, e podes ter a certeza que os consumidores sentir-se-ão mais inteligentes por terem escolhido a sua solução.&lt;br&gt;
No próximo artigo desta série irei abordar sobre outras dicas que irão ajudar você a criar bibliotecas melhores.&lt;/p&gt;

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

&lt;p&gt;Este é o Alexandre Juca, ele é Engenheiro de Software na NEXT e é apaixonado por Fintechs, Segurança, I.A e Negócios.&lt;br&gt;
A sua missão é revolucionar e impulsionar empresas usando tecnologia.&lt;/p&gt;

&lt;p&gt;Lista de algumas bibliotecas open source desenvolvidas por Alexandre Juca e que tem ele como contribuidor:&lt;/p&gt;

&lt;p&gt;ProxPay Elixir - &lt;a href="https://github.com/nextbss/proxypay-elixir"&gt;https://github.com/nextbss/proxypay-elixir&lt;/a&gt;&lt;br&gt;
ExOauth2 - &lt;a href="https://github.com/AlexJuca/ex_oauth2"&gt;https://github.com/AlexJuca/ex_oauth2&lt;/a&gt;&lt;br&gt;
OktaAuth - &lt;a href="https://github.com/nextbss/okta_auth"&gt;https://github.com/nextbss/okta_auth&lt;/a&gt;&lt;br&gt;
ProxyPay Kotlin — &lt;a href="https://github.com/nextbss/proxypay-kotlin"&gt;https://github.com/nextbss/proxypay-kotlin&lt;/a&gt;&lt;br&gt;
BiometricKit — &lt;a href="https://github.com/AlexJuca/BiometricKit"&gt;https://github.com/AlexJuca/BiometricKit&lt;/a&gt;&lt;br&gt;
Kamba Android SDK — &lt;a href="https://github.com/usekamba/kamba-android-sdk"&gt;https://github.com/usekamba/kamba-android-sdk&lt;/a&gt;&lt;br&gt;
Kamba Woocommerce — &lt;a href="https://github.com/usekamba/kamba-woocommerce"&gt;https://github.com/usekamba/kamba-woocommerce&lt;/a&gt;&lt;br&gt;
Hades - &lt;a href="https://github.com/fklement/hades"&gt;https://github.com/fklement/hades&lt;/a&gt;&lt;/p&gt;

</description>
      <category>engenhariadesoftware</category>
      <category>programação</category>
      <category>desenvolvimentodesoftware</category>
      <category>tecnologia</category>
    </item>
  </channel>
</rss>
