<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator>
  <link href="https://mariomelo.com/feed.xml" rel="self" type="application/atom+xml" />
  <link href="https://mariomelo.com/" rel="alternate" type="text/html" />
  <updated>2026-03-19T16:33:32+00:00</updated>
  <id>https://mariomelo.com/feed.xml</id>
  <title type="html">Mario Melo</title>
  <subtitle>Software Developer &amp; Scrum Trainer</subtitle>

  
  
  <entry xml:lang="pt">
    <title type="html">Porque saí do substack e quais são as alternativas?</title>
    <link href="https://mariomelo.com/porque-abandonei-o-substack" rel="alternate" type="text/html" title="Porque saí do substack e quais são as alternativas?" />
    <published>2026-02-13T00:00:00+00:00</published>
    <updated>2026-02-13T00:00:00+00:00</updated>
    <id>https://mariomelo.com/porque-abandonei-o-substack</id>
    <content type="html" xml:base="https://mariomelo.com/porque-abandonei-o-substack">
      <![CDATA[<p>Ano passado eu tentei me comprometer a escrever mais, e fui razoavelmente bem até a metade do ano. Escolhi o Substack como plataforma, e gostei da idéia de como ele conectava quem escrevia a quem lia os textos.</p>

<p>Mas aí, veio a <a href="https://pt.wikipedia.org/wiki/Merdifica%C3%A7%C3%A3o"><em>merdificação</em></a>.</p>

<h2 id="métricas-sempre-elas">Métricas, sempre elas</h2>

<p>O Substack é uma plataforma onde alguns autores liberam seus textos sem cobrar nada por isso, enquanto outros cobram um certo valor para textos mais importantes. Daí, o que passa a ser relevante para quem escreve?</p>

<ul>
  <li>Número de views</li>
  <li>Número de menções</li>
  <li>Número de assinantes</li>
  <li>Número de assinantes pagos</li>
</ul>

<p>E até aí tudo bem, tudo normal. Tem muito conteúdo bom por lá que vale o dinheiro cobrado, e muitas pessoas competentes o bastante para conseguirem viver desse modelo.</p>

<p>O problema não são <del>todos</del> os autores, mas sim o que a plataforma faz para tentar tornar essas métricas atraentes o suficiente para manter os autores ali e atrair novos escritores. Com o tempo, o substack adicionou:</p>

<ul>
  <li>Uma espécie de Twitter</li>
  <li>Popups pedindo para o leitor assinar a newsletter o tempo todo</li>
  <li>Opção padrão de assinar <strong>TODOS</strong> os substacks que um autor recomenda ao assinar a sua newsletter</li>
</ul>

<p>Ler um post no substack se tornou um exercício de paciência e eu comecei a ficar chateado de fazer quem dedica um pouco do seu tempo para ler o que eu escrevi passar por isso. Aí minha vontade de escrever ali foi diminuindo.</p>

<h2 id="onde-eu-tracei-a-linha">Onde eu tracei a linha</h2>

<p>Como se nada disso bastasse, as métricas fizeram com que newsletter completamente desprezíveis se tornassem interessantes para o negócio porque geram renda para a empresa.</p>

<p>E isso inclui <a href="https://arstechnica.com/tech-policy/2025/07/substacks-nazi-problem-wont-go-away-after-push-notification-apology">newsletters nazistas</a>.</p>

<p>Aí sair do substack deixou de ser uma opção e passou a ser uma necessidade para mim.</p>

<h2 id="pra-onde-eu-fui-e-pra-onde-você-pode-ir">Pra onde eu fui e pra onde você pode ir?</h2>

<p>Se enviar newsletters é super importante para você, o <a href="https://ghost.org">Ghost</a> é a melhor opção. É open-source, fácil de configurar e é bem leve. Muitas pessoas têm feito esta transição, e em termos de funcionalidades é quem mais se assemelha ao substack.</p>

<p>Se você quer só escrever e imagens não são muito importantes para você, dá pra usar o <a href="https://writefreely.org">WriteFreely</a>. Como foi feito em Go, é bastante leve (no teste que fiz no meu servidor ele consumia apenas cerca de 50Mb de memoria RAM!). A experiência de escrever é agradável e direto ao ponto. Curiosamente, o WriteFreely foi desenvolvido como alternativa ao Medium porque seu fundador se cansou da merdificação do Medium.</p>

<p>Se você quiser algo gratuito, com alto nível de personalização e tendo total propriedade sobre os eu conteúdo, o melhor a se fazer é usar um gerador de blogs estáticos como o <a href="https://jekyllrb.com">Jekyll</a>, o <a href="https://gohugo.io">Hugo</a> ou o <a href="https://astro.build">Astro</a>. Esse blog foi feito com o Jekyll, que é feito em Ruby e foi criado a mais tempo, e acabei seguindo por esse caminho porque eu já tinha adquirido um tema que se encaixava com o que eu tinha imaginado para meu site. O Hugo é uma opção mais moderna, e provavelmente a melhor escolha aqui, principalmente se você pretende escrever em mais de um idioma.</p>

<p>Outra vantagem dos geradores de sites estáticos é que você pode hospedá-los gratuitamente no Github pages, por exemplo. Nem precisa pagar um servidor.</p>

<p>Se você quer algo para ler, sugiro fortemente usar um RSS Reader, que nada mais é do que um aplicativo onde você adiciona os blogs que gosta de ler e ele te avisa sobre novos posts sem poluir a sua caixa de email. O RSS é ainda uma forma de leitura mais <strong>consciente</strong>: você precisa escolher aquilo que quer ler e acompanhar, e nenhum algoritmo tenta te empurrar nenhuma outra coisa.</p>

<p>Atualmente, os softwares/serviços que uso são:</p>

<ul>
  <li><a href="https://www.scaleway.com/en/">Scaleway</a>, para hospedar meu site.</li>
  <li><a href="https://typora.io">Typora</a>, para escrever os posts.</li>
  <li><a href="https://plausible.io">Plausible</a>, self-hosted. Para coletar métricas respeitando a sua privacidade (nada de Google Analytics aqui).</li>
  <li><a href="https://procreate.com">Procreate</a>, para criar as imagens que uso no blog</li>
  <li><a href="https://vivaldi.com">Vivaldi</a>, navegador que também tem um RSS reader</li>
</ul>

<h2 id="mas-e-a-newsletter">Mas… e a newsletter?</h2>

<p>Bom, por enquanto ela não existe, mas pode ser que no futuro eu crie uma. Agradeço de coração a todo mundo que assinou a newsletter no substack, e espero que vocês sigam acompanhando o que eu escrever por aqui.</p>

]]>
    </content>
    <author>
      <name>Mario Melo</name>
    </author>
    
    <category term="Tools" />
    
    <category term="Degoogle" />
    
    <summary type="html">Tem um tempo que não escrevo, e tem um motivo: estava desanimado em continuar publicando no Substack.</summary>
  </entry>
  
  <entry xml:lang="pt">
    <title type="html">O pacote de expansão do Scrum é valioso?</title>
    <link href="https://mariomelo.com/o-pacote-de-expansao-do-scrum-e-valioso" rel="alternate" type="text/html" title="O pacote de expansão do Scrum é valioso?" />
    <published>2025-07-28T17:00:36+00:00</published>
    <updated>2025-07-28T17:00:36+00:00</updated>
    <id>https://mariomelo.com/o-pacote-de-expansao-do-scrum-e-valioso</id>
    <content type="html" xml:base="https://mariomelo.com/o-pacote-de-expansao-do-scrum-e-valioso">
      <![CDATA[<p>No mês passado Jeff Sutherland e companhia publicaram um pacote de expansão para o Framework Scrum (vou chamá-lo de SGEP para abreviar). E verdade seja dita, meio que flopou. Tivemos cerca de meia semana de posts no LinkedIn (principalmente reviews negativos) e acabou.</p>

<p>Não queria escrever nada superficial sobre isso, então tentei ler cuidadosamente, com baixas expectativas, e fiz algumas anotações ao longo do caminho.</p>

<h1 id="não-é-perfeito">Não é perfeito…</h1>

<p>Scrum é um framework e portanto é incompleto por natureza. Ele nos dá a tarefa de completá-lo com práticas, técnicas e ferramentas, e essa é a melhor parte do Framework Scrum na minha opinião.</p>

<p>Quando ouvi pela primeira vez sobre o pacote de expansão, temi que ele preencheria as lacunas e tornaria a coisa toda mais prescritiva, e acho que a maioria das pessoas compartilhou o mesmo sentimento. Os autores conseguiram evitar esse problema muito bem, porém, havia outros problemas que encontrei.</p>

<h2 id="não-é-um-pacote-de-expansão">Não é um pacote de expansão</h2>

<p>Ao invés de apenas adicionar novas informações, os autores também mudaram alguns conceitos originais (ex: revertendo para o uso da palavra <strong>roles</strong> ao invés de <strong>accountabilities</strong>).</p>

<p>Também diz que o Product Backlog Refinement pode ser um evento, o que realmente não aprecio já que na minha experiência esse tipo de linguagem fomenta um comportamento mecânico.</p>

<p>Não é um único documento. Como os autores afirmam logo no início:</p>

<p><em>“Este documento é uma coleção de trabalhos independentes. Cada seção mantém sua licença original ou status de copyright, conforme indicado.”</em></p>

<p>Então a leitura é uma estrada cheia de lombadas, e às vezes repetitiva.</p>

<p>Fora isso, eu diria que é praticamente inofensivo.</p>

<h1 id="na-verdade-pode-ajudar-quem-está-tendo-dificuldades-com-scrum">Na verdade pode ajudar quem está tendo dificuldades com Scrum</h1>

<p>Venho ensinando desenvolvimento de software e Scrum desde 2013, e ouso dizer que uma boa parte das perguntas que as pessoas me fazem durante sessões de treinamento podem ser respondidas pelo pacote de expansão.</p>

<p>E na maioria das vezes o SGEP conseguiu fazer isso expandindo o <strong>PORQUÊ</strong> das coisas, com um enorme foco em <strong>empirismo</strong>.</p>

<h2 id="mais-palavras-facilitam-o-entendimento">Mais palavras facilitam o entendimento</h2>

<p>Deixe-me dar um exemplo concreto: a <strong>Sprint Review</strong>. O Scrum Guide original é um tanto quanto críptico quando diz:</p>

<blockquote>
  <p>O propósito da Sprint Review é inspecionar o resultado da Sprint e determinar futuras adaptações</p>

  <p><cite> Scrum Guide, 2020</cite></p>
</blockquote>

<p>Também diz que <em>O Product Backlog <strong>também pode ser ajustado</strong> para atender novas oportunidades.</em></p>

<p>Nas minhas aulas frequentemente levo algum tempo para discutir isso: precisamos determinar futuras adaptações, o que significa mudar o Product Backlog de alguma forma. Portanto, uma Sprint Review que não muda o Product Backlog é algo que deveria causar alguma reflexão. Além disso, se a Sprint Review é um evento obrigatório, significa que o Scrum Team não está passivamente aberto a mudar o Product Backlog: <strong>eles estão ativamente buscando essas mudanças.</strong></p>

<p>O SGEP usa mais palavras para descrever isso:</p>

<p>“<em>O Product Backlog (o quê) <strong>É</strong> adaptado</em>” - Não “<em>também pode ser ajustado</em>”, mas um forte “<strong>É</strong>.”</p>

<p>Esse é o tipo de diferença que importa para mim. Reforçando que Scrum é sobre aprender através de experimentação para que possamos usar informação fresca para desenvolver coisas.</p>

<h2 id="foco-em-empirismo">Foco em Empirismo</h2>

<p>O principal problema que a maioria das pessoas tem com Scrum, às vezes sem nem perceber, é que usam o framework acreditando que vai aumentar a velocidade de desenvolvimento. Isso frequentemente coloca Product Owner e Developers em confronto ao invés de colaboração. Esse problema é tão comum que a última atualização do Scrum Guide mudou o termo “<em>Development Team</em>” para “<em>Developers</em>”, e a explicação de por que fizeram isso foi:</p>

<blockquote>
  <p>O objetivo era eliminar o conceito de um time separado dentro de um time que levou ao comportamento de “proxy” ou “nós e eles” entre o PO e Dev Team.</p>

  <p>Agora existe apenas um Scrum Team focado no mesmo objetivo, com três diferentes conjuntos de responsabilidades: PO, SM e Developers.</p>

  <p><cite><a href="https://scrumguides.org/revisions.html">- Scrum Guide 2020 Revisions</a></cite></p>
</blockquote>

<p>Não me entenda mal: eu gosto dessa mudança. Mas para iniciantes ou mesmo pessoas que têm usado o Framework Scrum de forma disfuncional por muito tempo, isso não vai resolver nenhum problema. Quer dizer, nem o SGEP resolve, mas pelo menos acho que fez um trabalho melhor tentando alcançar isso.</p>

<p>Por exemplo, o SGEP:</p>

<ul>
  <li>
    <p>Afirma claramente que ser uma feature-factory ou uma discovery factory não é desejável</p>
  </li>
  <li>
    <p>Estabelece que o Product Owner precisa <strong>comunicar efetivamente os resultados</strong></p>
  </li>
  <li>
    <p>O Produto se torna um artefato com métricas baseadas em resultados</p>
  </li>
</ul>

<p>O SGEP também cria a <strong>Definition of Outcome Done</strong>, e tenho sentimentos mistos sobre isso. Por um lado adiciona mais uma peça ao quebra-cabeça e torna o framework Scrum mais prescritivo, mas por outro lado pode ser especialmente importante para aqueles começando ou tendo dificuldades com Scrum.</p>

<p>Falando nisso, o SGEP também fornece alguns insights valiosos para aqueles começando ou tendo dificuldades com seu trabalho como Scrum Masters.</p>

<h2 id="fornece-melhores-direções-para-scrum-masters">Fornece melhores direções para Scrum Masters</h2>

<p>O Scrum Guide original descreve o Scrum Master em meia página. E se você tem uma boa dose de experiência com o framework, isso é mais que suficiente.</p>

<p>O SGEP, porém, entra mais nos detalhes específicos, mas sem limitar muito do seu trabalho. Afirma, por exemplo, que <strong>o Sprint Backlog deve ter trabalho suficiente para começar, ex: comece com um ou dois Product Backlog Items em direção ao Sprint Goal</strong>. E você pode ler essa frase como: “não existe Definition of Ready”.</p>

<p>Outro exemplo é o Product Backlog: enquanto o guia original afirma que o Scrum Master deve <em><strong>encontrar técnicas para definição efetiva do Product Goal e gerenciamento do Product Backlog</strong></em>, o SGEP adiciona algumas informações valiosas em cima disso, como: <em><strong>Um Product Backlog menor frequentemente fornece mais Transparência</strong></em> ou até a sugestão de usar um <em><strong>Outcome Criteria</strong></em> para Product Backlog Items.</p>

<p>Mais uma vez, sei que essas são notícias velhas para alguns. No entanto, torna óbvio algumas das coisas que as pessoas frequentemente têm dificuldade em aprender.</p>

<h2 id="então-é-valioso">Então, é valioso?</h2>

<p>Pode ser. Mas não para todo mundo. Mas ler é um bom exercício de qualquer forma, então vá em frente. O foco em empirismo é o que me fez gostar, e é um <strong>pacote de expansão</strong>, o que significa… é opcional de qualquer forma. Você também pode pegar algumas das ideias e aplicá-las se não quiser adicionar tudo.</p>

<p>Então, se você está indo bem com Scrum, não precisa. Afinal, você provavelmente já está fazendo a maioria das coisas descritas lá.</p>

<p>Se você sente que o Scrum Guide é críptico e te deixa com a sensação de que deveria elaborar um pouco mais em alguns aspectos porque você está travado, então o Scrum Guide Expansion Pack pode ser uma boa coisa para você.</p>
]]>
    </content>
    <author>
      <name>Mario Melo</name>
    </author>
    
    <category term="Teamwork" />
    
    <category term="Scrum" />
    
    <summary type="html">No mês passado Jeff Sutherland e companhia publicaram um pacote de expansão para o Framework Scrum (vou chamá-lo de SGEP para abreviar).</summary>
  </entry>
  
  <entry xml:lang="pt">
    <title type="html">As armadilhas do desenvolvimento aumentado por IA, parte 2</title>
    <link href="https://mariomelo.com/as-armadilhas-do-desenvolvimento-aumentado-por-ia-parte-2" rel="alternate" type="text/html" title="As armadilhas do desenvolvimento aumentado por IA, parte 2" />
    <published>2025-06-04T09:21:57+00:00</published>
    <updated>2025-06-04T09:21:57+00:00</updated>
    <id>https://mariomelo.com/as-armadilhas-do-desenvolvimento-aumentado-por-ia-parte-2</id>
    <content type="html" xml:base="https://mariomelo.com/as-armadilhas-do-desenvolvimento-aumentado-por-ia-parte-2">
      <![CDATA[<p><strong>AVISO</strong>: Este é o segundo post que escrevi sobre minha palestra no Global Scrum Gathering Munich, e embora eu não ache que você precise ler ambos os posts em ordem, sugiro fortemente que leia os dois para ter a totalidade das ideias que estou compartilhando. Então, aqui vai o link para o primeiro:</p>

<p>Agora, vamos voltar às nossas armadilhas e também falar sobre uma “<em>guerra</em>” que está acontecendo pelos últimos 40 anos: a <a href="https://en.wikipedia.org/wiki/Editor_war">Guerra dos Editores</a>. Pode parecer uma guerra boba, ou uma simples questão de preferências, mas confie em mim: não é apenas tribalismo geek, é sobre filosofias fundamentalmente diferentes de interação humano-computador.</p>

<p>Eu sou um usuário de NeoVim. Isso significa que sou um daqueles geeks que prefere digitar código no terminal ao invés de usar algo mais moderno como VSCode. Enquanto uso NeoVim eu nunca uso meu mouse ou touchpad: apenas digito coisas e uso um monte de combinações de teclas para navegar pelo código. Mas não estou sozinho! O primeiro editor Vi foi criado em 1976 e desde então sua popularidade só cresceu entre os mais geeks dos desenvolvedores de software.</p>

<p>Por quê? Bem, vamos explicar isso enquanto falamos sobre uma das armadilhas que mencionei em Munique:</p>

<h2 id="armadilha-4-a-visão-de-túnel-na-codificação"><strong>Armadilha 4: A Visão de Túnel na Codificação</strong></h2>

<p>Vi e seus irmãos (Vim, Neovim) se tornaram populares porque permitiam que desenvolvedores navegassem pelo código mais rápido. Ao invés de mover sua mão para o mouse, rolar para baixo, selecionar uma parte do código que você quer mudar e então digitar a mudança, esses editores propuseram uma ideia diferente: eles teriam <strong>modos</strong>. Enquanto no modo <strong>INSERT</strong>, tudo que você digita no teclado apareceria na tela, assim como acontece em qualquer outro editor. Mas no modo <strong>NORMAL</strong>, cada tecla no seu teclado pode ser usada para navegar pelo código.</p>

<p>Por exemplo: se você pressionar 3wce você instantaneamente mudaria o conteúdo da terceira palavra naquela linha. (Algo como: Vá para a <strong>3</strong>ª <strong>W</strong>ord <strong>C</strong>hange até seu <strong>E</strong>nd).</p>

<p>Basicamente cria um dialeto para que você possa dizer ao seu editor onde você quer ir e o que quer fazer com seu código sem precisar usar mouse, menus, etc. E acelerar como navegamos pelo código é importante porque <strong>desenvolvedores de software gastam mais tempo navegando e entendendo o código do que escrevendo</strong>.</p>

<p>Um gráfico representando os resultados de uma pesquisa sobre como desenvolvedores gastam seu tempo</p>

<p>Então, por que estamos focando em usar LLMs para gerar código quando também podemos usá-los para nos ajudar a entender o código? Quer dizer, eles são ótimos programadores, não estou negando isso. Mas na minha experiência eles podem fornecer muito mais valor explicando o código ao invés de apenas criá-lo.</p>

<p>Aqui está um exemplo prático de como fiz isso: estou atualmente escrevendo um software para melhorar as atividades práticas que realizo nas minhas aulas. E em algum momento decidi pedir ao Claude para explicar minha própria arquitetura para mim. Como o Claude se destaca em output de texto, achei que seria legal usar uma ferramenta como <a href="https://mermaid.js.org">Mermaid</a>, uma ferramenta que transforma inputs de texto em diagramas elegantes. Pedi ao Claude para explicar a estrutura usando <a href="https://www.markdown-cheatsheet.com">MarkDown</a> e <a href="https://mermaid.js.org">Mermaid</a>, e colei o resultado em um editor de texto compatível com ambas as tecnologias chamado <a href="https://typora.io/">Typora</a>. Aqui está o resultado:</p>

<p><img src="../assets/images/posts/4fad149de25d.jpeg" alt="Image" /></p>

<p>Essa é uma ótima documentação que pode ser usada para explicar tanto aos desenvolvedores do meu time quanto ao próprio LLM como a arquitetura funciona! Especialmente porque o diagrama pode ser lido pelo LLM como um simples input de texto, minimizando a quantidade de tokens consumidos em cada interação.</p>

<p>A questão é que, não importa se você escreveu o código manualmente ou se um LLM escreveu a coisa toda para você, você ainda será responsável pelas consequências. Portanto, entender o que está acontecendo é fundamentalmente importante.</p>

<p>Lembre-se: <strong>se algo funciona e você não sabe como, quando parar de funcionar você não saberá o porquê.</strong></p>

<h2 id="armadilha-5-o-viés-de-volume"><strong>Armadilha 5: O Viés de Volume</strong></h2>

<p>Algumas pessoas ainda estão reclamando da qualidade do código gerado por LLMs e discordo fortemente dessa opinião. Na minha experiência, o código gerado é na verdade muito bom.</p>

<p>O que me incomoda é a <strong>quantidade</strong> de código.</p>

<p>Especialmente porque não acredito em “vibe coding” (isto é: confiar no código gerado e nem dar uma olhada nele). Preciso revisar o código e garantir que está fazendo o que deveria fazer porque… sou um adulto responsável? Então, quando o LLM muda 8 arquivos e adiciona 200 linhas de código para cada prompt que faço, meu trabalho se torna extremamente doloroso e bem, sem graça. Tentei múltiplas abordagens e diferentes prompts para reduzir esse problema mas ainda não encontrei uma solução.</p>

<p>Para ser justo, o Claude 4.0 apresentou uma grande melhoria quando se trata dessa armadilha específica, e acho que teremos uma solução definitiva para isso num futuro próximo. Mas ainda não chegamos lá.</p>

<p><img src="../assets/images/posts/eaa796ed5b4d.png" alt="Image" /><em>Um prompt, MUITAS mudanças</em></p>

<p>O que sinto é que ao invés de nos ajudar a andar mais rápido, os LLMs estão nos ajudando a dar passos maiores. Ambas as abordagens podem nos ajudar a cobrir uma distância maior na mesma quantidade de tempo, mas a segunda também vem com um alto custo quando você está andando na direção errada. O modelo de negócio também contribui para isso: quando uso o Cursor, por exemplo, tenho tokens/interações limitados, o que me incentiva a tirar o máximo de cada prompt.</p>

<h2 id="conclusão"><strong>Conclusão</strong></h2>

<p>Escrever sobre trabalhar com LLMs é uma coisa estranha. Eu sinceramente acredito em tudo que escrevi neste post <strong>hoje</strong>. Mas as coisas estão mudando rápido, e este post pode envelhecer como leite ou vinho dependendo dos próximos desenvolvimentos. Se você valoriza aprender mais sobre esse tópico, sugiro fortemente que faça duas coisas: <strong>use</strong> para criar algo ao invés de apenas ler sobre isso no LinkedIn (melhor ainda: se afaste do LinkedIn de uma vez), e tente ler diferentes opiniões sobre o assunto. O livro de Karen Hao “<strong>The Empire of AI</strong>” pode ser um bom começo.</p>
]]>
    </content>
    <author>
      <name>Mario Melo</name>
    </author>
    
    <category term="Coding" />
    
    <category term="AI" />
    
    <summary type="html">AVISO: Este é o segundo post que escrevi sobre minha palestra no Global Scrum Gathering Munich, e embora eu não ache que você precise ler ambos os posts em ordem, sugiro fortemente que leia os dois para ter a totalidade das ideias que estou compartilhando.</summary>
  </entry>
  
  <entry xml:lang="pt">
    <title type="html">As armadilhas do desenvolvimento aumentado por IA, parte 1</title>
    <link href="https://mariomelo.com/as-armadilhas-do-desenvolvimento-aumentado-por-ia" rel="alternate" type="text/html" title="As armadilhas do desenvolvimento aumentado por IA, parte 1" />
    <published>2025-05-07T17:00:08+00:00</published>
    <updated>2025-05-07T17:00:08+00:00</updated>
    <id>https://mariomelo.com/as-armadilhas-do-desenvolvimento-aumentado-por-ia</id>
    <content type="html" xml:base="https://mariomelo.com/as-armadilhas-do-desenvolvimento-aumentado-por-ia">
      <![CDATA[<p>Minha palestra no Global Scrum Gathering Munich foi rápida, e eu disse lá que escreveria sobre o assunto para aprofundar essa discussão, então aqui estou. Adicionei uma “Parte 1” ao título porque agora gostaria de explorar três delas: <strong>Fixação na Escrita</strong>, <strong>Abordagem Monolítica</strong> e <strong>Atrofia para Aprender</strong>.</p>

<p>A coisa engraçada nessa conferência é que fui a duas palestras subsequentes que se conectaram diretamente com o que apresentei: Nigel Baker e Paul Goddard falaram sobre Pair Programming (e ainda estou decepcionado que eles não mencionaram Penn &amp; Teller nos seus exemplos de pareamento) e o keynote final do Henrik Kniberg que falou sobre IA agêntica em software e desenvolvimento ágil de software. Então, também vou conectar insights das apresentações deles para enriquecer nossa conversa. Para fazer isso, vou mudar a ordem em que inicialmente apresentei as armadilhas.</p>

<h2 id="armadilha-1---fixação-na-escrita">Armadilha 1 - Fixação na Escrita</h2>

<p>Minha primeira reclamação sobre como a maioria das pessoas tem usado IA era sobre como continuamos escrevendo e usando texto como a <strong>única</strong> forma de falar com nossos LLMs. Kniberg usou duas formas diferentes de comunicação durante sua apresentação: <strong>voz</strong> e um desenho em <strong>guardanapo</strong>. E é precisamente sobre isso que eu estava falando: a linguagem tem limitações, e essas são notícias velhas. Nietzsche notoriamente disse que <em><strong>Toda palavra é um preconceito</strong></em> e William James desafiou nossa capacidade de compreender o significado por trás das palavras com sua anedota do esquilo dando volta na árvore.</p>

<p>Se você quiser experimentar como isso poderia funcionar, você pode integrar o Aider com ChatGPT para usar sua voz para programar (e talvez esse possa ser meu próximo post também). Mas se você não quiser ir tão longe, <strong>desenhe</strong>, tire screenshots para usar como exemplos, basicamente: <strong>experimente</strong>.</p>

<p>Um diagrama mostrando como os módulos da minha aplicação devem interagir entre si</p>

<p>Agora, o diagrama nos leva imediatamente para a próxima armadilha…</p>

<h2 id="armadilha-2---atrofia-para-aprender">Armadilha 2 - Atrofia para Aprender</h2>

<p><em>Se uma IA pode programar, por que eu aprenderia a programar?</em>, bem… essa é uma pergunta interessante. Na minha palestra mencionei que o código gerado pelos LLMs atuais (como Sonnet 3.7) é na verdade muito bom, e muitas vezes melhor do que o que um humano escreveria. E os LLMs estão melhorando mais rápido do que nós estamos agora, então…</p>

<p>Então ainda precisamos aprender. Olhe o diagrama na seção anterior: ele fala sobre estrutura de software e como organizar o código. Se você não sabe programar, você não consegue criar diagramas como esses e <strong>suas opções serão limitadas</strong>. Essas limitações podem te levar a becos sem saída e problemas que você é incapaz de resolver, e se seu colega IA também é incapaz de resolver então…</p>

<p><img src="../assets/images/posts/b22f19f41da8.jpeg" alt="Image" /><em>O lado sombrio do vibe</em></p>

<p>Como Nigel Baker e Paul Goddard disseram na palestra deles: <strong>parear é uma ótima forma de aprender</strong>. Você provavelmente vai aprender que pessoas diferentes usam LLMs de formas diferentes, e você vai ter que descobrir quando usar cada abordagem. Por exemplo: hoje em dia você pode literalmente programar um agente que checaria tudo que sua pessoa amada postou na internet e automaticamente compraria presentes para ela em datas especiais. E provavelmente serão bons presentes!</p>

<p>Mas é uma boa ideia? Bem, eu não acho. Simon Wardley propõe uma pergunta interessante para resolver esse dilema, e em todo caso, se você ainda não assistiu a palestra dele <strong>por favor assista</strong>:</p>

<blockquote>
  <p><em>Quanto você valoriza um humano envolvido nessa decisão?</em></p>
</blockquote>

<p>E às vezes, quando desenvolvemos software, isso importa. Mas novamente: suas capacidades de tomada de decisão serão limitadas pelo seu conhecimento. Então, continue aprendendo (e tente parear com outra pessoa para que você possa aprender mais e mais rápido).</p>

<h2 id="armadilha-3---a-abordagem-monolítica">Armadilha 3 - A Abordagem Monolítica</h2>

<p>Eu fiz uma piada durante minha apresentação e disse que <em>Vibe Coding</em> deveria ser renomeado para <em>Conversational Reactive Assisted Programming</em>, ou <strong>C.R.A.P.</strong>. Todo mundo riu, e momentos depois estávamos todos assistindo Henrik Kniberg fazendo uma demonstração impressionante usando Cursor.</p>

<p>Então, acho que vou ter que me explicar. :)</p>

<p>O termo Vibe Coding foi cunhado por Andrej Karpathy, e ele disse que a técnica é “<em>não tão ruim para projetos descartáveis de fim de semana</em>”. Uma parte chave da definição de vibe coding é que o usuário aceita código sem entendimento completo, e o pesquisador de IA Simon Willison até disse que “<em><strong>Se um LLM escreveu cada linha do seu código, mas você revisou, testou e entendeu tudo, isso não é vibe coding no meu entendimento—isso é usar um LLM como um assistente de digitação</strong></em>.”</p>

<p>Então, por essa definição de Vibe Coding, eu mantenho minha piada. Pelo menos por enquanto. O conceito de não se importar com o código gerado por um LLM pode ser uma boa ideia, mas apenas se soubermos <strong>quando usá-lo</strong>, e por enquanto não deveria ser 100% do tempo a menos que você esteja construindo um protótipo.</p>

<p>A questão é que, se você não sabe programar, Vibe Coding será sua <strong>única opção</strong> quando usar um LLM para desenvolver software. E não é realmente <strong>programação</strong>, porque é não-determinístico: o mesmo prompt pode gerar resultados diferentes. Eu prefiro o termo que Simon Wardley usa: <strong>Vibe Wrangling</strong>.</p>

<p><img src="../assets/images/posts/0f708cd44fe0.jpeg" alt="Image" /><em>Um slide da minha palestra: Se você tem mais conhecimento técnico, você terá mais opções</em></p>

<p>Talvez no futuro ter <strong>Vibe Coding</strong> como sua única opção não será um problema, mas ainda não chegamos lá. Pode acontecer ano que vem, em 2035, ou pode nunca acontecer. Mas não importa a resposta, aprender a programar ainda é relevante porque vai <strong>expandir suas opções</strong>. E essa é minha principal (e talvez única) crítica sobre a ótima sessão de keynote do Kniberg: eu não acho que Vibe Coding é uma <strong>evolução</strong> de copiar e colar código gerado por um LLM, por exemplo. Eu vejo todas essas abordagens sendo usadas em contextos diferentes, e a decisão sempre vai se resumir a uma versão levemente modificada da pergunta proposta por Simon Wardley:</p>

<blockquote>
  <p>Quão consciente eu preciso estar sobre a forma como isso vai ser implementado?</p>
</blockquote>

<p>Para mim a resposta ainda é “<em><strong>com bastante frequência</strong></em>”. LLMs são enviesados, não-determinísticos e replicam todos os problemas que estavam presentes em seus dados de treinamento. Eles vão cometer erros, e alguns desses erros podem prejudicar pessoas, especialmente em grupos que são sub-representados nos dados usados para treinar os modelos (você pode e deve conferir o trabalho da Dra. <strong>Timnit Gebru</strong>). Quando aceitamos código gerado por IA sem entendimento completo, estamos herdando não apenas a solução, mas também os preconceitos conceituais embutidos nela.</p>

<p>Então, responder essa pergunta é algo que vamos começar a fazer cada vez mais. E voltando à sessão de Nigel Baker e Paul Goddard: você não precisa responder essa pergunta sozinho.</p>
]]>
    </content>
    <author>
      <name>Mario Melo</name>
    </author>
    
    <category term="Coding" />
    
    <category term="AI" />
    
    <summary type="html">Minha palestra no Global Scrum Gathering Munich foi rápida, e eu disse lá que escreveria sobre o assunto para aprofundar essa discussão, então aqui estou.</summary>
  </entry>
  
  <entry xml:lang="pt">
    <title type="html">O que escolhi não construir: Decisões que tomei enquanto criava minha plataforma de treinamento usando Elixir</title>
    <link href="https://mariomelo.com/o-que-escolhi-nao-construir" rel="alternate" type="text/html" title="O que escolhi não construir: Decisões que tomei enquanto criava minha plataforma de treinamento usando Elixir" />
    <published>2025-03-31T17:11:56+00:00</published>
    <updated>2025-03-31T17:11:56+00:00</updated>
    <id>https://mariomelo.com/o-que-escolhi-nao-construir</id>
    <content type="html" xml:base="https://mariomelo.com/o-que-escolhi-nao-construir">
      <![CDATA[<p>Como qualquer desenvolvedor por aí, eu adoro começar projetos pessoais. Mas para mim eles têm um peso diferente: desenvolver um projeto pessoal me ajuda a manter conectado com minha <a href="/about">missão pessoal.</a></p>

<p>Estou constantemente ensinando e fazendo coaching com pessoas sobre como desenvolver produtos melhores, seja em aulas de CSM/CSD, como consultor ou como mentor. Eu tenho minha cota de histórias para compartilhar durante esses eventos, mas sabe como é… embora essas histórias sejam novas e empolgantes para os estudantes, não posso dizer o mesmo depois de repeti-las uma dúzia de vezes.</p>

<p>E além disso… preciso de uma desculpa para colocar a mão no código. :)</p>

<h2 id="o-produto">O Produto</h2>

<p>Como instrutor, tento criar simulações para que meus estudantes possam aprender pela própria experiência na maior parte do tempo. É por isso que em 2019 criei o jogo de cartas <a href="https://scrumchkin.com">Scrumchkin</a>, por exemplo. Mas desde a pandemia, a maioria das minhas sessões de treinamento tem sido online, o que torna muito difícil replicar o mesmo ambiente dinâmico que eu tinha com as cartas reais do Scrumchkin em um treinamento presencial.</p>

<p>Então, decidi que meu produto tentaria resolver esse problema:</p>

<blockquote>
  <p><strong>Os estudantes devem ser capazes de aprender assuntos complexos através de experiência dinâmica e simulações.</strong></p>
</blockquote>

<p>Era um fit perfeito, afinal: tenho aulas periódicas onde posso levar o produto para um teste de campo e coletar feedback, e tenho acesso a uma comunidade de instrutores que poderiam estar interessados em experimentar o produto e fornecer um tipo diferente de feedback.</p>

<p>Como tudo que eu precisava era uma desculpa para começar a escrever código, fiquei satisfeito com isso.</p>

<p><strong>Decisão:</strong> Escolha uma biblioteca de componentes UI desde o início e continue com ela. Você pode mudar tudo depois, <strong>se necessário</strong>.</p>

<h2 id="decisões-de-ferramentas">Decisões de Ferramentas</h2>

<p>Decidi evitar usar um banco de dados no início, até descobrir que tipo de dados quero armazenar e como quero armazená-los.</p>

<p>Elixir (minha linguagem preferida) tem algo que faz o trabalho muito bem: GenServers. Posso usá-los para armazenar dados temporariamente sem precisar recorrer a um banco de dados. A informação estará lá até que uma de três coisas aconteça:</p>

<ul>
  <li>
    <p>Eu reinicie o servidor</p>
  </li>
  <li>
    <p>Um erro ocorra e o GenServer seja reiniciado</p>
  </li>
  <li>
    <p>Eu termine o GenServer</p>
  </li>
</ul>

<p>Essa abordagem me permitiu mover mais rápido e esquecer migrações, por exemplo.</p>

<p><strong>Mas, mas… Mario! Não é arriscado?</strong></p>

<p>Risco depende do contexto. Minhas sessões de treinamento são curtas, e no pior cenário eu perderia cerca de 15 minutos de tempo e os estudantes teriam que reiniciar um exercício se um GenServer falhar durante o treinamento.</p>

<p>Então, é um risco que estou <strong>conscientemente</strong> disposto a assumir.</p>

<h2 id="falando-em-falhas">Falando em falhas…</h2>

<p>Não posso dizer que estou fazendo TDD puro, mas estou escrevendo muitos testes. Especialmente porque estou usando Claude para gerar alguns pedaços de código para mim (vou escrever depois sobre <strong>quais</strong> pedaços de código o Claude está escrevendo para mim).</p>

<p>É muito difícil usar TDD com um LLM. Esses modelos geram pedaços enormes de código de uma vez. Enquanto isso, TDD é todo sobre aquele ritmo incremental: um teste, faz passar, e depois ataca o próximo. O que estou fazendo é escrever testes para meus GenServers, pedir ao Claude para sugerir testes extras que eu possa ter esquecido e então pedir ao Claude para implementar as funções que fariam os testes passar.</p>

<p>Aprendi que testes agora são <strong>muito mais importantes do que eram antes da IA</strong>. Quando um LLM faz dezenas de mudanças no seu código, é impossível para você garantir que seu código ainda faz o que deveria fazer. E o Claude quebrou meus testes mais vezes do que eu consigo contar, especialmente quando tentou modificar muitos arquivos de uma vez.</p>

<p><strong>Decisão:</strong> Usar IA como copiloto aumenta a necessidade de testes automatizados. E a IA também pode te ajudar a escrever seus testes.</p>

<h2 id="decisões-de-design">Decisões de Design</h2>

<p>Adquiri o <a href="https://tailwindcss.com/plus">tailwindui</a> há muito tempo e gosto de usar seus blocos de construção para criar minhas aplicações. Posso usá-lo para deixar meu produto bonito sem gastar muito tempo refinando demais meu design.</p>

<p>Claro, sendo um não-designer eu também tenho dificuldades com o layout geral. Mesmo tendo blocos bonitos para trabalhar, ainda sou bem capaz de bagunçar tudo quando os junto. Então, às vezes uso <a href="https://lovable.dev">Lovable</a> para entender melhores formas de visualizar como os componentes poderiam ficar juntos.</p>

<p><strong>Decisão:</strong> Tente adiar ter um banco de dados. Pense em diferentes formas de fazer isso para que você possa aprender mais sobre seus dados antes de se comprometer com uma estrutura de modelo.</p>

<h2 id="mecanismo-de-autenticação">Mecanismo de Autenticação</h2>

<p>Quando estou em uma sessão de treinamento, não quero que meus estudantes criem contas e lembrem senhas para uma experiência que vai durar 2 ou 3 dias. Também não quero gastar tempo mexendo com um mecanismo de autenticação.</p>

<p>Agora, sei que alguns de vocês estão pensando: “<em>Ei Mario, é 2025! Você pode configurar um mecanismo de autenticação em alguns minutos</em>”. Talvez sim, talvez não. Mas tenho certeza de que ter um mecanismo completo de autenticação instantaneamente adicionaria pelo menos um pouco de complexidade a tudo mais que quero desenvolver.</p>

<p>Então meu mecanismo funciona assim:</p>

<p>Você me diz seu nome, eu salvo na sua sessão e pronto. A não ser que você seja o instrutor, é claro. Então tudo que você tem que fazer é digitar seu nome como <strong>SUPER_SECRET_PASSWORD</strong> e você terá acesso a funcionalidades avançadas.</p>

<p>É seguro? Não.</p>

<p>É bom o suficiente para usar em uma aula com 20 pessoas? Definitivamente sim.</p>

<p><strong>Decisão:</strong> Autenticação vem no último momento responsável. Pense nisso, trabalhe em volta disso e talvez você acabe criando algo inovador.</p>

<h2 id="deploy">Deploy</h2>

<p>Recentemente li o incrível livro Simplicity do <a href="https://articles.pragdave.me">Dave Thomas</a>, e há muitas boas ideias lá. Uma que particularmente gosto é: <strong>automatize seu deploy desde o dia zero</strong>, para que você possa fazer deploy frequentemente.</p>

<p>Fiz isso usando github workflows e minha dedibox na <a href="https://www.scaleway.com/en/">Scaleway</a>. Agora faço deploy fazendo apenas um simples:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git push origin deploy
</code></pre></div></div>

<p>E claro, o deploy ocorre apenas se todos os meus testes passarem. Coisas bem básicas, eu sei. Mas fazer isso desde o dia um me permite fazer deploy frequentemente e coletar feedback rapidamente.</p>

<p><strong>Decisão:</strong> Crie um hello world, faça deploy e automatize todo o processo de deployment antes de fazer qualquer outra coisa.</p>

<h2 id="considerações-finais">Considerações Finais</h2>

<p>Um bom projeto pessoal é um projeto pessoal que você pode rapidamente fazer deploy e ter outras pessoas usando. No meu caso, como instrutor, a ideia de criar uma plataforma para simular coisas da vida real durante sessões de treinamento parece ser um fit perfeito.</p>

<p>Vou revisitar algumas dessas decisões? <strong>CLARO!</strong> Essa é toda a ideia por trás de cada uma dessas decisões. Um dia vou ter um mecanismo de autenticação adequado e um banco de dados, mas quando esse dia chegar vou ter uma razão para implementar essas coisas.</p>

<p>Como Jaqen de Game of Thrones diria:</p>

<blockquote>
  <p>O que dizemos para nossa necessidade de implementar autenticação em nossos produtos? <strong>Hoje não.</strong></p>
</blockquote>
]]>
    </content>
    <author>
      <name>Mario Melo</name>
    </author>
    
    <category term="Building" />
    
    <category term="Product" />
    
    <summary type="html">Como qualquer desenvolvedor por aí, eu adoro começar projetos pessoais.</summary>
  </entry>
  
  <entry xml:lang="pt">
    <title type="html">Linguagem importa: Uma demo não é uma review</title>
    <link href="https://mariomelo.com/linguagem-importa-uma-demo-nao-e-uma-review" rel="alternate" type="text/html" title="Linguagem importa: Uma demo não é uma review" />
    <published>2025-02-27T14:13:07+00:00</published>
    <updated>2025-02-27T14:13:07+00:00</updated>
    <id>https://mariomelo.com/linguagem-importa-uma-demo-nao-e-uma-review</id>
    <content type="html" xml:base="https://mariomelo.com/linguagem-importa-uma-demo-nao-e-uma-review">
      <![CDATA[<p>Eu me lembro de quando fui apresentado pela primeira vez à semiótica durante o Cynefin Virtual Basecamp naqueles tempos de pandemia. Eu fiquei meio perdido, aprendi bastante, mas na época o assunto parecia abstrato e viajado demais, daí acabou não me atraindo tanto. Mas… aquele evento despertou em mim alguma curiosidade sobre o tema que só cresceu desde então.</p>

<p>Acontece que a <strong>linguagem</strong> é provavelmente um dos tópicos mais impressionantes que encontrei desde que comecei a estudar filosofia, e é um caminho completamente sem volta: uma vez que você começa a pensar sobre o significado das palavras e símbolos, nunca mais volta atrás. Tanto que quando me deparei com o último post do Kent Beck (link abaixo), comecei automaticamente a refletir sobre a palavra <strong>demo</strong>.</p>

<p><a href="https://tidyfirst.substack.com/p/the-threat-of-incremental-delivery?utm_source=substack&amp;utm_campaign=post_embed&amp;utm_medium=web">Software Design: Tidy First - The Threat of Incremental Delivery</a></p>

<p>Então, vou tentar explorar um pouco o significado de duas palavras que frequentemente usamos no desenvolvimento de software: <strong>demo</strong> e <strong>review</strong>.</p>

<p>Prometo não viajar muito!</p>

<h2 id="o-que-é-um-demo-resposta-1">O que é um “demo”? Resposta 1:</h2>

<p>Como alguém que gosta de videogames, lembro-me de jogar muitos demos quando era mais jovem. Os demos eram basicamente uma versão do jogo com recursos limitados, como uma única fase, e havia inúmeras revistas (como a CD Expert!) que vinham com um CD-ROM contendo dezenas de demos para que você pudesse ter uma pequena amostra de um jogo antes de tomar a decisão de gastar seu dinheiro para comprar a versão completa. Os demos ainda existem e estão por aí, só não vêm mais em CD-ROMs.</p>

<p><img src="../assets/images/posts/183e7a75fc6e.jpeg" alt="Image" /><em>Um demo funciona como um “aperitivo” para convencer as pessoas a comprar o produto</em></p>

<p>Então, um <strong>demo</strong> é sempre uma <strong>demonstração</strong> de algo que <strong>já está feito</strong>. Seu propósito é permitir que as pessoas testem algo antes de responder a uma pergunta simples: <strong>isso vale meu dinheiro?</strong> Do lado dos desenvolvedores, eles estão tentando <strong>demonstrar</strong> que a resposta deveria ser um sonoro “SIM!”.</p>

<p>E é por isso que não gosto de usar a palavra <strong>demo</strong> em cenários onde o cliente <strong>já está comprometido com o desenvolvimento do produto</strong>. Eles já investiram dinheiro ali, então… qual é o propósito de oferecer a eles uma <strong>demonstração</strong>?</p>

<h2 id="o-que-mais-é-um-demo-resposta-2">O que mais é um “demo”? Resposta 2:</h2>

<p>A palavra <strong>demo</strong> poderia ter um significado diferente. Especialmente em ambientes de baixa confiança, onde o cliente precisa de alguma <strong>prova de progresso</strong>. Alguma forma de validar que o que está sendo produzido pela equipe é <strong>100% coerente</strong> com a especificação inicial.</p>

<p><em>Aqui cliente, se você clicar aqui, uma janela popup se abre e uma mensagem de erro é mostrada, Q.E.D.</em></p>

<p>Q.E.D - <em>quod erat demonstrandum</em> , ou C.Q.D - <em>Como queríamos demonstrar</em>.</p>

<p>Desta vez, estamos usando uma <strong>demonstração</strong> para <strong>provar algo</strong>. Para mostrar ao cliente que estamos trabalhando desde nossa última reunião e que o progresso que fizemos <strong>corresponde às expectativas iniciais</strong>.</p>

<p>Esse significado pode funcionar melhor para algumas equipes de desenvolvimento de software, mas ainda tem um problema: <strong>uma demonstração não é sobre coletar feedback.</strong></p>

<h1 id="e-quanto-a-um-review">E quanto a um “review”?</h1>

<p>Re-view. Re-ver. Ver novamente. Funciona?</p>

<p>“<em>Vamos olhar para o software que estamos produzindo mais uma vez e verificar se estamos indo para o destino correto</em>.”</p>

<p>Isso parece bom. Mas ao mesmo tempo penso em quando minha bicicleta passa por uma revisão de segurança:</p>

<p>“<em>Temos uma lista de verificação predefinida, e vamos verificar cada item para garantir que tudo esteja de acordo com os padrões.</em>”</p>

<p>Aí não, já não funciona tão bem.</p>

<p>“<strong>Review</strong>” não é minha palavra preferida para o contexto de desenvolvimento de softwares complexos, mas é muito melhor que <strong>demo</strong>. Pelo menos existe a possibilidade de transmitirmos a mensagem correta aqui.</p>

<h1 id="quais-outras-palavras-poderíamos-usar">Quais outras palavras poderíamos usar?</h1>

<p>Não existe uma palavra perfeita para usar. Mas se olharmos para o framework Scrum, por exemplo: o nome <strong>Sprint Retrospective</strong> faz todo sentido para mim. O nome <strong>Sprint Review</strong> não. Estamos <strong>revisando</strong> <strong>a</strong> <strong>Sprint</strong>? Que tipo de <strong>review</strong> estamos fazendo?</p>

<p>Essa conversa me lembra de quando eu estava planejando meu casamento e tivemos que experimentar todos os salgadinhos chiques, os doces e o bolo (Ô tarefa boa!). Nós os experimentávamos e fornecíamos feedback. Não era uma simples degustação, porque os nossos comentários sobre a comida eram usados para adaptar o que seria servido na festa. Essa experiência está muito mais alinhada com o que as equipes de desenvolvimento de software estão realmente tentando (ou deveriam estar) fazer em um Sprint Review.</p>

<p>Então, se eu fosse renomear o Sprint Review, eu chamaria algo como “<strong>Experimentação do Incremento</strong>” ou “<strong>Experimentação do Produto</strong>”.</p>

<p>Assim falamos do que foi produzido (incrementos) e não do processo de produção (Sprint). E uma experimentação é sobre empirismo, torna mais explícita a necessidade da participação ativa do cliente.</p>

<p>É perfeito? Bem… não. Mas:</p>

<blockquote>
  <p><em>Toda palavra é um preconceito</em></p>

  <p><cite>- Nietzsche</cite></p>
</blockquote>

<p>PS: Se você gosta deste tipo de assunto, provavelmente vai gostar de passar meia hora ouvindo este episódio de <a href="https://www.philosophizethis.org/podcast/episode-178-susan-sontag?rq=178">Philosophize This! - Episode 178: Susan Sontag on Metaphors</a>. Embora esteja em inglês, é possível ver a transcrição neste link e aí fica fácil traduzir com o auxílio de qualquer navegador ou LLM.</p>
]]>
    </content>
    <author>
      <name>Mario Melo</name>
    </author>
    
    <category term="Teamwork" />
    
    <category term="Scrum" />
    
    <summary type="html">Eu me lembro de quando fui apresentado pela primeira vez à semiótica durante o Cynefin Virtual Basecamp naqueles tempos de pandemia.</summary>
  </entry>
  
  <entry xml:lang="pt">
    <title type="html">Empirismo e racionalismo no desenvolvimento de software</title>
    <link href="https://mariomelo.com/empirismo-e-racionalismo-no-desenvolvimento" rel="alternate" type="text/html" title="Empirismo e racionalismo no desenvolvimento de software" />
    <published>2025-02-06T16:54:51+00:00</published>
    <updated>2025-02-06T16:54:51+00:00</updated>
    <id>https://mariomelo.com/empirismo-e-racionalismo-no-desenvolvimento</id>
    <content type="html" xml:base="https://mariomelo.com/empirismo-e-racionalismo-no-desenvolvimento">
      <![CDATA[<h2 id="mas-de-onde-saiu-esse-post">Mas de onde saiu esse post?</h2>

<p>Antes de mais nada, um esclarecimento: não, eu não estou sob efeito de entorpecentes. Mas recentemente comecei a estudar filosofia e tomei gosto pela coisa. E enquanto eu estudava minha cabeça não parava de conectar conceitos e questionamentos filosóficos com técnicas e comportamentos que estamos habituados a ver no mundo do desenvolvimento de software. Fiz logo uma lista sobre possíveis posts que gostaria de escrever, então esse aqui definitivamente não será o último post sobre filosofia e desenvolvimento.</p>

<p>Ou seja… esse post viajado não será o último post nessa linha. :)</p>

<h2 id="descartes-era-uns-50-ágil">Descartes era uns 50% ágil</h2>

<p>Descartes enfrentando a realidade do desenvolvimento de software moderno: nem sempre nossas ideias “claras e distintas” passam nos testes unitários.</p>

<p>Descartes era um <strong>racionalista</strong> , o que significa que ele acreditava que a melhor forma de encontrar a verdade era através do pensamento. Algo que poderia nos fazer pensar nele como um gerente de projetos tradicional, sentado em sua mesa pensando em cada detalhe do plano que devemos seguir para desenvolver nosso produto.</p>

<p>Mas pensar nele dessa forma não seria justo, porque afinal em seu método cartesiano podemos encontrar idéias muito similares àquilo que praticamos no desenvolvimento ágil de software:</p>

<ul>
  <li>
    <p>Quebrar problemas grandes em problemas menores</p>
  </li>
  <li>
    <p>Ordenar os problemas e resolver os mais simples primeiro</p>
  </li>
</ul>

<p>Dá até pra imaginar ele escrevendo testes unitários e quebrando itens do Product Backlog, né? Mas tem um problema: Descartes acreditava que poderíamos alcançar idéias “<strong>claras, objetivas e imutáveis</strong>”, e que poderíamos usá-las como blocos de LEGO para construir outras idéias maiores.</p>

<p>É como se ele fosse a favor de escrever testes unitários em um primeiro momento para dar <strong>clareza e objetividade</strong> , mas deixasse de enxergar valor em manter esses testes no repositório depois que as funções fossem implementadas porque aquela idéia já foi validada e consolidada.</p>

<p>Ou seja: Descartes buscava uma <strong>verdade imutável</strong>, mas o processo para chegar até essas verdades era <strong>iterativo</strong>.</p>

<p>Mas se Descartes estava parcialmente certo sobre método, onde ele se perdeu? É aí que entra David Hume com uma ideia revolucionária: e se a experiência for mais importante que o raciocínio puro?</p>

<h2 id="hume-teria-sido-um-ótimo-scrum-master">Hume teria sido um ótimo Scrum Master</h2>

<p><img src="../assets/images/posts/c6e6e222962e.jpeg" alt="Image" /><em>Hume planejando seus experimentos em produção</em></p>

<p>David Hume teve a vantagem de nascer uns 120 anos depois de Descartes e com isso ter mais material para estudar e explorar. Ele argumentava que o conhecimento real só pode ser obtido através da experiência, e que apenas sentar e refletir ou estudar não nos geraria nenhum novo <strong>fato</strong>, e sim meras <strong>especulações</strong>.</p>

<p>Mas mesmo sendo um fã inveterado de experimentos ele sabia reconhecer suas limitações:</p>

<blockquote>
  <p>Embora a experiência seja nosso único guia no raciocínio sobre questões de fato, deve-se reconhecer que este guia não é totalmente infalível e que, em alguns casos, pode conduzir-nos a erros</p>

  <p><cite>- David Hume</cite></p>
</blockquote>

<p>Através desse pensamento ele levantou alguns problemas (e refletiu sobre outros que já haviam sido previamente levantados por outros filósofos) que são facilmente reconhecíveis no mundo do desenvolvimento de software:</p>

<ol>
  <li>
    <p><strong>O problema da indução:</strong> A experiência passada não garante a repetição de resultados futuros. Popularmente conhecido como: se funciona na minha máquina, funciona no servidor.</p>
  </li>
  <li>
    <p><strong>O problema da causalidade:</strong> Só porque um evento A ocorreu seguido de um evento B não significa que um causou o outro. Popularmente conhecido como: para replicar o bug que o cliente encontrou basta seguir estes passos aqui.</p>
  </li>
  <li>
    <p><strong>A falibilidade do experimento:</strong> um experimento sempre pode falhar ou nos levar a conclusões erradas. Popularmente conhecido como: se cobrirmos 100% do código com testes nunca mais vamos ter bugs.</p>
  </li>
</ol>

<p>É como diria Sílvio Santos e seu auditório: <strong>Eu só acredito… VENDO!</strong></p>

<p>Essa máxima é o que deveria reger equipes Scrum por todo o mundo, já que o framework tem o Empirismo como parte de seu alicerce. Se David Hume fosse um Scrum Master e visse equipes que fazem Sprint Reviews com apresentações de slides ou Dailies que são basicamente um Status Report ele definitivamente não ficaria parado assistindo.</p>

<p>Se Hume fosse Scrum Master hoje, ele provavelmente:</p>

<ul>
  <li>
    <p>Insistiria em demonstrações de software funcionando</p>
  </li>
  <li>
    <p>Priorizaria métricas reais sobre estimativas teóricas</p>
  </li>
  <li>
    <p>Questionaria qualquer “verdade absoluta” sobre processos</p>
  </li>
</ul>

<h2 id="legal-mas-dá-pra-concluir-alguma-coisa-útil-sobre-isso-tudo">Legal… mas dá pra concluir alguma coisa útil sobre isso tudo?</h2>

<p>Bem, primeiramente eu não sou especialista em filosofia e tomei o máximo de cuidado pra não cometer nenhum crime ao mencionar esses filósofos e seus pensamentos. Estou confortável com o meu entendimento sobre o tema, e acredito que este tipo de entendimento mais profundo sobre o porquê das coisas sempre nos leva a questionar comportamentos mecânicos e estar mais <strong>conscientes</strong> sobre aquilo que praticamos no dia a dia.</p>

<p>Acho que escrever me faz absorver melhor os temas que estudo, e mesmo que ninguém leia acaba tendo valor pra mim.</p>

<p>Por exemplo, podemos concluir que o <strong>contexto importa</strong>. Descartes provavelmente escreveria testes unitários para validar a lógica de construção do nosso produto, enquanto Hume pensaria em testes de aceitação para avaliar o comportamento do cliente ao usar o produto. Ambas as abordagens têm um valor que pode ser maior ou menor de acordo com o contexto em que são aplicadas.</p>

<p>Se Descartes e Hume decidissem fazer pair programming hoje, provavelmente criariam o <strong>DevOps</strong>.</p>

<p>Descartes contribuiria com:</p>

<ul>
  <li>
    <p>Infraestrutura como código (afinal, precisa ser clara e objetiva)</p>
  </li>
  <li>
    <p>Pipeline de CI/CD (ordem e método em ação)</p>
  </li>
  <li>
    <p>Testes automatizados (validando verdades fundamentais)</p>
  </li>
</ul>

<p>Já Hume insistiria em:</p>

<ul>
  <li>
    <p>Monitoramento constante (porque a experiência importa e falhas acontecem)</p>
  </li>
  <li>
    <p>Feature flags (para validar hipóteses em produção)</p>
  </li>
  <li>
    <p>Cultura de blameless postmortem (aprender com os erros e tratá-los como parte natural do processo)</p>
  </li>
</ul>

<p>Além disso, se entendermos cada prática cotidiana como um experimento que pode falhar podemos começar se atingimos resultados satisfatórios em cada um destes experimentos:</p>

<ul>
  <li>
    <p>Por que fazemos reuniões diárias?</p>
  </li>
  <li>
    <p>Por que fazemos Sprint Reviews?</p>
  </li>
  <li>
    <p>Como posso mensurar o valor que uma determinada prática traz para meu time?</p>
  </li>
</ul>

<p>E dessa forma começamos a fazer nosso trabalho com mais <strong>consciência</strong>, levando sempre em consideração a <strong>intenção</strong> de cada passo.</p>

<h3 id="se-interessou-bom-aí-vão-minhas-recomendações">Se interessou? Bom, aí vão minhas recomendações:</h3>

<p>Eu comecei a aprender mais filosofia através do Estoicismo, e o <strong>Diário Estoico</strong> de Ryan Holiday é um livro que estou relendo pela terceira vez e portanto não canso de recomendá-lo. Se o estoicismo de agradar, toda a obra de Seneca pode ser interessante para você, e eu recomendo começar com “<strong>Sobre a tranquilidade da alma</strong> ”.</p>

<p>Outros livros que ajudam a tornar as palavras rebuscadas dos filósofos um pouco mais palatáveis e que gostei bastante foram:</p>

<ul>
  <li>
    <p>Ser livre com Sartre (meu favorito desta série!)</p>
  </li>
  <li>
    <p>Viver apaixonadamente com Kierkegaard</p>
  </li>
  <li>
    <p>Afirmar-se com Nietzsche</p>
  </li>
  <li>
    <p>Desapegar-se com Schopenhauer</p>
  </li>
</ul>

<p>Estes livros não foram escritos pelos filósofos, mas por professores de filosofia que traduzem os pensamentos para os dias atuais através de metáforas e perguntas para você começar a se questionar.</p>

]]>
    </content>
    <author>
      <name>Mario Melo</name>
    </author>
    
    <category term="Coding" />
    
    <category term="Philosophy" />
    
    <summary type="html">Mas de onde saiu esse post?</summary>
  </entry>
  
  <entry xml:lang="pt">
    <title type="html">O advento do TDD: Um guia para iniciantes</title>
    <link href="https://mariomelo.com/o-advento-do-tdd-um-guia-para-iniciantes" rel="alternate" type="text/html" title="O advento do TDD: Um guia para iniciantes" />
    <published>2025-01-14T17:22:21+00:00</published>
    <updated>2025-01-14T17:22:21+00:00</updated>
    <id>https://mariomelo.com/o-advento-do-tdd-um-guia-para-iniciantes</id>
    <content type="html" xml:base="https://mariomelo.com/o-advento-do-tdd-um-guia-para-iniciantes">
      <![CDATA[<h2 id="começando-com-test-driven-development">Começando com Test-Driven Development</h2>

<p>“Como posso começar a aplicar Test-Driven Development?” Essa pergunta ecoa nas minhas sessões de treinamento como uma chamada de função recursiva. Embora minha resposta padrão sempre tenha sido <em>“Comece corrigindo bugs,”</em> descobri uma abordagem ainda mais envolvente: <strong>Advent of Code</strong>.</p>

<h2 id="minha-abordagem-padrão-corrigindo-um-bug-existente">Minha abordagem padrão: corrigindo um bug existente</h2>

<p>Vamos examinar um exemplo simples. Imagine que você tem uma função de calculadora:</p>

<p>Quando alguém tenta dividir por zero, nossa aplicação quebra <strong>sem cerimônia</strong>. Isso apresenta uma oportunidade perfeita para TDD – podemos escrever um teste expressando nosso <strong>comportamento desejado</strong>:</p>

<p><img src="../assets/images/posts/0dbccba9581c.png" alt="Código de teste para cenário de divisão por zero" /></p>

<p>Meu teste vai falhar, é claro, porque meu código falha. Agora posso corrigir meu código e fazer meu teste passar.</p>

<h2 id="a-abordagem-gamificada-advent-of-code">A Abordagem Gamificada: Advent of Code</h2>

<p>Como um autoproclamado geek com afinidade por puzzles, descobri que o <a href="https://adventofcode.com">Advent of Code</a> é o terreno de treinamento perfeito para TDD. Cada puzzle fornece:</p>

<ul>
  <li>
    <p>Uma amostra de entrada</p>
  </li>
  <li>
    <p>Uma saída esperada</p>
  </li>
</ul>

<p>Essa estrutura naturalmente te guia para a mentalidade de TDD – você escreve seu teste baseado no exemplo antes de implementar sua solução. É como ter uma <strong>especificação embutida</strong>!</p>

<p><img src="../assets/images/posts/980611310d5a.png" alt="Exemplo do Advent of Code mostrando entrada e saída esperada" /></p>

<p>Quer dizer, não só é uma boa forma de aprender TDD, mas também é divertido. Você está aprimorando suas habilidades de desenvolvimento, resolvendo um puzzle e praticando uma técnica muito valiosa.</p>

<p>Conforme você avança pelos desafios, pode começar a experimentar mais com TDD e talvez reduzir a granularidade de alguns dos seus testes. Por exemplo, você pode precisar fazer o parse de uma entrada de texto complexa em um Map para resolver o problema, e então isso poderia ser um teste por si só.</p>

<h2 id="ferramentas-que-melhoram-a-experiência">Ferramentas Que Melhoram a Experiência</h2>

<p>Em Elixir (minha linguagem preferida), o <strong>operador pipe</strong> (<code class="language-plaintext highlighter-rouge">|&gt;</code>) é particularmente poderoso para TDD:</p>

<p><img src="../assets/images/posts/ad2c4c517ce0.png" alt="Exemplo de código com operador pipe em Elixir" /></p>

<p>Aquele pequeno triângulo basicamente diz: <em>pegue a saída da função acima e passe para a função seguinte.</em> Essa sintaxe elegante permite que você esboce o fluxo de alto nível da sua solução antes de mergulhar nos detalhes de implementação.</p>

<p>Combine isso com ferramentas como <code class="language-plaintext highlighter-rouge">mix test.watch</code>, que automaticamente executa os testes quando arquivos mudam, e você tem um ciclo de feedback rápido que faz o TDD parecer natural e intuitivo.</p>

<h3 id="pronto-para-começar">Pronto para Começar?</h3>

<p>Escolha sua linguagem de programação preferida e mergulhe! Você pode explorar meu repositório do Advent of Code 2024 para inspiração:</p>

<p><a href="https://github.com/mariomelo/advent_of_code24">https://github.com/mariomelo/advent_of_code24</a></p>

<p>Lembre-se: O objetivo não é perfeição, mas prática. Cada puzzle é uma oportunidade de fortalecer seus músculos de TDD enquanto se diverte!</p>

<p><em>Para insights mais profundos sobre TDD, confira o excelente artigo sobre Software Design: Tidy First?</em></p>

<p><a href="https://tidyfirst.substack.com/p/canon-tdd?utm_source=substack&amp;utm_campaign=post_embed&amp;utm_medium=web"> Software Design: Tidy First? - Canon TDD</a></p>

<p>Bom código!</p>
]]>
    </content>
    <author>
      <name>Mario Melo</name>
    </author>
    
    <category term="Coding" />
    
    <category term="Testing" />
    
    <summary type="html">Começando com Test-Driven Development</summary>
  </entry>
  
  <entry xml:lang="pt">
    <title type="html">Os 3 vieses do desenvolvimento de software, parte 3: Modularidade</title>
    <link href="https://mariomelo.com/os-3-vieses-do-desenvolvimento-de-software-parte-3-modularidade" rel="alternate" type="text/html" title="Os 3 vieses do desenvolvimento de software, parte 3: Modularidade" />
    <published>2024-12-04T11:11:18+00:00</published>
    <updated>2024-12-04T11:11:18+00:00</updated>
    <id>https://mariomelo.com/os-3-vieses-do-desenvolvimento-de-software-parte-3-modularidade</id>
    <content type="html" xml:base="https://mariomelo.com/os-3-vieses-do-desenvolvimento-de-software-parte-3-modularidade">
      <![CDATA[<h2 id="o-que-é-o-viés-da-modularidade">O que é o viés da Modularidade?</h2>

<p>Até agora falamos sobre <strong>Estratificação</strong> e <strong>Cronologia</strong>, e passamos da “abordagem Mario Bros” onde sempre desenvolvemos a fase 1-1 antes da fase 1-2 para a “abordagem Megaman”, onde temos mais flexibilidade e podemos desenvolver nossos módulos em qualquer ordem.</p>

<p>Você percebeu que eu acabei de usar a palavra “<strong>módulos</strong>”? Esse é o problema que vamos abordar neste post: se consideramos que uma determinada parte do nosso software está pronta, isso significa que essa parte não é mais flexível. Se Estratificação é sobre <strong>camadas</strong> e Cronologia é sobre <strong>sequência</strong> , Modularidade é sobre as caixas onde colocamos nosso código - e às vezes, essas caixas se tornam prisões.</p>

<h2 id="entendendo-o-viés-da-modularidade">Entendendo o viés da Modularidade</h2>

<p>Quando você derrota um chefe no Megaman, você ganha acesso a uma nova arma. Uma arma completa e funcional, mas também uma arma que nunca mudará. No desenvolvimento de software, no entanto, se tentarmos finalizar uma parte do nosso software e declarar que nunca mais tocaremos naquela área do código… Bom, digamos que simplesmente não funciona assim. Foi mal, Megaman.</p>

<p>Então, qual jogo poderíamos usar como analogia para melhorar a abordagem do MegaMan? Planescape: Torment! (Ou qualquer outro RPG clássico, na verdade).</p>

<p><img src="../assets/images/posts/7ad65250cea2.png" alt="planescape.png" /></p>

<p>Em Planescape, cada vez que você acumula experiência suficiente pode melhorar seu personagem adicionando pontos à sua Força, Sabedoria, Inteligência, Destreza, Carisma e Constituição. Você melhora gradualmente essas estatísticas, mas nunca <strong>completa</strong> nenhuma delas: você sempre pode adicionar mais pontos a uma determinada estatística durante seu próximo “ciclo de evolução”.</p>

<p>Pense no Megaman: quando você começa a jogar, pode escolher uma das 8 fases para jogar. Mas cada vez que você vence uma fase, tem menos opções sobre o que jogar em seguida, até chegar a um ponto onde não terá escolha porque já venceu 7 fases e só resta uma. Você começa flexível, mas perde essa flexibilidade ao longo do caminho.</p>

<p><img src="../assets/images/posts/f29db3600f80.png" alt="Captura de Tela 2024-11-26 às 16.41.30.png" /></p>

<p>Em Planescape não adquirimos novos “<strong>módulos</strong>” para nosso personagem; melhoramos suas características de acordo com nossas necessidades, e nossas necessidades mudam conforme avançamos no jogo.</p>

<h2 id="chega-de-jogos-vamos-falar-de-software">Chega de jogos. Vamos falar de software!</h2>

<p>Bem, tecnicamente esses jogos também são software, mas eu entendi o ponto. :)</p>

<p>Vamos voltar ao exemplo que tínhamos no nosso último artigo: um jogo da Forca. Ao quebrar o viés da Cronologia, decidimos adiar o desenvolvimento de um “Módulo de Dicionário” implementando apenas uma função que sempre retorna a mesma palavra: <strong>ELEFANTE</strong>.</p>

<p><img src="../assets/images/posts/436f8105a745.webp" alt="b8089ce3-1a92-4b29-8fbe-6c27303befb3_789x194.webp" /></p>

<p>Ao fazer isso, conseguimos focar em coisas mais interessantes como o mecanismo do jogo sem gastar muito tempo com o dicionário. Se pensarmos no nosso próximo passo, alguém poderia dizer que poderíamos finalizar o dicionário real em seguida e dar ao nosso Megaman uma nova arma. Mas ao fazer isso, prejudicaríamos nossa capacidade de adaptar ao feedback do cliente, pois reduzimos a quantidade de possibilidades que poderíamos desenvolver no futuro.</p>

<p>A menos que estejamos dispostos a descartar parte do nosso trabalho e refazê-lo de acordo com o feedback que recebemos, é claro. Na verdade, não é um crime fazer isso, mas esse tipo de desperdício pode ser drasticamente minimizado se, em vez de implementar o Dicionário, nos fizermos a seguinte pergunta:</p>

<p><em><strong>Como poderíamos adicionar um único ponto de melhoria em nosso Dicionário, como no jogo Planescape?</strong></em></p>

<p>Talvez pudéssemos criar uma lista de palavras e escolher uma palavra aleatória cada vez que a função <code class="language-plaintext highlighter-rouge">get_word</code> é chamada. Isso é simples, poderia ser feito em alguns minutos e melhoraria muito o jogo.</p>

<p><img src="../assets/images/posts/a051804e0114.png" alt="Captura de Tela 2024-11-26 às 17.51.47.png" /></p>

<p>Observe que não implementamos a integração com a API mostrada inicialmente em nosso último post, mas podemos fazer isso no futuro se acharmos que é uma boa ideia.</p>

<p><strong>Ou não.</strong></p>

<h2 id="benefícios-de-quebrar-o-viés-da-modularidade">Benefícios de quebrar o viés da Modularidade</h2>

<p>Digamos que você está desenvolvendo aquele jogo da Forca usando a abordagem MegaMan e faz parte de um Time Scrum. Durante a Sprint Review, você mostra ao seu cliente o que construiu e pede feedback:</p>

<p><em><strong>Então cliente, terminamos a Interface e o Dicionário. O que você acha que devemos fazer em seguida?</strong></em></p>

<p><img src="../assets/images/posts/56af0e0babed.png" alt="Image" /></p>

<p>Bem, qual é o sentido de pedir feedback aqui? Se o cliente nos pedir para mudar algo relacionado ao Dicionário ou à Interface, desperdiçaremos muito do trabalho que fizemos, e se eles limitarem seu feedback às áreas restantes do software, não estamos nos beneficiando de todo o propósito do Scrum.</p>

<p>Agora, imagine você com a abordagem Planescape. O time melhorou nosso Dicionário e nossa Interface, mas ao invés de finalizá-los, usamos o tempo restante para criar um Sistema de Pontuação simples:</p>

<p><img src="../assets/images/posts/0189eca16007.png" alt="Image" /></p>

<p>Neste cenário, você poderia fazer ao seu cliente uma pergunta diferente durante a Sprint Review, como:</p>

<p><strong>Então cliente, baseado no que você viu, onde deveríamos alocar nossos próximos 3 pontos de melhoria? E o que estamos tentando alcançar fazendo isso?</strong></p>

<p>Percebe a diferença? O cliente mantém suas opções e mesmo que nos peça para melhorar algo em que já trabalhamos, não jogamos trabalho fora. Pelo menos não tanto.</p>

<p>Além disso, talvez não precisemos implementar aquela integração com a API agora, já que o cliente decide aprimorar o Sistema de Pontuação e implementar um Mecanismo de Dicas. Enquanto isso, não teremos que nos preocupar com quantas chamadas de API estamos fazendo durante o processo de desenvolvimento, criar mocks e stubs para testar nosso jogo ou criar uma opção de configuração para tornar nosso jogo implantável em ambos os servidores de staging e produção.</p>

<p>O desperdício que minimizamos não está relacionado apenas ao feedback do cliente, <strong>mas a todo o processo de desenvolvimento</strong>.</p>

<p>Talvez nunca usemos aquela API. Na verdade, enquanto desenvolvia este Jogo da Forca para um curso de Certified Scrum Developer que eu estava dando, minha esposa jogou o jogo e teve uma ideia interessante: já que o curso era sobre Scrum, deveríamos usar palavras do Scrum Guide, e ao fazer isso acabamos com um dicionário estático que tinha 802 palavras diferentes. Todas relacionadas ao mesmo assunto: <strong>Scrum</strong>.</p>

<h2 id="como-podemos-evitar-esse-viés-da-modularidade">Como podemos evitar esse viés da Modularidade?</h2>

<p>Vou ser direto com esta resposta: Use o <strong>Método do Hambúrguer</strong>. Eu sei que poderia elaborar mais, mas na minha experiência não há melhor maneira de lidar com esse viés como time do que usar esse método. Você pode ler mais sobre esse método aqui:</p>

<p><a href="https://gojko.net/2012/01/23/splitting-user-stories-the-hamburger-method/">https://gojko.net/2012/01/23/splitting-user-stories-the-hamburger-method/</a>.</p>

<p>Também é uma ótima maneira de lidar com dependências, que frequentemente nos empurram em direção ao viés da <strong>Modularidade</strong>.</p>

<p>Ainda há mais uma coisa que precisamos abordar aqui: <strong>A abordagem Planescape: Torment nem mesmo é nosso destino final</strong>. Isso porque naquele jogo (que é sensacional, diga-se de passagem) sempre teremos as mesmas 6 estatísticas para melhorar nosso personagem. E se você realmente quebrar este viés da Modularidade, será capaz de <strong>descobrir novas áreas para explorar conforme avança</strong>.</p>

<h2 id="mário-você-fala-demais-este-post-está-muito-longo-poderia-resumir-por-favor">Mário, você fala demais. Este post está muito longo, poderia resumir, por favor?</h2>

<p>Sim! Antes de declarar qualquer parte do seu software como ‘completa’, lembre-se: até o personagem de RPG mais poderoso ainda pode evoluir.</p>

<p>Aqui você encontra os dois artigos anteriores sobre vieses:</p>
]]>
    </content>
    <author>
      <name>Mario Melo</name>
    </author>
    
    <category term="Coding" />
    
    <category term="Bias" />
    
    <summary type="html">O que é o viés da Modularidade?</summary>
  </entry>
  
  <entry xml:lang="pt">
    <title type="html">Os 3 vieses do desenvolvimento de software, parte 2: Cronologia</title>
    <link href="https://mariomelo.com/os-3-vieses-do-desenvolvimento-de-software-parte-2-cronologia" rel="alternate" type="text/html" title="Os 3 vieses do desenvolvimento de software, parte 2: Cronologia" />
    <published>2024-11-28T11:10:12+00:00</published>
    <updated>2024-11-28T11:10:12+00:00</updated>
    <id>https://mariomelo.com/os-3-vieses-do-desenvolvimento-de-software-parte-2-cronologia</id>
    <content type="html" xml:base="https://mariomelo.com/os-3-vieses-do-desenvolvimento-de-software-parte-2-cronologia">
      <![CDATA[<p>No meu último post, falei sobre como o hábito de dividir o software em camadas pode nos levar a trabalhar em uma camada de cada vez, produzindo o indesejado efeito BDUF (Big Design Upfront). Desta vez, vamos falar sobre como um fluxo imaginário do usuário pode nos levar a seguir cegamente um fluxo de desenvolvimento predefinido.</p>

<h2 id="entendendo-o-viés-da-cronologia">Entendendo o Viés da Cronologia</h2>

<p>Lembro da primeira vez que joguei Mario Bros no console NES que meu pai me deu quando eu tinha 4 anos: o controle retangular absurdamente não ergonômico, a alegria de jogar um jogo com um personagem que tinha o mesmo nome que eu… Foi incrível!</p>

<p>O jogo era muito linear: 8 mundos com 4 fases cada. Você começa na Fase 1-1 e termina o jogo depois de vencer a fase 8-4. Existiam atalhos que eu podia pegar para pular algumas fases, mas eu nunca podia voltar para jogar uma fase já terminada.</p>

<p>O mundo 1-1 do primeiro Mario Bros resumido em uma imagem</p>

<p>Desenvolver software sob um Viés de Cronologia é como jogar aquele jogo do Mario Bros, exceto que não é tão divertido. Você começa desenvolvendo o mundo 1-1 porque é o que o usuário jogará primeiro. Depois desenvolve o mundo 1-2, e assim por diante. Se seguirmos esse caminho, claramente não estamos caindo no <strong><a href="/blog/os-3-vieses-do-desenvolvimento-de-software-parte-1-estratificacao">Viés da Estratificação</a></strong>, porque estamos criando todas as camadas para cada fase (não estamos terminando o design de todos os níveis antes de implementar o mecanismo do jogo, por exemplo). Com isso poderíamos coletar feedback do cliente após desenvolver cada fase e usar isso para criar melhores fases no futuro. Mas ainda assim… estamos perdendo algumas boas oportunidades.</p>

<p>Sabe o que é engraçado? Essa progressão linear estilo Mario aparece em todo lugar no desenvolvimento de software. Pegue a tela de login, por exemplo - ela praticamente se tornou nossa “Fase 1-1”. É quase como se houvesse uma regra não escrita que diz “<em>Implementarás a autenticação primeiro</em>” só porque é a primeira coisa que os usuários veem. E na maioria das vezes, esta é a primeira coisa que uma equipe de desenvolvimento de software implementa quando começa a desenvolver um novo produto. Você já fez isso? Eu fiz, <strong>inúmeras vezes</strong>.</p>

<h2 id="mas-qual-é-o-problema-dessa-abordagem">Mas qual é o problema dessa abordagem?</h2>

<p>Problemas, eu diria. No plural.</p>

<p>O mais óbvio é que <strong>não estamos nos beneficiando totalmente de uma abordagem ágil se estamos seguindo um caminho predefinido</strong>. Depois de revisar a Fase 1-1, teremos alguma flexibilidade sobre como desenvolver a fase 1-2, mas não sobre o que devemos desenvolver em nossa próxima iteração. Além disso, todas as nossas conversas sobre o produto deixarão aquele gosto amargo de tempo perdido porque o caminho já está definido. Esse sentimento é bastante comum entre desenvolvedores em Times Scrum durante o Planning e a Review quando estão caindo neste viés.</p>

<p>E se a fase 6-2 for a mais valiosa para meu usuário? Eles terão que esperar <strong>26 iterações</strong> para finalmente poder jogá-la!</p>

<p>Outro problema será a mitigação de riscos. Se estou construindo um jogo do Mario, talvez eu tenha algumas ideias ousadas que quero validar primeiro, como um mundo aquático, um castelo com quebra-cabeças ou um chefe muito desafiador. Até mesmo o chefe final!</p>

<p>Então a solução parece direta: basta desenvolver recursos em qualquer ordem que forneça mais valor, certo? Poderíamos construir a fase 4-3 antes da fase 1-2, seguindo as prioridades do usuário em vez da ordem sequencial.</p>

<p>Bem… acontece que frequentemente esbarramos em um obstáculo familiar: dependências. Mas é aqui que outro clássico dos games nos oferece uma alternativa iluminadora…</p>

<h2 id="quebrando-o-viés-da-cronologia-e-as-dependências">Quebrando o Viés da Cronologia (e as dependências)</h2>

<p>Voltando à minha infância e meu console NES, havia um jogo que eu amava ainda mais que Mario Bros: <strong>MegaMan</strong>. Em todo jogo do MegaMan você podia selecionar qual fase queria jogar, e uma vez que você derrotava o chefe da fase, você ganhava acesso à sua arma e podia usá-la pelo resto do jogo.</p>

<p><img src="../assets/images/posts/e58894f2eea3.jpeg" alt="Image" /><em>Só de ver essa tela eu tenho vontade de jogar Megaman novamente!</em></p>

<p>Então, você podia escolher lutar contra o Fireman primeiro e usar sua arma de fogo contra o Iceman, ou o contrário. Depende de você. Não havia absolutamente nenhuma sequência predefinida. Mas… o que acontece se tentarmos usar a mesma abordagem no desenvolvimento de software? Bem, às vezes vamos ouvir e dizer coisas como:</p>

<p>“<strong>Não podemos desenvolver um relatório sem criar um CRUD para inserir os dados primeiro, afinal não existe relatório sem dados!</strong>”</p>

<p>Ok, vamos desafiar isso: <strong>Como poderíamos desenvolver um relatório sem ter uma interface para inserção de dados?</strong> Bem, mockando os dados. Imagine que vamos construir um jogo da Forca. Alguém poderia dizer que a primeira coisa que precisamos fazer é criar um dicionário de palavras que podemos usar durante o jogo, porque <strong>ter uma palavra para jogar é um pré-requisito</strong>!</p>

<p>Então, se cairmos nessa armadilha, provavelmente vamos gastar algum tempo desenvolvendo algo como:</p>

<p><img src="../assets/images/posts/2a14700e04ab.jpeg" alt="Image" /></p>

<p>Não parece muito, mas requereu algum tempo para pesquisar uma maneira de gerar uma palavra aleatória, ler a documentação da API, criar uma conta, obter uma chave de API, escrever o código, testá-lo e refatorá-lo um pouco. Mas o mecanismo do jogo é muito mais importante, e se pudéssemos economizar algum tempo aqui, poderíamos usar esse tempo para desenvolvê-lo melhor. E uma maneira de fazer isso é estabelecendo uma interface simples.</p>

<p>Quando eu chamo a função <code class="language-plaintext highlighter-rouge">get_word</code>, recebo uma palavra, e não me importo realmente de onde ela veio. Se fizermos isso, poderíamos criar nosso Dicionário assim:</p>

<p><img src="../assets/images/posts/7d3b4b82aafe.jpeg" alt="Image" /></p>

<p>Sim, a palavra sempre será <code class="language-plaintext highlighter-rouge">ELEFANTE</code>.</p>

<p>Mas não estou dizendo que devemos lançar o jogo assim! Tudo que estou dizendo é que agora, em vez de mostrar ao usuário uma tela que gera um monte de palavras aleatórias, vamos mostrar um jogo da Forca totalmente funcional que sempre usa a palavra <code class="language-plaintext highlighter-rouge">ELEFANTE</code>. E fazendo isso, nossa revisão do produto se tornará mais interessante porque agora temos uma pergunta muito poderosa para fazer: O que devemos fazer a seguir?</p>

<p>Poderíamos decidir implementar o Dicionário, ou o cliente poderia pedir outra coisa, como um sistema de pontuação para o jogo ou um mecanismo de dicas. Teremos opções. Não estamos jogando Mario Bros, estamos jogando MegaMan.</p>

<h2 id="e-como-começo-a-fazer-isso">E como começo a fazer isso?</h2>

<p>Antes de qualquer coisa, liste todas as suas suposições de dependência e comece a questioná-las. Eu gosto de usar a construção “<strong>Como poderíamos / sem</strong>” para fazer isso:</p>

<ul>
  <li>
    <p><em><strong>Como poderíamos</strong></em> autenticar o usuário <em><strong>sem</strong></em> uma tela de login?</p>
  </li>
  <li>
    <p><em><strong>Como poderíamos</strong></em> gerar um relatório <em><strong>sem</strong></em> ter uma maneira de popular o banco de dados?</p>
  </li>
  <li>
    <p><em><strong>Como poderíamos</strong></em> mostrar esta informação <em><strong>sem</strong></em> usar gráficos?</p>
  </li>
</ul>

<p>Segundo e mais importante: certifique-se de que sua equipe sabe trabalhar com interfaces. Isso é fundamental para evitar retrabalho e quebrar coisas.</p>

<p>Lembre-se: para nos adaptar às mudanças com sucesso, devemos aprender a fazer isso sem aumentar os custos de desenvolvimento. Assim como no MegaMan, o melhor caminho nem sempre é o mais óbvio - às vezes você precisa lutar contra o Fireman antes do Iceman, e às vezes você precisa construir aquele sistema de pontuação antes de implementar o algoritmo perfeito de seleção de palavras.</p>

<p>O Viés da Cronologia, assim como seu primo o Viés da Estratificação, nos engana a seguir um caminho predeterminado quando deveríamos estar nos perguntando aquela simples mas poderosa questão: “<strong>O que devemos fazer a seguir?</strong>”. Afinal, desenvolvimento de software não é sobre completar níveis em uma ordem predefinida - é sobre criar valor da maneira mais efetiva possível.</p>

<p>Em breve teremos o post final desta série, onde exploraremos nosso último viés: <strong>a Modularidade.</strong></p>

<p>Ah! E se você chegou até aqui, obrigado por ler!</p>
]]>
    </content>
    <author>
      <name>Mario Melo</name>
    </author>
    
    <category term="Coding" />
    
    <category term="Bias" />
    
    <summary type="html">No meu último post, falei sobre como o hábito de dividir o software em camadas pode nos levar a trabalhar em uma camada de cada vez, produzindo o indesejado efeito BDUF (Big Design Upfront).</summary>
  </entry>
  
  <entry xml:lang="pt">
    <title type="html">Os 3 vieses do desenvolvimento de software, parte 1: Estratificação</title>
    <link href="https://mariomelo.com/os-3-vieses-do-desenvolvimento-de-software-parte-1-estratificacao" rel="alternate" type="text/html" title="Os 3 vieses do desenvolvimento de software, parte 1: Estratificação" />
    <published>2024-10-14T11:25:01+00:00</published>
    <updated>2024-10-14T11:25:01+00:00</updated>
    <id>https://mariomelo.com/os-3-vieses-do-desenvolvimento-de-software-parte-1-estratificacao</id>
    <content type="html" xml:base="https://mariomelo.com/os-3-vieses-do-desenvolvimento-de-software-parte-1-estratificacao">
      <![CDATA[<p>Recentemente, falei no Regional Scrum Gathering Stockholm sobre os 3 vieses do desenvolvimento de software: Estratificação, Cronologia e Modularidade.</p>

<p>O evento foi incrível, pois os organizadores (Evelyn, Giuseppe, Khurram e Thomas) e os voluntários fizeram um trabalho fantástico na organização. Saí do evento verdadeiramente feliz e com muito alimento para o pensamento. Essa foi minha motivação para transformar minha apresentação em três posts: um para cada viés que descrevi lá.</p>

<h2 id="então-o-que-são-esses-vieses">Então, o que são esses vieses?</h2>

<p>Um viés pode ser definido como “Uma preferência ou inclinação, especialmente uma que inibe o julgamento imparcial”. No desenvolvimento de software, isso poderia ser traduzido como modelar um projeto de software usando conceitos que estão profundamente enraizados em nosso cérebro, evitando assim uma abordagem alternativa que poderia nos ajudar a criar algo mais flexível.</p>

<p>Fazemos as coisas desta maneira porque sempre as fizemos assim. E isso é um loop infinito.</p>

<p>Para quebrar esses vieses, primeiro devemos entendê-los, então vamos começar com o primeiro: <strong>Estratificação</strong>.</p>

<h2 id="estratificação">Estratificação?</h2>

<p>Sim, eu inventei esses três nomes e não estou realmente satisfeito com eles. Mas, como Phil Karlton disse: “Existem apenas duas coisas difíceis em Ciência da Computação: invalidação de cache e dar nomes às coisas”.</p>

<p>O viés de estratificação acontece quando, após dividir um software em camadas (digamos: banco de dados, backend e frontend), começamos imediatamente a desenvolver a camada mais baixa, que geralmente é o modelo de banco de dados. Imagine isto: você começa com a camada de banco de dados, meticulosamente criando cada tabela e relacionamento. Só quando isso está “pronto” você passa para o backend, e que Deus o livre de alguém mencionar o frontend até que a API esteja completa!</p>

<p>Este é provavelmente o mais famoso dos vieses, pois há muito tempo é chamado de BDUF (Big Design Upfront) e foi uma das primeiras barreiras que tivemos que superar para desenvolver software mais flexível. A coisa triste é que ainda acontece. Muito.</p>

<p>Existem dois problemas principais com essa abordagem. Número um: <strong>efeitos colaterais</strong>. Uma mudança em um único ponto da camada superior pode gerar múltiplas mudanças nas camadas inferiores.</p>

<p>Segundo problema: <strong>efeitos colaterais dos efeitos colaterais, ou: bugs</strong>. Agora, porque você teve que mudar o banco de dados, alguma parte do backend que mal está relacionada à mudança inicial pode ser afetada e também afetar alguma parte do frontend que é <strong>completamente não relacionada</strong> à mudança inicial.</p>

<p><img src="../assets/images/posts/5fef1256b440.jpeg" alt="Image" /></p>

<p>Se você prestou atenção, notou que ao corrigir um bug você poderia desencadear exatamente o mesmo processo novamente, o que nos leva a um loop infinito de desespero, frustração e clientes irritados.</p>

<h2 id="sou-vítima-desse-viés-como-escapo-dele">Sou vítima desse viés? Como escapo dele?</h2>

<p>Existem sintomas. Seu cliente não conseguirá fornecer feedback valioso porque não verá nada utilizável, a quantidade de retrabalho necessária sempre que você precisar mudar algo será insuportável, e você pode sentir a necessidade de descartar algumas boas ideias devido aos custos de desenvolvimento. Mais importante: seus desenvolvedores ficarão mortalmente entediados.</p>

<p>E justamente porque esse era o <em>status quo</em> não muito tempo atrás, os desenvolvedores entediados de então decidiram criar algo para ajudá-los a sair dessa situação. Algo que permitiria que o banco de dados evoluísse com segurança ao longo do tempo sem gerar muita dívida técnica. Eles chamaram isso de “<strong>Migrações de Banco de Dados</strong> “.</p>

<p>É bonito, não é? Uma solução técnica criada para resolver um problema técnico que estava dificultando a capacidade da equipe de se adaptar às mudanças. Voltarei a isso mais tarde após o exemplo técnico, então se você já está familiarizado com o conceito ou não está familiarizado com código, pode pular a próxima seção.</p>

<h2 id="colocando-a-mão-na-massa-com-código">Colocando a mão na massa (com código)!</h2>

<p>Vamos dar uma olhada em uma Migração de Banco de Dados usando Elixir e Ecto. Imagine que você está criando uma tabela para armazenar os usuários do seu sistema. Você (e seu cliente) podem ter muitas ideias interessantes sobre todos os dados que você pode armazenar lá: nome, e-mail, uma pequena biografia, um avatar, data de nascimento, e a lista continua.</p>

<p>Se entendermos que o banco de dados pode evoluir, podemos começar com algo mais simples. Apenas o nome de usuário e o e-mail, por exemplo.</p>

<div class="language-elixir highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">defmodule</span> <span class="no">MyApp</span><span class="o">.</span><span class="no">Repo</span><span class="o">.</span><span class="no">Migrations</span><span class="o">.</span><span class="no">CreateUsers</span> <span class="k">do</span>
  <span class="kn">use</span> <span class="no">Ecto</span><span class="o">.</span><span class="no">Migration</span>

  <span class="k">def</span> <span class="n">change</span> <span class="k">do</span>
    <span class="n">create</span> <span class="n">table</span><span class="p">(</span><span class="ss">:users</span><span class="p">)</span> <span class="k">do</span>
      <span class="n">add</span> <span class="ss">:username</span><span class="p">,</span> <span class="ss">:string</span>
      <span class="n">add</span> <span class="ss">:email</span><span class="p">,</span> <span class="ss">:string</span>
      
      <span class="n">timestamps</span><span class="p">()</span>
    <span class="k">end</span>
  <span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>

<p>Fazer esta primeira parte nos fornecerá opções para a próxima iteração. Podemos realmente nos perguntar qual é a coisa mais importante a desenvolver: o avatar? a pequena biografia? algo completamente diferente em outra parte do sistema?</p>

<p>Mais tarde, se decidirmos implementar o avatar do usuário e uma biografia curtinha, poderíamos criar outra migração como esta:</p>

<div class="language-elixir highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">defmodule</span> <span class="no">MyApp</span><span class="o">.</span><span class="no">Repo</span><span class="o">.</span><span class="no">Migrations</span><span class="o">.</span><span class="no">AddProfileToUsers</span> <span class="k">do</span>
  <span class="kn">use</span> <span class="no">Ecto</span><span class="o">.</span><span class="no">Migration</span>

  <span class="k">def</span> <span class="n">change</span> <span class="k">do</span>
    <span class="n">alter</span> <span class="n">table</span><span class="p">(</span><span class="ss">:users</span><span class="p">)</span> <span class="k">do</span>
      <span class="n">add</span> <span class="ss">:bio</span><span class="p">,</span> <span class="ss">:text</span>
      <span class="n">add</span> <span class="ss">:avatar_url</span><span class="p">,</span> <span class="ss">:string</span>
    <span class="k">end</span>
  <span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>

<p>Desta forma, podemos garantir que o banco de dados do cliente estará sempre atualizado e que ninguém executará o mesmo script de banco de dados duas vezes e quebrará tudo.</p>

<h2 id="existem-benefícios-técnicos-mas-também-não-técnicos">Existem benefícios técnicos, mas também não-técnicos</h2>

<p>Além do benefício óbvio de criar algo mais flexível, existem alguns benefícios não-técnicos muito interessantes. Por exemplo: como você construiu um banco de dados mais leve, o que quer que a equipe precise desenvolver a seguir levará menos tempo simplesmente porque haverá menos campos e tabelas para lidar. Isso também se refletirá na quantidade de efeitos colaterais (ou seja, bugs) que seu processo de desenvolvimento pode gerar, porque a complexidade do seu software não crescerá exponencialmente como antes. Podemos resumir isso como: <strong>quebrar o viés de estratificação equivale a economizar tempo</strong>.</p>

<p>Esse tempo que você economizou pode gerar um efeito borboleta. A equipe agora pode pensar no que fazer com esse tempo. Talvez aprender a escrever alguns testes unitários, ou dedicar um tempo para experimentar uma nova tecnologia. Como a resposta a essa pergunta não é óbvia, eles terão que colaborar para encontrar a melhor opção. Observe que todos terão que colaborar: desenvolvedores, designers, testadores, pessoas de negócios.</p>

<p>Todo esse conceito de migração de banco de dados foi criado porque alguém desafiou a ideia de que “<strong>Não podemos alterar o banco de dados como quisermos</strong>”. Uma pessoa técnica, com uma solução técnica. Porque às vezes, quando um desenvolvedor enfrenta um desafio como esse e tem o tempo e os recursos adequados para lidar com ele, uma inovação nasce.</p>

<p>Isso também acontece quando quebramos os vieses de Cronologia e Modularidade, mas falaremos sobre eles mais tarde. :)</p>

<hr />

<p><strong>Ps:</strong> Se você quiser ler mais sobre este assunto, pode conferir o post detalhado e incrível do Martin Fowler, aqui: <a href="https://martinfowler.com/articles/evodb.html">https://martinfowler.com/articles/evodb.html</a></p>
]]>
    </content>
    <author>
      <name>Mario Melo</name>
    </author>
    
    <category term="Coding" />
    
    <category term="Bias" />
    
    <summary type="html">Recentemente, falei no Regional Scrum Gathering Stockholm sobre os 3 vieses do desenvolvimento de software: Estratificação, Cronologia e Modularidade.</summary>
  </entry>
  
  <entry xml:lang="pt">
    <title type="html">A relacao entre especificidade e obsolescência</title>
    <link href="https://mariomelo.com/a-relacao-entre-especificidade-e-obsolescencia" rel="alternate" type="text/html" title="A relacao entre especificidade e obsolescência" />
    <published>2024-08-06T14:51:32+00:00</published>
    <updated>2024-08-06T14:51:32+00:00</updated>
    <id>https://mariomelo.com/a-relacao-entre-especificidade-e-obsolescencia</id>
    <content type="html" xml:base="https://mariomelo.com/a-relacao-entre-especificidade-e-obsolescencia">
      <![CDATA[<p>Imagine que você receba a seguinte informação: <strong>Lady Gaga está trabalhando em seu próximo álbum.</strong></p>

<p>Se é verdade agora, seria verdade amanhã também? Provavelmente. As chances são de que ela passe <strong>alguns meses</strong> até terminar o álbum, e a frase ainda será verdadeira durante esse período. No entanto, se você receber uma informação mais específica, o cenário pode mudar:</p>

<ul>
  <li><strong>Lady Gaga está trabalhando na primeira música do seu novo álbum</strong></li>
</ul>

<p>Por quanto tempo essa frase será verdadeira? Talvez <strong>alguns dias ou semanas</strong>.</p>

<ul>
  <li><strong>Lady Gaga está escrevendo a letra da primeira música do seu novo álbum</strong></li>
</ul>

<p>Por quanto tempo essa frase será verdadeira? Talvez <strong>alguns dias ou horas</strong>.</p>

<ul>
  <li><strong>Lady Gaga está escrevendo o refrão da primeira música do seu novo álbum</strong></li>
</ul>

<p>Por quanto tempo essa frase será verdadeira? Talvez <strong>algumas horas ou até mesmo minutos</strong>.</p>

<p>Quando se trata de software, poderíamos dizer o mesmo. E Kent Beck recentemente republicou um artigo legal sobre o assunto chamado “Software is Bananas” (link abaixo).</p>

<p><a href="https://tidyfirst.substack.com/p/software-is-bananas?utm_source=substack&amp;utm_campaign=post_embed&amp;utm_medium=web">Software Design: Tidy First? - Software Is Bananas</a></p>

<p>O problema é que informações diferentes em contextos diferentes terão “datas de validade” diferentes. Digamos que você tenha um problema e queira criar um produto de software para resolver esse problema, então você formula uma hipótese:</p>

<p><code class="language-plaintext highlighter-rouge">Se essa ideia que eu tenho funcionar, o problema X desaparecerá.</code></p>

<p>Se você não implementar sua ideia em, digamos, 6 meses, ela pode não fazer mais sentido mesmo que o problema original ainda exista. É natural: o problema é menos volátil do que a solução simplesmente porque existe uma relação de dependência entre eles.</p>

<p>Mas digamos que você decida seguir em frente e implementar sua ideia. Você então começa a fazer anotações sobre como fazê-lo:</p>

<p><code class="language-plaintext highlighter-rouge">Para implementar essa ideia, farei a etapa X, a etapa Y e a etapa Z.</code></p>

<p>A mesma regra se aplica aqui. Se você não seguir as etapas que estabeleceu imediatamente, poderá decidir implementar a mesma ideia de outra maneira. As etapas são mais específicas e, portanto, mais voláteis.</p>

<p>Em resumo, não tem problema ter uma lista de problemas para resolver, desde que você não gaste muito tempo pensando em como resolver muitos deles de uma vez. E não tem problema discutir os detalhes de implementação de um punhado de ideias, desde que você tenha certeza de que vai implementá-las nos próximos dias.</p>
]]>
    </content>
    <author>
      <name>Mario Melo</name>
    </author>
    
    <category term="Building" />
    
    <category term="Product" />
    
    <summary type="html">Imagine que você receba a seguinte informação: Lady Gaga está trabalhando em seu próximo álbum.</summary>
  </entry>
  
  <entry xml:lang="pt">
    <title type="html">Uma reflexão sobre meus 20 anos trabalhando com desenvolvimento de software</title>
    <link href="https://mariomelo.com/uma-reflexao-sobre-meus-20-anos-de-desenvolvimento-de-software" rel="alternate" type="text/html" title="Uma reflexão sobre meus 20 anos trabalhando com desenvolvimento de software" />
    <published>2024-07-22T16:02:33+00:00</published>
    <updated>2024-07-22T16:02:33+00:00</updated>
    <id>https://mariomelo.com/uma-reflexao-sobre-meus-20-anos-de-desenvolvimento-de-software</id>
    <content type="html" xml:base="https://mariomelo.com/uma-reflexao-sobre-meus-20-anos-de-desenvolvimento-de-software">
      <![CDATA[<p>Recebi meu primeiro salário como desenvolvedor de software em julho de 2004. Já se passaram 20 anos.</p>

<p>Durante esses anos fui desenvolvedor, dono de empresa, consultor, instrutor, e aprendi (principalmente cometendo erros) muitas coisas sobre o lado técnico e o lado social do desenvolvimento de software.</p>

<p>O que escrevi aqui é baseado no que vivi neste mercado, o que significa: é baseado em muitos anos de experiência, mas também é enviesado por essas mesmas experiências. Mas como vi coisas mudando e outras não mudando, gostaria de tentar elaborar meu raciocínio sobre quais são as causas e consequências desses resultados.</p>

<p>Então, vamos lá!</p>

<h2 id="o-que-mudou-em-20-anos">O que mudou em 20 anos?</h2>

<p>Bem… Obviamente, <strong>a tecnologia mudou.</strong> E com isso, tudo mudou.</p>

<p>Quando comecei a programar não tínhamos iPhones ou telefones Android, e curiosamente eu estava trabalhando com computação móvel. Pocket PC 2002 era o sistema operacional e eu escrevia código C++ que precisava ser altamente otimizado por causa de todas as restrições de memória que tínhamos naquela época.</p>

<p><img src="../assets/images/posts/718c3cc53b95.jpeg" alt="Computadores móveis Intermec" /><em>Mobile nos anos 2000: Esses dispositivos conseguiam fazer o Nokia 3310 parecer frágil</em></p>

<p>Mas mais importante: as <strong>organizações mudaram</strong>. E a maioria das mudanças que vi foram causadas por inovações tecnológicas.</p>

<h4 id="complicado-depois-mais-simples-depois-complexo"><strong>Complicado, depois mais simples, depois complexo</strong></h4>

<p>Se você já escreveu uma aplicação web usando J2EE e Enterprise Beans, lembra como era burocrático. O deploy não era direto, precisávamos escrever muito código para fazer a coisa mais simples e mudanças no schema do banco de dados eram um pesadelo. A questão é que estávamos principalmente criando aplicações web privadas porque a web não era o que é hoje (nem mesmo o Orkut tinha sido criado ainda).</p>

<p>No início, esses pontos de dor incentivaram as organizações a buscar <strong>equipes maiores</strong>, um <strong>departamento de gerenciamento de banco de dados</strong> especializado e também um <strong>departamento de operações</strong>.</p>

<p>Por outro lado, os desenvolvedores começaram a criar ferramentas para resolver esses pontos de dor: frameworks ORM como Hibernate começaram a se tornar populares, depois frameworks como Rails começaram a introduzir maneiras mais fáceis de criar bancos de dados evolutivos e também uma abordagem mais direta para criar uma aplicação web.</p>

<p>Essas mudanças empoderaram os desenvolvedores e permitiram que pequenas equipes fossem ainda mais produtivas do que as grandes equipes corporativas eram. Com isso vimos uma mudança no mercado: todo mundo queria equipes menores com os chamados Desenvolvedores Full-stack. Computação em nuvem estava disponível para todos por menos de US$5/mês com Heroku, DigitalOcean e AWS, e muitas startups começaram a aparecer em todo lugar.</p>

<p><strong>Mas então… tudo mudou.</strong></p>

<p>A web evoluiu e o que era um simples REQUEST/RESPONSE com HTML e CSS se tornou um quebra-cabeça complexo usando Ajax, jQuery, e depois Angular, Ember, React, Vue, Svelte. As empresas começaram a exigir <strong>desenvolvedores frontend</strong>.</p>

<p>No backend, as coisas ficaram ainda mais complexas. Os gigantes da indústria estavam enfrentando os desafios causados pelo seu próprio sucesso: como lidar com uma quantidade tão massiva de usuários simultâneos? Como armazenar eficientemente essa quantidade massiva de dados?</p>

<p>Então novamente, os desenvolvedores vieram ao resgate e criaram soluções como Docker, Kubernetes, Grafana. Os gigantes compartilharam suas histórias de sucesso e as empresas de médio porte decidiram adicionar toda essa complexidade aos seus produtos para alcançar os mesmos resultados. Em parte, esse movimento também foi causado pelos desenvolvedores: queríamos trabalhar com a tecnologia de ponta usada pelos gigantes do mercado, mesmo que claramente não fosse necessário para nossos servidores que estavam lidando com muito menos usuários do que Google ou Facebook.</p>

<p>Desenvolver um software simples parecia… desnecessariamente complexo. A maioria das empresas com as quais trabalhei naquela época não estavam criando produtos para as massas, mas produtos de nicho com pouca ou nenhuma necessidade de tal complexidade. E foi na verdade quando comecei a trabalhar mais com consultoria e treinamento novamente. Eu estava constantemente defendendo modelos mais simples sempre que eram bons o suficiente.</p>

<p>Ainda estou.</p>

<h2 id="o-que-não-mudou-em-20-anos">O que não mudou em 20 anos?</h2>

<p>Muitas coisas:</p>

<ul>
  <li>
    <p>Ainda precisamos de desenvolvedores de software</p>
  </li>
  <li>
    <p>As pessoas ainda estão tentando descobrir como medir produtividade no campo de desenvolvimento de software</p>
  </li>
  <li>
    <p>Estimativas ainda são um problema para a maioria das pessoas</p>
  </li>
  <li>
    <p>As pessoas ainda discutem sobre qual é o melhor editor de texto/IDE/framework/linguagem</p>
  </li>
  <li>
    <p>E bem… <strong>desenvolvimento de software ainda me traz alegria</strong> :)</p>
  </li>
</ul>

<p>Não sinto que disse tudo o que queria dizer. Ainda preciso refletir mais sobre como mudei durante esses 20 anos.</p>

<p>Talvez eu escreva mais sobre isso no futuro.</p>
]]>
    </content>
    <author>
      <name>Mario Melo</name>
    </author>
    
    <category term="Building" />
    
    <category term="Career" />
    
    <summary type="html">Recebi meu primeiro salário como desenvolvedor de software em julho de 2004.</summary>
  </entry>
  
  <entry xml:lang="pt">
    <title type="html">Dependencias: Bibliotecas ou OTP applications</title>
    <link href="https://mariomelo.com/dependencias-bibliotecas-ou-otp-applications" rel="alternate" type="text/html" title="Dependencias: Bibliotecas ou OTP applications" />
    <published>2024-07-18T08:51:08+00:00</published>
    <updated>2024-07-18T08:51:08+00:00</updated>
    <id>https://mariomelo.com/dependencias-bibliotecas-ou-otp-applications</id>
    <content type="html" xml:base="https://mariomelo.com/dependencias-bibliotecas-ou-otp-applications">
      <![CDATA[<h2 id="o-projeto-scrumchkin-online">O projeto: Scrumchkin Online</h2>

<p>Há cerca de um ano atrás criei um jogo de cartas para ensinar Scrum: <a href="http://scrumchkin.com">o Scrumchkin</a>. O jogo tornou o processo de aprendizado mais divertido e foi adotado por <em>Scrum Trainers</em> de diversos países, até que a pandemia inviabilizou qualquer turma presencial.</p>

<p>E foi daí que surgiu meu projeto pessoal: criar uma versão online do Scrumchkin. O que seria uma ótima oportunidade para brincar e aprender mais sobre <em>Phoenix Liveview</em>.</p>

<p>Inicialmente, pensei na seguinte estrutura para o projeto:</p>

<p>Desta forma, seria possível criar jogos em processos separados e ter um registro com identificadores únicos de cada jogo para que cada partida pudesse ser acessada através de uma URL diferente.</p>

<p>Exemplo:</p>

<ul>
  <li>
    <p>O usuário acessa a URL <code class="language-plaintext highlighter-rouge">http://scrumchkin.com/game/abc123</code></p>
  </li>
  <li>
    <p>A aplicação web pergunta ao Registro de Jogos onde está o jogo <code class="language-plaintext highlighter-rouge">abc123</code></p>
  </li>
  <li>
    <p>O Registro de Jogos encontra o PID da partida e retorna para aplicação web</p>
  </li>
</ul>

<h3 id="o-registro-de-jogos-como-uma-biblioteca">O Registro de Jogos como uma biblioteca</h3>

<p>Tendo em mente o <strong>princípio da responsabilidade única</strong> , o desenho acima deixa bem evidente a existência de 3 projetos diferentes: O Registro de Jogos, o Servidor de Jogos e a Interface Web.</p>

<p><em>Os próximos parágrafos vão falar sobre alguns aspectos técnicos de Elixir a título de curiosidade. Se você quiser apenas entender a diferença entre uma biblioteca e uma aplicação OTP basta pular esta parte</em> :)</p>

<p>Tecnicamente o Registro de Jogos é extremamente simples: ele vincula um ID único a uma partida. Ele é basicamente um dicionário que tem como chave um <em>UUID</em> e como valor um <em>PID</em> de um GenServer para uma partida.</p>

<p>Inicialmente, criei o Registro de Jogos como uma biblioteca capaz de fazer operações CRUD em uma <em>tabela ets</em> :</p>
<div class="language-elixir highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">defmodule</span> <span class="no">GameRegister</span> <span class="k">do</span>
  <span class="k">def</span> <span class="n">init</span><span class="p">()</span> <span class="k">do</span>
    <span class="ss">:ets</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">:scrumchkin</span><span class="p">,</span> <span class="p">[</span><span class="ss">:set</span><span class="p">,</span> <span class="ss">:public</span><span class="p">,</span> <span class="ss">:named_table</span><span class="p">])</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="n">save</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="k">do</span>
    <span class="n">key</span> <span class="o">=</span> <span class="no">UUID</span><span class="o">.</span><span class="n">uuid1</span><span class="p">()</span>
    <span class="ss">:ets</span><span class="o">.</span><span class="n">insert_new</span><span class="p">(</span><span class="ss">:scrumchkin</span><span class="p">,</span> <span class="p">{</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">})</span>
    <span class="n">key</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="n">delete</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="k">do</span>
    <span class="ss">:ets</span><span class="o">.</span><span class="n">delete</span><span class="p">(</span><span class="ss">:scrumchkin</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="n">get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="k">do</span>
    <span class="ss">:scrumchkin</span>
    <span class="o">|&gt;</span> <span class="ss">:ets</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
    <span class="o">|&gt;</span> <span class="n">format_result</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="n">list_all</span> <span class="k">do</span>
    <span class="ss">:ets</span><span class="o">.</span><span class="n">tab2list</span><span class="p">(</span><span class="ss">:scrumchkin</span><span class="p">)</span>
  <span class="k">end</span>

  <span class="k">defp</span> <span class="n">format_result</span><span class="p">([]),</span> <span class="k">do</span><span class="p">:</span> <span class="p">{</span><span class="ss">:error</span><span class="p">,</span> <span class="s2">"Game not found"</span><span class="p">}</span>

  <span class="k">defp</span> <span class="n">format_result</span><span class="p">(</span><span class="n">item_list</span><span class="p">)</span> <span class="k">do</span>
    <span class="n">item_list</span>
    <span class="o">|&gt;</span> <span class="n">hd</span>
  <span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>

<p><strong>TL;DR</strong> - A biblioteca armazena o estado atual de partidas e as vincula a um código identificador. Ela é capaz de listar, obter, salvar e deletar partidas do registro.</p>

<h3 id="um-pequeno-problema">Um pequeno problema</h3>

<p>Para que eu pudesse utilizar a tabela ets, ela precisava existir. Isto significa que em algum momento a função <code class="language-plaintext highlighter-rouge">init</code> do código acima precisaria ser chamada pela minha aplicação web.</p>

<div class="language-elixir highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="k">def</span> <span class="n">init</span><span class="p">()</span> <span class="k">do</span>
    <span class="ss">:ets</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">:scrumchkin</span><span class="p">,</span> <span class="p">[</span><span class="ss">:set</span><span class="p">,</span> <span class="ss">:public</span><span class="p">,</span> <span class="ss">:named_table</span><span class="p">])</span>
  <span class="k">end</span>
</code></pre></div></div>

<p>Mas isso vai contra o princípio de responsabilidade única que utilizei para dividir este projeto em partes menores, certo?</p>

<h3 id="o-registro-como-uma-aplicação">O Registro como uma aplicação</h3>

<p>Mas o que é uma dependência como biblioteca? Ela é uma engrenagem que faz parte de um todo; algo bem parecido com uma peça de Lego. Sabemos onde estão os pinos e buracos e a utilizamos para construir algo maior.</p>

<p><img src="../assets/images/posts/0b40ff6369e6.png" alt="Dependências como Bibliotecas" /><em>A dependência de uma aplicação OTP é um pouco diferente.</em></p>

<p>Pense em um carro. Geralmente, carros têm um mecanismo de refrigeração do motor que é iniciado no momento em que você vira a chave e dá a partida. O carro depende deste mecanismo para funcionar, mas ele é um tanto quanto independente: muitas vezes ele é acionado quando desligamos o carro (aquele barulho de ventilador que vem de debaixo do capô, principalmente em dias quentes).</p>

<p>Esse mecanismo de refrigeração tem interfaces com o motor do carro, mas controla seu próprio estado. Existe uma relação clara de <strong>dependência</strong> , mas não de controle. O motor depende do sistema de refrigeração para não superaquecer, mas não o controla.</p>

<p>E o mesmo precisava acontecer com meu Registro de Jogos, que ficou assim:</p>

<div class="language-elixir highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">defmodule</span> <span class="no">GameRegister</span> <span class="k">do</span>
  <span class="kn">use</span> <span class="no">GenServer</span>

  <span class="k">def</span> <span class="n">start_link</span><span class="p">(</span><span class="n">state</span><span class="p">)</span> <span class="k">do</span>
    <span class="no">GenServer</span><span class="o">.</span><span class="n">start_link</span><span class="p">(</span><span class="bp">__MODULE__</span><span class="p">,</span> <span class="n">state</span><span class="p">,</span> <span class="ss">name:</span> <span class="bp">__MODULE__</span><span class="p">)</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="n">init</span><span class="p">(</span><span class="n">stack</span><span class="p">)</span> <span class="k">do</span>
    <span class="ss">:ets</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">:scrumchkin</span><span class="p">,</span> <span class="p">[</span><span class="ss">:set</span><span class="p">,</span> <span class="ss">:public</span><span class="p">,</span> <span class="ss">:named_table</span><span class="p">])</span>
    <span class="no">IO</span><span class="o">.</span><span class="n">puts</span><span class="p">(</span><span class="s2">"Tabela scrumchkin criada"</span><span class="p">)</span>
    <span class="p">{</span><span class="ss">:ok</span><span class="p">,</span> <span class="n">stack</span><span class="p">}</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="n">handle_call</span><span class="p">({</span><span class="ss">:save</span><span class="p">,</span> <span class="n">game</span><span class="p">},</span> <span class="n">_from</span><span class="p">,</span> <span class="n">state</span><span class="p">)</span> <span class="k">do</span>
    <span class="n">key</span> <span class="o">=</span> <span class="no">UUID</span><span class="o">.</span><span class="n">uuid1</span><span class="p">()</span>
    <span class="ss">:ets</span><span class="o">.</span><span class="n">insert_new</span><span class="p">(</span><span class="ss">:scrumchkin</span><span class="p">,</span> <span class="p">{</span><span class="n">key</span><span class="p">,</span> <span class="n">game</span><span class="p">})</span>
    <span class="p">{</span><span class="ss">:reply</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">state</span><span class="p">}</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="n">handle_call</span><span class="p">({</span><span class="ss">:delete</span><span class="p">,</span> <span class="n">game_id</span><span class="p">},</span> <span class="n">_from</span><span class="p">,</span> <span class="n">state</span><span class="p">)</span> <span class="k">do</span>
    <span class="ss">:ets</span><span class="o">.</span><span class="n">delete</span><span class="p">(</span><span class="ss">:scrumchkin</span><span class="p">,</span> <span class="n">game_id</span><span class="p">)</span>
    <span class="p">{</span><span class="ss">:reply</span><span class="p">,</span> <span class="ss">:ok</span><span class="p">,</span> <span class="n">state</span><span class="p">}</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="n">handle_call</span><span class="p">({</span><span class="ss">:get</span><span class="p">,</span> <span class="n">game_id</span><span class="p">},</span> <span class="n">_from</span><span class="p">,</span> <span class="n">state</span><span class="p">)</span> <span class="k">do</span>
    <span class="n">result</span> <span class="o">=</span>
      <span class="ss">:scrumchkin</span>
      <span class="o">|&gt;</span> <span class="ss">:ets</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">game_id</span><span class="p">)</span>
      <span class="o">|&gt;</span> <span class="n">format_result</span>

    <span class="p">{</span><span class="ss">:reply</span><span class="p">,</span> <span class="n">result</span><span class="p">,</span> <span class="n">state</span><span class="p">}</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="n">handle_call</span><span class="p">(</span><span class="ss">:list_all</span><span class="p">,</span> <span class="n">_from</span><span class="p">,</span> <span class="n">state</span><span class="p">)</span> <span class="k">do</span>
    <span class="p">{</span><span class="ss">:reply</span><span class="p">,</span> <span class="ss">:ets</span><span class="o">.</span><span class="n">tab2list</span><span class="p">(</span><span class="ss">:scrumchkin</span><span class="p">),</span> <span class="n">state</span><span class="p">}</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="n">save</span><span class="p">(</span><span class="n">game</span><span class="p">)</span> <span class="k">do</span>
    <span class="no">GenServer</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="bp">__MODULE__</span><span class="p">,</span> <span class="p">{</span><span class="ss">:save</span><span class="p">,</span> <span class="n">game</span><span class="p">})</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="n">delete</span><span class="p">(</span><span class="n">game_id</span><span class="p">)</span> <span class="k">do</span>
    <span class="no">GenServer</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="bp">__MODULE__</span><span class="p">,</span> <span class="p">{</span><span class="ss">:delete</span><span class="p">,</span> <span class="n">game_id</span><span class="p">})</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="n">get</span><span class="p">(</span><span class="n">game_id</span><span class="p">)</span> <span class="k">do</span>
    <span class="no">GenServer</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="bp">__MODULE__</span><span class="p">,</span> <span class="p">{</span><span class="ss">:get</span><span class="p">,</span> <span class="n">game_id</span><span class="p">})</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="n">list_all</span> <span class="k">do</span>
    <span class="no">GenServer</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="bp">__MODULE__</span><span class="p">,</span> <span class="ss">:list_all</span><span class="p">)</span>
  <span class="k">end</span>

  <span class="k">defp</span> <span class="n">format_result</span><span class="p">([]),</span> <span class="k">do</span><span class="p">:</span> <span class="p">{</span><span class="ss">:error</span><span class="p">,</span> <span class="s2">"Game not found"</span><span class="p">}</span>

  <span class="k">defp</span> <span class="n">format_result</span><span class="p">(</span><span class="n">item_list</span><span class="p">)</span> <span class="k">do</span>
    <span class="n">item_list</span>
    <span class="o">|&gt;</span> <span class="n">hd</span>
  <span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>

<h3 id="mas-o-que-muda">Mas… o que muda?</h3>

<p>Minha aplicação web não é responsável por criar a tabela ets. Ela apenas diz que depende do Registro de Jogos e que ele é agora uma <strong>aplicação extra</strong>.</p>

<p>A alteração no arquivo <code class="language-plaintext highlighter-rouge">mix.exs</code> é simples:</p>
<div class="language-elixir highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="k">def</span> <span class="n">application</span> <span class="k">do</span>
    <span class="p">[</span>
      <span class="ss">mod:</span> <span class="p">{</span><span class="no">Scrumchkin</span><span class="o">.</span><span class="no">Application</span><span class="p">,</span> <span class="p">[]},</span>
      <span class="ss">extra_applications:</span> <span class="p">[</span><span class="ss">:logger</span><span class="p">,</span> <span class="ss">:runtime_tools</span><span class="p">,</span> <span class="ss">:game_register</span><span class="p">,</span> <span class="ss">:game_engine</span><span class="p">]</span>
    <span class="p">]</span>
  <span class="k">end</span>
  <span class="k">defp</span> <span class="n">deps</span> <span class="k">do</span>
    <span class="p">[</span>
      <span class="p">{</span><span class="ss">:game_engine</span><span class="p">,</span> <span class="ss">path:</span> <span class="s2">"../game_engine"</span><span class="p">},</span>
      <span class="p">{</span><span class="ss">:game_register</span><span class="p">,</span> <span class="ss">path:</span> <span class="s2">"../game_register"</span><span class="p">}</span>
    <span class="p">]</span>
  <span class="k">end</span>
</code></pre></div></div>

<p>Agora, toda vez que inicio minha aplicação com um <code class="language-plaintext highlighter-rouge">mix phx.server</code> omeu registro de jogos é iniciado automaticamente e assume a responsabilidade de criar a tabela ets onde vai armazenar os PIDs das partidas de Scrumchkin.</p>

<p>A minha aplicação web <strong>depende</strong> do Registro de Jogos, mas confia que ele consegue resolver seus problemas sozinho.</p>
]]>
    </content>
    <author>
      <name>Mario Melo</name>
    </author>
    
    <category term="Coding" />
    
    <category term="Elixir" />
    
    <summary type="html">O projeto: Scrumchkin Online</summary>
  </entry>
  
  <entry xml:lang="pt">
    <title type="html">Property base testing e o problema da transferencia de r$ 17,99</title>
    <link href="https://mariomelo.com/property-based-testing-e-o-problema-da-transferencia" rel="alternate" type="text/html" title="Property base testing e o problema da transferencia de r$ 17,99" />
    <published>2022-03-28T14:48:26+00:00</published>
    <updated>2022-03-28T14:48:26+00:00</updated>
    <id>https://mariomelo.com/property-based-testing-e-o-problema-da-transferencia</id>
    <content type="html" xml:base="https://mariomelo.com/property-based-testing-e-o-problema-da-transferencia">
      <![CDATA[<p>Há algumas semanas uma pessoa descobriu que seu banco não permitia que ela fizesse uma transferência bancária de um valor bastante específico: <strong>R$17,99</strong>. O que acontecia? O banco automaticamente convertia o valor transferido para <strong>R$17,98</strong>.</p>

<p>O mais curioso é que transferências de outros valores funcionavam perfeitamente. Bem, quase todos. As pessoas começaram a descobrir outros casos específicos onde o problema acontecia: <strong>R$ 32,23</strong> ou <strong>R$ 155,17.</strong></p>

<p>A idéia desse post não é debater a causa do problema, mas sim mostrar uma técnica que pode ajudar equipes a detectar problemas parecidos.</p>

<p>O texto inclui algum código em Elixir, mas também inclui ilustrações para explicar cada conceito. O objetivo é tornar este conteúdo útil tanto para pessoas técnicas quanto para pessoas não-técnicas.</p>

<h3 id="testes-unitários-ajudariam-bem-não-exatamente">Testes unitários ajudariam? Bem… não exatamente.</h3>

<p>Não me leve a mal: eu sou fã de testes unitários e (<em>quase</em>) sempre pratico TDD.</p>

<p>Mas um teste convencional para uma função de transferência de dinheiro provavelmente seria algo parecido com o exemplo abaixo:</p>

<script src="https://gist.github.com/mariomelo/56fa58d3515bc5c78afff7a24ded0dc6.js"></script>

<p>Não fica muito específico?</p>

<p>Repare que o teste onde a transferência é possível foca em apenas um caso: uma transferência de <strong>R$ 25,00</strong>. E nesse caso, os testes são um sucesso:</p>

<p><img src="../assets/images/posts/e55bd026f55a.png" alt="Testes passando com sucesso" /></p>

<h3 id="mas-podemos-escrever-um-teste-para-o-caso-dos-r1799-certo">Mas podemos escrever um teste para o caso dos R$17,99, certo?</h3>

<p>Claro! <strong>Depois de saber da existência do erro</strong> poderíamos incluir um teste adicional para garantir que transferências bancárias de R$ 17,99 também podem ser efetuadas:</p>

<script src="https://gist.github.com/mariomelo/b3fab52e0eebccdbbe77afdfb9cdc55f.js"></script>

<p>Aqui podemos colocar o famoso ciclo do TDD (<em>Test Driven Development</em>, ou desenvolvimento orientado a testes) em ação: <strong>Red, Green, Refactor.</strong></p>

<p><img src="../assets/images/posts/a1cf3f1ae6aa.jpeg" alt="Ciclo Red, Green, Refactor do TDD" /></p>

<p>Este teste falha (<strong>RED</strong>), e então podemos corrigir o problema até que o teste passe (<strong>GREEN</strong>). E agora, tendo o teste como uma rede de segurança podemos deixar alterar o código para torná-lo mais legível sem medo de quebrar nada (<strong>REFACTOR</strong>).</p>

<p><img src="../assets/images/posts/6fcf1901980a.png" alt="Teste falhando mostrando diferença no saldo" /><em>O teste falha pois o saldo restante foi de R$2,02 e não R$ 2,01</em></p>

<p>Pronto! Agora quando fizermos este teste passar vamos garantir que as transferências de R$17,99 funcionarão perfeitamente. Mas algumas perguntas ficam no ar:</p>

<ul>
  <li>
    <p>A transferência de <strong>R$ 32,23</strong> vai funcionar?</p>
  </li>
  <li>
    <p>E se existirem outros valores que geram o mesmo erro?</p>
  </li>
  <li>
    <p>E se existirem valores que geram outro erro diferente?</p>
  </li>
  <li>
    <p>Como podemos evitar que problemas como esse cheguem aos nossos clientes?</p>
  </li>
</ul>

<p>E é aí que entra em cena o PBT — Property Based Testing, ou <strong>Testes Baseados em Propriedades</strong>.</p>

<h3 id="pbt-limpando-onde-os-testes-convencionais-não-alcançam">PBT: limpando onde os testes convencionais não alcançam</h3>

<p>É bem simples de escrever o teste dos R$17,99 <strong>depois</strong> que sabemos da existência do erro.</p>

<p><img src="../assets/images/posts/3dcaa4913450.jpeg" alt="Ilustração sobre escrever testes após descobrir o erro" /></p>

<p>O que acontece é que nós escrevemos os testes com casos que já temos em mente, de maneira bastante <strong>linear e específica</strong>. Mas o teste é tão específico que testa apenas um caso. E se o problema continuar acontecendo com transferências de outros valores?</p>

<p><img src="../assets/images/posts/52d6e20585be.png" alt="Teste mostrando problema com transferência de R$ 6,05" /><em>Neste caso, o problema apareceu apenas ao tentar transferir R$ 6,05</em></p>

<p>Mas… como poderíamos identificar valores problemáticos <strong>antes mesmo de saber do problema</strong>? É aí que entram os testes baseados em propriedade.</p>

<p>Trabalhar com propriedades significa não pensar em casos específicos, e sim nas características de cada variável envolvida no teste. Neste caso, podemos dizer que:</p>

<ul>
  <li>
    <p>O saldo inicial de quem vai transferir o dinheiro pode ser <strong>qualquer valor maior que zero</strong>.</p>
  </li>
  <li>
    <p>O valor da transferência é <strong>maior que zero e menor ou igual ao saldo disponível.</strong></p>
  </li>
</ul>

<p><img src="../assets/images/posts/ad110b85f0ac.jpeg" alt="Ilustração sobre propriedades dos testes" /></p>

<p>Para saber se a transferência foi feita com os valores corretos basta a gente “tirar a prova”, como fazíamos no ensino fundamental. :)</p>

<blockquote>
  <p><strong>Valor transferido + Saldo remanescente = Saldo antes da transferência</strong></p>
</blockquote>

<p>Quando definimos as regras desta maneira, as ferramentas de testes automatizados são capazes de validar diversos casos diferentes. E muitas vezes esses “casos diferentes” acabam incluindo situações que sequer imaginamos, e por isso jamais escreveríamos um teste convencional sobre elas.</p>

<script src="https://gist.github.com/mariomelo/320463a24d236fd1c1f634951431f42c.js"></script>

<p>Agora, ao rodar os testes descobrimos que existem outros valores que também acabam por gerar o erro:</p>

<p><img src="../assets/images/posts/2df433c8c4e5.png" alt="Teste PBT detectando erro com valores diferentes" /><em>Opa! Se eu tiver R$0,98 e tentar transferir R$0,71 o problema também acontece!</em></p>

<p>Ah! Repare que a biblioteca de testes diz: <strong>Counter example stored</strong>.</p>

<p>As bibliotecas de PBT costumam armazenar os valores que geraram erros e usá-los novamente até que o problema seja corrigido. Ou seja, quando o teste passar é porque o problema foi resolvido, e não porque a biblioteca selecionou apenas valores para os quais o problema não acontece.</p>

<h3 id="tá-mas-o-que-isso-tem-a-ver-com-agilidade">Tá, mas o que isso tem a ver com agilidade?</h3>

<p>Bem, agilidade é a capacidade de mudar e gerar resultados rapidamente.</p>

<p>É como se você estivesse em um carro de corrida em uma pista sinuosa: para fazer curvas rapidamente e sem perder muita velocidade você vai precisar de um veículo sólido e bem construído. Sem isso, você se limita a duas opções:</p>

<ul>
  <li>
    <p>Fazer a curva beeeeem devagarzinho para garantir que o veículo não quebre</p>
  </li>
  <li>
    <p>Fazer a curva rapidamente e desmantelar seu veículo</p>
  </li>
</ul>

<p><strong>Exemplo:</strong></p>

<p>Imagine que o banco decidisse permitir contas em Bitcoins. Teriam agora que trabalhar com uma moeda que tem bem mais do que duas casas decimais.</p>

<p>Agora imagine que o banco pode ter uma aplicação que:</p>

<p>a) Não tem nenhum teste automatizado</p>

<p>b) Tem alguns testes automatizados</p>

<p>c) Tem testes automatizados convencionais e alguns utilizando PBT</p>

<p>Em qual cenário o banco conseguiria ter um produto funcional em produção mais rapidamente?</p>

<p>Resumindo: <strong>Não existe agilidade sem excelência técnica.</strong></p>

<h3 id="código-fonte-e-considerações-finais">Código Fonte e considerações finais</h3>

<p>Eu escrevi o código para gerar o erro de forma proposital e assim ilustrar como uma determinada técnica poderia ajudar a resolver um problema.</p>

<p>Caso você tenha curiosidade, o código utilizado neste post está disponível em: <a href="https://github.com/mariomelo/post_pbt">https://github.com/mariomelo/post_pbt</a></p>
]]>
    </content>
    <author>
      <name>Mario Melo</name>
    </author>
    
    <category term="Coding" />
    
    <category term="Testing" />
    
    <summary type="html">Há algumas semanas uma pessoa descobriu que seu banco não permitia que ela fizesse uma transferência bancária de um valor bastante específico: R$17,99.</summary>
  </entry>
  
  <entry xml:lang="pt">
    <title type="html">3 fake news que voce ja deve ter ouvido sobre o scrum</title>
    <link href="https://mariomelo.com/3-fake-news-sobre-o-scrum" rel="alternate" type="text/html" title="3 fake news que voce ja deve ter ouvido sobre o scrum" />
    <published>2022-02-09T15:30:31+00:00</published>
    <updated>2022-02-09T15:30:31+00:00</updated>
    <id>https://mariomelo.com/3-fake-news-sobre-o-scrum</id>
    <content type="html" xml:base="https://mariomelo.com/3-fake-news-sobre-o-scrum">
      <![CDATA[<p>O Scrum se tornou absurdamente popular, e boa parte desta popularidade se deve a sua simplicidade. Mas, como o Scrum Guide dizia em suas primeiras linhas da versão 2017:</p>

<blockquote>
  <p>Scrum is simple to understand, but difficult to master</p>

  <p><cite>- Scrum Guide, 2017 version</cite></p>
</blockquote>

<p>Ou seja, existe um universo de distância entre entender Scrum e realmente dominá-lo. E é aí que mora o perigo: Esta distância é o habitat perfeito para as vítimas do <a href="https://pt.wikipedia.org/wiki/Efeito_Dunning-Kruger">efeito Dunning Kruger</a>.</p>

<p><img src="../assets/images/posts/cd04250d7c4b.jpeg" alt="Gráfico do efeito Dunning-Kruger" /><em>Imagem criada pelo <a href="http://www.investificar.com.br">www.investificar.com.br</a></em></p>

<p><strong>Do Wikipédia:</strong> <em>O efeito Dunning-Kruger é o fenômeno pelo qual indivíduos que possuem pouco conhecimento sobre um assunto acreditam saber mais que outros mais bem preparados, fazendo com que tomem decisões erradas e cheguem a resultados indevidos; é a sua incompetência que os restringe da habilidade de reconhecer os próprios erros.</em></p>

<p>Dito isto, vamos às três fake news!</p>

<h3 id="1--o-problema-do-scrum-é-que-ele-é-muito-simples">1 — O problema do Scrum é que ele é muito simples</h3>

<p>O Scrum é um framework, mas é comum escutar pessoas se referirem ao Scrum como uma metodologia. Pode parecer implicância minha, mas essa simples troca de palavras diz muito sobre o entendimento do Scrum.</p>

<p>Afinal, o que é um framework? Bem, de acordo com o <a href="https://dictionary.cambridge.org/pt/dicionario/ingles/framework">dicionário de Cambridge</a>:</p>

<blockquote>
  <p><strong>A supporting structure around which something can be built</strong></p>

  <p><cite>- Dicionário de Cambridge</cite></p>
</blockquote>

<p>O Scrum é uma estrutura sobre a qual você deve construir sua maneira de trabalhar. É como o <a href="https://rubyonrails.org/">Ruby on Rails</a>, o <a href="https://expressjs.com/pt-br/">ExpressJS</a> ou o <a href="http://hibernate.org/">Hibernate</a>: eles não funcionam sozinhos, mas te ajudam a trabalhar de uma forma mais estruturada e produtiva.</p>

<p><strong>Frameworks são incompletos por padrão e de propósito</strong>. São criados para que você possa pensar e expandi-los da maneira que fizer mais sentido no seu contexto de trabalho. E é daí que surgem as práticas ágeis como Story Points, User Story Mapping, Priorização por Risco x Valor, User Stories, etc.</p>

<p><img src="../assets/images/posts/5a054b71daa0.png" alt="Ilustração de práticas ágeis complementando o Scrum" /></p>

<p>Como o Scrum implementa o ciclo <a href="https://pt.wikipedia.org/wiki/Ciclo_PDCA">PDCA</a>, é possível adotar uma determinada prática ágil, validar seus efeitos e decidir se vale ou não a pena continuar com aquela prática. E claro, é preciso experimentar novas ideias e repetir esta reflexão ao final de cada Sprint.</p>

<p><strong>Resumindo:</strong></p>

<p>O Scrum é simples e incompleto de propósito para fazer você pensar em maneiras de complementá-lo.</p>

<p>Se alguém lhe disser que o problema do Scrum é ser simples demais, esta pessoa ainda não entendeu nada sobre o framework.</p>

<h3 id="2--management-30-e-devops-vieram-para-substituir-o-scrum">2 — Management 3.0 e DevOps vieram para substituir o Scrum</h3>

<p>Em Minas Gerais temos uma expressão muito utilizada quando alguém diz algo assim:</p>

<p><em><strong>MÉQUÉ???</strong></em> — Do mineirês: como é que é?</p>

<p>Esta afirmação não faz o menor sentido se você já compreendeu o conceito de um framework: Management 3.0 e DevOps chegam para complementar, e não para substituir.</p>

<p><a href="https://scrumguides.org/docs/scrumguide/v2020/2020-Scrum-Guide-PortugueseBR-2.0.pdf">Afinal, o Scrum Guide diz que:</a></p>

<blockquote>
  <p>Os Scrum Teams são estruturados e empoderados pela organização para gerenciar seu próprio trabalho.</p>

  <p><cite> - Scrum Guide, 2017 version</cite></p>
</blockquote>

<p>Sim, o Scrum não fala sobre automatizar deploys, por exemplo. Não fala em feedback wraps, delegation boards ou motivadores intrínsecos.</p>

<p>Porque o Scrum é um… <strong>framework</strong>!</p>

<p>Acredito que esta representação visual utilizada pelo <a href="https://twitter.com/axmagno">Alexandre Magno</a> em seus treinamentos ilustra muito bem esta ideia.</p>

<p><img src="../assets/images/posts/e3337e8091b0.jpeg" alt="Diagrama do framework Scrum com técnicas emergentes" /><em>Representação do framework Scrum completado por técnicas emergentes, criada por Alexandre Magno</em></p>

<h3 id="3--não-temos-mais-times-scrum-temos-squads">3 — Não temos mais times Scrum. Temos Squads.</h3>

<p>Essa é bem interessante, e eu adicionei aqui porque cada vez mais vejo organizações utilizando termos do famoso modelo Spotify. E muitas vezes a justificativa é a de que os times são multidisciplinares e não segmentado por áreas de conhecimento.</p>

<p>Mas, o que o <a href="https://scrumguides.org/docs/scrumguide/v2020/2020-Scrum-Guide-PortugueseBR-2.0.pdf">Scrum Guide</a> diz sobre seu <em>Scrum Team</em>?</p>

<ul>
  <li>
    <p><em>Scrum Teams</em> são multifuncionais, possuindo todas as habilidades necessárias, enquanto equipe, para criar o incremento do Produto.</p>
  </li>
  <li>
    <p>Individualmente os integrantes do <em>Scrum Team</em> podem ter habilidades especializadas e área de especialização, mas a responsabilidade pertence ao <em>Scrum Team</em> como um todo.</p>
  </li>
</ul>

<p>O conceito de Squads nasceu de maneira colaborativa no Spotify e foi parcialmente documentado em 2012 neste pdf <a href="https://twitter.com/henrikkniberg">Henrik Kniberg</a> e <a href="https://twitter.com/anders_ivarsson">Anders Ivarsson</a>. No documento, <a href="https://blog.crisp.se/wp-content/uploads/2012/11/SpotifyScaling.pdf">disponível neste link</a>, eles dizem que:</p>

<p><em>A Squad is similar to a Scrum team, and is designed to feel like a mini-startup. They sit together, and they have all the skills and tools needed to design, develop, test, and release to production. They are a self-organizing team and decide their own way of working.</em></p>

<p>É sempre válido refletir sobre o modelo adotado pela organização:</p>

<ul>
  <li>
    <p>Seu Scrum Team possui as características mencionadas no Scrum Guide?</p>
  </li>
  <li>
    <p>Sua organização provê o ambiente necessário para a existência de Squads/Scrum Teams?</p>
  </li>
  <li>
    <p>Qual problema está sendo atacado com a adoção de Squads?</p>
  </li>
  <li>
    <p>O que diferencia seu Squad de um Scrum Team?</p>
  </li>
</ul>

<p>Os Squads fizeram sentido no contexto de escala do Spotify, e talvez até sejam compatíveis na sua organização. Mas é fundamental compreender quais problemas o Scrum e o “Modelo Spotify” tentam resolver antes de fazer um CTRL+C / CTRL+V.</p>

<p>No final das contas, a desinformação sempre existirá e eventualmente as pessoas podem propagá-la mesmo com a melhor das intenções. A única forma que conheço de evitar essas armadilhas é seguir o conselho do sábio filósofo ET Bilu:</p>

<p><img src="../assets/images/posts/a88da506696d.png" alt="Meme do ET Bilu dizendo busquem conhecimento" /><em>O ET Bilu leria o Scrum Guide antes de começar a usar Scrum</em></p>

<p>E aí, vamos separar um tempinho para reler as <a href="https://scrumguides.org/docs/scrumguide/v2020/2020-Scrum-Guide-PortugueseBR-2.0.pdf">16 páginas do Scrum Guide</a>?</p>
]]>
    </content>
    <author>
      <name>Mario Melo</name>
    </author>
    
    <category term="Teamwork" />
    
    <category term="Scrum" />
    
    <summary type="html">O Scrum se tornou absurdamente popular, e boa parte desta popularidade se deve a sua simplicidade.</summary>
  </entry>
  
  <entry xml:lang="pt">
    <title type="html">Priorizacao com cost of delay</title>
    <link href="https://mariomelo.com/priorizacao-com-cost-of-delay" rel="alternate" type="text/html" title="Priorizacao com cost of delay" />
    <published>2022-02-08T16:42:37+00:00</published>
    <updated>2022-02-08T16:42:37+00:00</updated>
    <id>https://mariomelo.com/priorizacao-com-cost-of-delay</id>
    <content type="html" xml:base="https://mariomelo.com/priorizacao-com-cost-of-delay">
      <![CDATA[<p>Priorizar é uma das atividades mais importantes e difíceis na vida de qualquer Product Owner. Em boa parte das vezes a dificuldade em priorizar ocorre porque as pessoas têm diferentes <em><strong>opiniões</strong></em> sobre os impactos que cada item do Product Backlog pode causar no produto final.</p>

<p>Bom, e esse é o problema. A priorização com base em <em>**opiniões **</em>(que geralmente têm um peso proporcional ao peso do crachá de quem opina). Quando de alguma forma conseguimos tangibilizar o valor de cada item de nosso Product Backlog a discussão se torna muito mais racional.</p>

<p>Uma forma de entender melhor o valor de cada funcionalidade vem através de um simples questionamento: <strong>quanto estamos perdendo por ainda não ter entregue este item?</strong></p>

<p>Responder esta pergunta nem sempre é fácil, e muitas vezes implica em um muito trabalho de pesquisa. O importante é lembrar sempre que nem sempre estamos em busca de uma informação super precisa aqui. O propósito de entender o valor de cada item está em nos ajudar a tomar uma decisão racional.</p>

<p>Por exemplo: digamos que um determinado item vai me render entre R$30.000,00 e R$ 200.000,00. Esta faixa é <strong>muito</strong> ampla e pode parecer ter pouco valor, mas se eu sei que o custo do item não deve exceder R$ 15.000,00 eu já sou capaz de tomar uma decisão e não preciso investir mais tempo refinando minha pesquisa para diminuir este intervalo.</p>

<p><img src="../assets/images/posts/401d8f64d35c.jpeg" alt="Diferentes tipos de custo de atraso" /></p>

<p>Cada item pode ter um custo de atraso em um formato diferente: alguns tendem a crescer linearmente e outros exponencialmente. Há ainda aqueles com uma data fixa, como a adequação a alguma lei com data para entrar em vigor e outros cujo custo não tem uma relação tão relevante com o tempo de atraso. Entender quais tipos de item você tem em seu Product Backlog é o primeiro passo para racionalizar seu processo de priorização.</p>

<p>O tipo de item mais comum de se encontrar em um Product Backlog são aqueles cujo custo de atraso tende a aumentar com o tempo, seja de forma linear ou exponencial. Imagine um produto com os seguintes items em seu Product Backlog:</p>

<p><img src="../assets/images/posts/6e5a2b5187d3.jpeg" alt="Tabela com itens do Product Backlog e seus custos" /></p>

<p>Cada item tem um custo estimado por semana de atraso e um tempo estimado de desenvolvimento. Se dividirmos o custo de atraso pela duração de cada item chegamos ao famoso <strong>CD3: Cost of Delay Divided by Duration</strong> (custo de atraso dividido pela duração).</p>

<p>Mas por que esse tal de CD3 é importante? Para responder essa pergunta, vamos tentar priorizar este backlog de três maneiras diferentes.</p>

<p><strong>Priorização por tamanho</strong></p>

<p>Se optarmos por entregar primeiro os itens menores, nossa curva de entrega ficaria mais ou menos assim:</p>

<p><img src="../assets/images/posts/270bb0046b54.jpeg" alt="Gráfico de priorização por tamanho" /></p>

<p>Na primeira semana teríamos um custo de atraso equivalente a todos os itens somados (2.000 + 5000 + 6000 + 1500), afinal não entregamos nada.</p>

<p>Ao final da semana 1 conseguimos entregar o item <strong>Notificações</strong> (que foi priorizado por ter a menor duração) e com isso diminuímos nosso custo de atraso total em 2.000. E aí é repetimos este processo para os próximos items do Product Backlog.</p>

<p>No final das contas, temos o seguinte cenário:</p>

<ul>
  <li>
    <p>1 semana com custo de atraso total de 14.500</p>
  </li>
  <li>
    <p>2 semanas com custo de atraso total de 12.500</p>
  </li>
  <li>
    <p>3 semanas com custo de atraso total de 11.000</p>
  </li>
  <li>
    <p>4 semanas com custo de atraso total de 6.000</p>
  </li>
</ul>

<p>Neste cenário nosso custo de atraso total foi de:</p>

<p>(1 x 14.500) + (2 x 12.500) + (3 x 11.000) + (4 x 6.000) = <strong>96.500</strong></p>

<p><strong>Priorização por valor</strong></p>

<p>Quando priorizamos por valor a coisa muda um pouco de figura:</p>

<p><img src="../assets/images/posts/98ab79c2b24c.jpeg" alt="Gráfico de priorização por valor" /></p>

<ul>
  <li>
    <p>4 semanas com custo de atraso total de 14.500</p>
  </li>
  <li>
    <p>3 semanas com custo de atraso total de 8.500</p>
  </li>
  <li>
    <p>1 semanas com custo de atraso total de 3.500</p>
  </li>
  <li>
    <p>2 semanas com custo de atraso total de 1.500</p>
  </li>
</ul>

<p>Neste cenário começamos a trabalhar com o item <strong>APP</strong> por ser o que tem o maior custo de atraso por semana. Ao final temos um custo de atraso total de:</p>

<p>(4 x 14.500) + (3 x 8.500) + (1 x 3.500) + (2 x 1.500) = <strong>90.000</strong></p>

<p><strong>Priorização por CD3</strong></p>

<p>A priorização por valor gerou um resultado um pouco melhor, mas ainda temos espaço para melhorias. Veja o que acontece quando priorizamos pelo CD3:</p>

<p><img src="../assets/images/posts/a77c54287629.jpeg" alt="Gráfico de priorização por CD3" /></p>

<ul>
  <li>
    <p>1 semana com custo de atraso total de 14.500</p>
  </li>
  <li>
    <p>3 semanas com custo de atraso total de 12.500</p>
  </li>
  <li>
    <p>4 semanas com custo de atraso total de 7.500</p>
  </li>
  <li>
    <p>2 semanas com custo de atraso total de 1.500</p>
  </li>
</ul>

<p>(1 x 14.500) + (3 x 12.500) + (4 x 7.500) + (2 x 1.500) = <strong>85.000</strong></p>

<p>Uma boa redução não é mesmo? E um ótimo exemplo de como uma pessoa que atua como Product Owner pode causar um impacto muito positivo no desenvolvimento de um produto!</p>

<p><strong>Conclusão</strong></p>

<p>Saber priorizar bem é importante, e para fazer isso sempre vai ser necessário ter uma boa noção do valor de cada item de seu Product Backlog.</p>

<p>Fórmulas como o cálculo do CD3 podem ajudar bastante uma vez que você tenha dado o primeiro passo: ter esta noção de valor. Mas este primeiro passo é muito dependente da aproximação do Product Owner com o mercado e o bom entendimento dos problemas de seus clientes. E bem, para isso não tem uma fórmula mágica. :)</p>
]]>
    </content>
    <author>
      <name>Mario Melo</name>
    </author>
    
    <category term="Teamwork" />
    
    <category term="Prioritization" />
    
    <summary type="html">Priorizar é uma das atividades mais importantes e difíceis na vida de qualquer Product Owner.</summary>
  </entry>
  
  <entry xml:lang="pt">
    <title type="html">Autonomia na Retrospectiva</title>
    <link href="https://mariomelo.com/autonomia-na-retrospectiva" rel="alternate" type="text/html" title="Autonomia na Retrospectiva" />
    <published>2022-02-07T12:04:52+00:00</published>
    <updated>2022-02-07T12:04:52+00:00</updated>
    <id>https://mariomelo.com/autonomia-na-retrospectiva</id>
    <content type="html" xml:base="https://mariomelo.com/autonomia-na-retrospectiva">
      <![CDATA[<p>A <strong>Sprint Retrospective</strong> é um evento que depende demais da participação dos integrantes do time, e às vezes quem assume o papel de <strong>ScrumMaster</strong> precisa tirar um coelho da cartola para sair da mesmice e evitar a passividade do time.</p>

<p>Um jeito simples de fazer isso é ter critérios chave para que o time possa avaliar qualitativamente a <strong>Sprint</strong> que se passou. Mas quais critérios chave devemos utilizar?</p>

<p><strong>Daniel Pink</strong> define através de experimentos em seu livro <strong>Drive</strong> que a Autonomia é um dos três pilares que sustentam a motivação das pessoas no trabalho. Podemos nos valer deste conceito para criar um modelo de retrospectiva mais participativa em 4 passos:</p>

<p><strong>1 — Peça para o time pensar em critérios chave</strong></p>

<p>Estabeleça um limite de tempo curto e escreva juntamente com o time quais fatores influenciam a qualidade do trabalho da equipe.</p>

<p>Lembre-se que a participação de todo o time Scrum é fundamental durante todas as etapas.</p>

<p><strong>2 — Limite os critérios chave</strong></p>

<p>Você pode usar <em><strong>dot voting</strong></em> para limitar os critérios chave que serão utilizados caso seja necessário. O ideal é ter <strong>entre 5 e 10 critérios</strong> ao final desta etapa.</p>

<p><img src="../assets/images/posts/e7e56cb3b051.jpeg" alt="Dot voting em post-its" /></p>

<p><strong>Importante:</strong> Você pode optar por fundir 2 ou mais temas caso eles sejam muito parecidos, apenas lembre-se de fazer isso antes da votação.</p>

<p><strong>3 — Peça para que cada membro do time avalie a última Sprint de acordo com os critérios mais votados</strong></p>

<p>Aqui não precisamos fazer uma análise super detalhada. Podemos utilizar 3 níveis de satisfação, como um semáforo.</p>

<p><strong>Exemplo</strong>: Uma pessoa pode votar <strong>verde</strong> para o critério <strong>Interrupções</strong> se acredita que foi pouco interrompida na Sprint passada.</p>

<p><img src="../assets/images/posts/11e1d3f5f7b4.jpeg" alt="Avaliação em formato de semáforo" /></p>

<p>Apenas atente-se para dois detalhes: certifique-se de que <strong>ninguém</strong> no time tenha dificuldades para distinguir as cores selecionadas e garanta que <strong>todos</strong> os membros avaliaram <strong>todos</strong> os critérios eleitos.</p>

<p><strong>4 — Avalie junto com o time a evolução ao longo das Sprints</strong></p>

<p>Um dos principais benefícios desta técnica é poder debater com o time o que tem influenciado cada a avaliação de cada critério, e ter um pequeno histórico pode ajudar bastante a perceber algumas tendências e possíveis correlações.</p>

<p><img src="../assets/images/posts/cde391c316cd.jpeg" alt="Gráfico de evolução dos critérios ao longo das sprints" /></p>

<p>Olhar para uma avaliação conjunta de critérios que o próprio time estabeleceu é uma ótima forma de quebrar o gelo inicial de uma retrospectiva.</p>

<p>Esse pode ser o empurrãozinho inicial que o time precisa para começar a propor ações e experimentos com potencial para aprimorar sua forma de trabalho.</p>
]]>
    </content>
    <author>
      <name>Mario Melo</name>
    </author>
    
    <category term="Teamwork" />
    
    <category term="Facilitation" />
    
    <summary type="html">A Sprint Retrospective é um evento que depende demais da participação dos integrantes do time, e às vezes quem assume o papel de ScrumMaster precisa t...</summary>
  </entry>
  
  <entry xml:lang="pt">
    <title type="html">Aprendi facilitacao visual em 4 meses e isso mudou tudo o que eu faco</title>
    <link href="https://mariomelo.com/aprendi-facilitacao-visual-em-4-meses" rel="alternate" type="text/html" title="Aprendi facilitacao visual em 4 meses e isso mudou tudo o que eu faco" />
    <published>2022-02-04T15:00:35+00:00</published>
    <updated>2022-02-04T15:00:35+00:00</updated>
    <id>https://mariomelo.com/aprendi-facilitacao-visual-em-4-meses</id>
    <content type="html" xml:base="https://mariomelo.com/aprendi-facilitacao-visual-em-4-meses">
      <![CDATA[<p>Eu sou um desenvolvedor de software que me tornei um trainer de Scrum. Até meados de junho de 2018 eu nunca tinha desenhado absolutamente nada que me desse orgulho. Nada. Mas isso mudou de uma forma incrivelmente rápida.</p>

<h3 id="como-as-coisas-funcionavam">Como as coisas funcionavam</h3>

<p>Desde 2014 eu tenho ministrado turmas da certificação CSD (Certified Scrum Developer), e a minha primeira versão do treinamento era composta por incríveis <strong>271 slides</strong>. Pode parecer um exagero, mas o curso tinha 40 horas de duração divididas em 5 dias. Isso dá aproximadamente um slide para cada 10 minutos de curso.</p>

<p>Na Facta temos vários quadros brancos à disposição no escritório, mas a coisa mais complexa que eu chegava a rabiscar eram fluxogramas com 7 ou 8 etapas.</p>

<h3 id="o-incômodo-com-as-apresentações">O incômodo com as apresentações</h3>

<p>Eu já não estava feliz com o Powerpoint e vivia buscando novas formas de organizar e apresentar o conteúdo dos meus cursos e palestras.</p>

<p>Tentei utilizar o <a href="http://prezi.com/">Prezi</a> e fiquei muito impressionado com os resultados, até me dar conta do tempo que gastava cada vez que precisava criar ou editar uma apresentação.</p>

<p>Aí descobri o <a href="http://haikudeck.com">HaikuDeck</a> e me apaixonei pela abordagem simples, mas acabei largando ele de lado por causa dos tempos de loading e por conta do visual dos arquivos PDF que ele exportava.</p>

<p>Então tentei utilizar o <a href="http://revealjs.com/">reveal.js</a> e achei incrível a idéia de montar minhas apresentações escrevendo arquivos Markdown que eu poderia armazenar em repositórios git (se você não entendeu nada desta última frase, não se preocupe), mas percebi também o quão difícil era rodar a apresentação em outros computadores ou ensinar outras pessoas a editar aqueles arquivos.</p>

<p>Bom, aí eu desisti.</p>

<h3 id="quando-tive-o-estalo">Quando tive o “estalo”</h3>

<p>Em junho de 2018 eu estava explicando um conceito para os alunos de uma turma de CSD em Lisboa e acabei desenhando algo no flipchart. Quando me preparava para virar a página, um dos alunos me pediu para esperar enquanto ele tirava uma foto do desenho que eu havia feito. Obviamente eu deixei que ele tirasse a foto antes de virar a página, mas a vergonha veio assim que percebi qual lembrança ele levaria do meu treinamento:</p>

<p><img src="../assets/images/posts/d83a8b7ba19b.png" alt="Desenho rudimentar de uma estátua com dois postes de luz" />
<em>Acredite ou não, o desenho mostra uma estátua iluminada por dois postes de luz</em></p>

<p>Neste momento decidi que eu <strong>precisava</strong> desenhar um pouco melhor. Pode parecer um tanto quanto óbvio (porque é), mas foi aí que percebi que desenhos poderiam ser uma ótima forma de comunicar ideias e transferir conhecimento para os alunos.</p>

<p>O único problema é que eu não sabia desenhar. Ou pelo menos eu acreditava nisso.</p>

<h3 id="como-comecei-a-aprender">Como comecei a aprender?</h3>

<p><strong>Passo 1</strong>: Assisti a alguns vídeos no do <a href="https://www.youtube.com/user/VisionLearning">Graham Shaw no YouTube</a> (<a href="https://www.youtube.com/watch?v=7TXEZ4tP06c">este aqui</a> em particular foi o que mais me chamou a atenção)</p>

<p><strong>Passo 2:</strong> Comprei um cursona Udemy, chamado <a href="https://www.udemy.com/drawing-for-trainers-leaders-and-presenters/">Drawing for trainers, leaders and presenters</a>, do Alex Glod</p>

<p><strong>Passo 3:</strong> Comprei um iPad Pro e um iPencil</p>

<p>Tudo bem, eu comprei muitas coisas e algumas delas não são exatamente baratas. Mas elas serviram para acelerar meu processo de aprendizado, e depois de um mês tempo eu já era capaz de fazer algo assim:</p>

<p><img src="../assets/images/posts/65c3b4e601fe.png" alt="Desenho no iPad de pessoa olhando no espelho" />
<em>Sim, o reflexo no espelho está errado, eu sei :)</em></p>

<p>Eu estava quase confortável o suficiente para testar meus desenhos na sala de aula, e havia decidido que eu faria um experimento na minha próxima turma: não usaria nenhum slide. Aliás, eu <strong>nem levaria o computador para o treinamento</strong>.</p>

<p>Mas antes disso eu testei minha nova habilidade em um Factalk, uma apresentação de 30 minutos que fazemos na Facta às sexta-feiras. Afinal, eu definitivamente não encontraria um ambiente mais seguro que esse para fazer este experimento.</p>

<p><img src="../assets/images/posts/709d79799f44.jpeg" alt="Múltiplos slides de papel colados na parede" />
<em>Quantos “slides” você consegue ver de uma só vez?</em></p>

<p>E no segundo mês de aprendizado eu adicionei pincel preto, papel, giz de cera e fita adesiva ao meu arsenal.</p>

<p>No final da sessão, 19 “slides” ficaram visíveis ao mesmo tempo na parede ao lado do fliperama, e a interação entre os participantes foi muito mais natural. Se a apresentação fosse em formato digital apenas 1 slide estaria visível por vez, ou seja, aproximadamente <strong>5% do conteúdo</strong>. Ou no caso do meu CSD com 217 slides, <strong>menos de 0,5%</strong>.</p>

<p>O feedback que tive depois desta apresentação me deu a confiança que faltava para testar esta abordagem na minha próxima turma.</p>

<h3 id="a-primeira-turma-sem-slides">A primeira turma sem slides</h3>

<p>O notebook saiu da mochila e deu espaço às canetas e conjuntos de giz de cera, e depois de 10 horas de vôo eu estava confiante para testar minhas habilidades pela primeira vez. Bem… mais nervoso do que confiante, mas <strong>pronto</strong>.</p>

<p>Logo no começo da minha primeira turma sem slides reparei um grande benefício sobre as aulas sem slides: várias dependências foram removidas quando deixei o computador em casa.</p>

<ul>
  <li>Preciso levar um adaptador HDMI-VGA?</li>
  <li>O projetor usa formato 4:3 ou 16:9?</li>
  <li>Que tipo de tomada eles usam neste país? Será que o WiFi lá funciona bem e sem restrições de acesso?
<br /><br /></li>
</ul>

<p>Não era incomum precisar pedir socorro durante os treinamentos em função destes detalhes. Certa vez em 2014 um projetor parou de funcionar e acabou atrasando e desmotivando consideravelmente uma turma minha.</p>

<p>Mas com papel, canetas e giz de cera eu tinha uma preocupação a menos. E com eles, eu podia <strong>criar meus slides sob demanda</strong>.</p>

<p><img src="../assets/images/posts/54b2912e8b36.png" alt="Desenho com margens e elementos conectados" />
<em>Comecei a usar margens e conectar elementos, mas as cores…</em></p>

<p>Eu mantive o time que estava ganhando e não usei nada além de caneta preta e giz de cera, mas comecei a arriscar novos formatos e a juntar formas (como o boneco carregando a caixa 21).</p>

<p>Criar slides sob demanda foi um novo benefício que percebi neste tipo de apresentação. Às vezes os alunos perguntam algo que está respondido em um determinado slide da apresentação, e ao invés de navegar pela apresentação para descobrir se o slide em questão é o 37 ou 129 eu podia apenas caminhar pela sala e apontar para uma folha colada na parede para recapitular os conceitos do mesmo. Ou desenhar uma nova folha caso fosse necessário.</p>

<p>Outras duas situações me chamaram a atenção durante esta turma:</p>

<ul>
  <li>Um aluno precisou voltar mais tarde do almoço, e quando voltou notou que havia uma folha nova colada na parede. Ele imediatamente me perguntou se eu podia resumir o que havia sido explicado ali.<br /><br /></li>
  <li>Como o treinamento em questão tinha 2 dias de duração, os alunos utilizavam os primeiros 5 minutos da segunda manhã caminhando pela sala e relembrando os conceitos resumidos em cada flipchart colado nas paredes.</li>
</ul>

<p><strong>Os desenhos não eram obras de arte, eles apenas comunicavam idéias de uma maneira agradável e eficaz.</strong></p>

<p>Eu fiquei impressionado com o feedback que recebi desta turma. Apesar dos desenhos serem extremamente rudimentares, todos os estudantes citaram o formato do treinamento em um tom muito positivo. Isso me motivou a tentar levar essa nova habilidade para um próximo nível.</p>

<h3 id="o-próximo-passo">O próximo passo</h3>

<p>No quarto mês eu já tinha adquirido algum vocabulário visual, mas me faltava tratar melhor as cores e a organização de idéias no flipchart. Foi então que ganhei da minha namorada <a href="https://eu.neuland.com/literature/specialist-books/uzmo-thinking-with-your-pen-english.html">um livro chamado UZMO</a>, do Martin Haussmann. Comprei também um conjunto de canetas da Neuland e comecei a estudar a técnica Bikablo.</p>

<p>Além de aprender mais sobre cores e organização de idéias, descobri que o <strong>cinza é a cor mais importante para se ter na caixa de ferramentas</strong>. Ele me ajudou a compor e sobrepor novos símbolos, e transformou cada flipchart meu em uma espécie de infográfico capaz de resumir os conceitos que eu transmitia de uma forma nova e extremamente agradável.</p>

<p><img src="../assets/images/posts/6fdde2d5137a.jpeg" alt="Flipchart português sobre Team Building com cores e organização" />
<em>Menos cores, mais informações e muita composição</em></p>

<p>Em 4 meses eu deixei de ter vergonha dos meus desenhos e passei a ver pessoas guardando os flipcharts ao final das turmas para decorar o escritório onde trabalham.</p>

<p>Levou algum tempo e esforço, mas foi <strong>muito mais rápido do que eu imaginava</strong>. Na verdade, eu nem imaginava que isto seria possível.</p>

<p>Atualmente eu desenho para tomar notas durante reuniões, durante meus treinamentos, ilustro minhas próprias apostilas e até crio apresentações desta maneira.</p>

<p>Eu precisei de 4 meses para sair da primeira foto deste post e chegar até a última. Eu sei que ainda há muito a ser aprimorado, mas tenho certeza de que compartilhar este progresso pode motivar várias pessoas que acreditam cegamente que “<strong>não sabem desenhar</strong> ”.</p>

<p>Se você é uma dessas pessoas, eu lhe desafio a fazer um teste.</p>

<p>E espero ver um de seus desenhos daqui há 4 meses!</p>

<h3 id="resumindo">RESUMINDO</h3>

<p>1- Você consegue desenhar, só precisa de prática.</p>

<p>2- Assista aos vídeos do <a href="https://www.youtube.com/user/VisionLearning">Graham Shaw no YouTube</a></p>

<p>3- Construa seu Vocabulário Visual (<a href="https://www.udemy.com/course/drawing-for-trainers-leaders-and-presenters/">talvez com este curso</a>)</p>

<p>4- Pesquise sobre a técnica Bikablo na internet</p>

<p>5- Seu objetivo é comunicar idéias de maneira rápida e eficaz, não fazer arte. Não tente ser melhor que o Leonardo da Vinci.</p>

<p>6- Pesquise e siga Graham Shaw, Alex Glod and Martin Haussmann.</p>

<p>7- Compre um pincel preto, um caderno sem pautas, um conjunto de giz de cera e pratique cerca de 30 minutos por dia.</p>

<p>PS: Quase um ano se passou desde que escrevi o post original em inglês. De lá pra cá, eu criei e ilustrei um <a href="https://scrumchkin.com/">jogo de cartas para ensinar Scrum</a> e gravei cursos ilustrados sobre agilidade em parceria <a href="https://emergee.com.br/">Emergee</a> e <a href="https://alura.com.br/">Alura</a> que hoje contam com mais de 70 mil alunos inscritos!</p>

]]>
    </content>
    <author>
      <name>Mario Melo</name>
    </author>
    
    <category term="Building" />
    
    <category term="Learning" />
    
    <summary type="html">NOTA : Aprender é um ato contínuo, e este texto conta somente o trecho inicial da jornada.</summary>
  </entry>
  
  <entry xml:lang="pt">
    <title type="html">Os perigos da cultura da perfeicao</title>
    <link href="https://mariomelo.com/os-perigos-da-cultura-da-perfeicao" rel="alternate" type="text/html" title="Os perigos da cultura da perfeicao" />
    <published>2022-02-04T14:52:36+00:00</published>
    <updated>2022-02-04T14:52:36+00:00</updated>
    <id>https://mariomelo.com/os-perigos-da-cultura-da-perfeicao</id>
    <content type="html" xml:base="https://mariomelo.com/os-perigos-da-cultura-da-perfeicao">
      <![CDATA[<p>Michael Caine como Alfred Pennyworth</p>

<p><em>Este texto é uma tradução de um post escrito por mim em 2014 aqui no Medium, em inglês. Link original: <a href="https://medium.com/@melomario/the-dangerous-failure-shaming-culture-49fc07093fde">Medium</a></em></p>

<h3 id="errar-ou-não-errar-eis-a-questão">Errar ou não errar, eis a questão</h3>

<p>Enquanto seres humanos, todos somos propensos ao erro. No entanto, muitos têm dificuldade de aceitar isso.</p>

<p>Quando você dá o seu melhor para alcançar um objetivo e eventualmente as coisas não saem como o planejado, o que acontece?</p>

<p>Você já se prepara para algum tipo de penalidade que vem pelo caminho?</p>

<h3 id="ambientes-sem-espaço-para-erros">Ambientes sem espaço para erros</h3>

<p>Qualquer que seja sua resposta para a pergunta, ela foi pelo menos parcialmente criada pelo ambiente no qual você viveu até agora.</p>

<p>Você foi livre o bastante para <strong>falhar</strong> enquanto era jovem?</p>

<p>Você trabalha em uma empresa onde as pessoas são punidas quando se <strong>enganam</strong>?</p>

<p>Você se sente confortável quando encara pessoas que <strong>decepcionou</strong>?</p>

<p>Um ambiente onde falhas não são toleradas limita experimentos: tudo precisa dar certo, e quando isto não acontece alguma pessoa será penalizada. Esta penalidade pode vir em forma de demissão, palmadas dos pais ou até mesmo o fim de relacionamentos.</p>

<p>Você sabe bem do que estou falando.</p>

<blockquote>
  <p>Você está errado. Que vergonha!</p>

  <p><cite>- Nós mesmos</cite></p>
</blockquote>

<p>Se você já passou por este tipo de ambiente (e as chances são bem grandes) você sabe o quanto precisa pensar e calcular antes de dar cada passo para frente. Ou para trás. Você precisa pensar e repensar cada movimento, pois se você falhar a punição estará logo ali lhe esperando.</p>

<h3 id="as-consequências-das-condenações">As consequências das condenações</h3>

<p>Bem, <em>se você olhar na face do mal, o mal estará olhando de volta para você</em>. E quando lhe tiram o direito de falhar você pode começar a achar isso natural e replicar o mesmo comportamento.</p>

<p>Digo isso porque isso aconteceu comigo, e na medida em que comecei a tentar reverter o problema percebi algumas consequências diretas deste tipo de cultura.</p>

<h3 id="estagnação">Estagnação</h3>

<p>Nós geralmente evoluímos por tentativa e erros. E aceitamos conceitos aprendidos na prática mais facilmente do que aqueles aprendidos pela teoria.</p>

<blockquote>
  <p>Por que nós caímos, mestre Bruce? Para podermos aprender a nos levantar novamente.</p>

  <p><cite>- Alfred Pennyworth</cite></p>
</blockquote>

<p>Na empresa onde trabalho estamos sempre nos incentivando a tentar coisas novas. Independentemente do que venha à cabeça, todos se sentem livre para propor e contestar idéias com qualquer um. Falhas são toleradas desde que possamos aprender alguma coisa com elas, e isto nos tem feito evoluir de maneira rápida e constante.</p>

<p>Se ninguém tivesse esta liberdade para falhar, perderíamos nossa autonomia e auto-confiança para tentar novas idéias e provavelmente ainda estaríamos presos em 2011 (Data de fundação da empresa).</p>

<h3 id="procrastinação">Procrastinação</h3>

<p>Eu não posso falhar, então preciso trabalhar nisto até ficar <strong>perfeito</strong>. E não importa quanto tempo leve.</p>

<blockquote>
  <p>Eu quero um novo engano, perder é melhor que hesitar</p>

  <p><cite> <em>— Queens of the Stone Age</em> </cite></p>
</blockquote>

<p>Certa vez trabalhei em um projeto que visava aprimorar um indicador interno de uma empresa de 10% para 90%. Depois de 5 meses de trabalho o projeto já era capaz de aumentar o indicador para algo próximo de 65% <strong>caso fosse implantado</strong>.</p>

<p>Os responsáveis pelo projeto preferiram não implantar enquanto não fosse possível chegar os 90% desejados. <strong>Isto durou 2 anos inteiros</strong>.</p>

<p>Durante 2 anos a empresa continuou com seu indicador na casa dos 10% enquanto poderia ter algo próximo de 65% porque ninguém quis dizer “ <em>Ei, ainda não foi possível chegar nos 90%, mas podemos começar com 65% e evoluir aos poucos</em> ”.</p>

<p>E provavelmente teriam alcançado os 90% muito mais rapidamente se tivessem arriscado.</p>

<p>Mas falhar era pesado demais. E demorar pra falhar faz com que demoremos para evoluir.</p>

<h3 id="mentiras-e-apatia">Mentiras e Apatia</h3>

<p>A casa está em chamas mas ninguém tem coragem de chamar os bombeiros. Inclusive, parece que jogaram o isqueiro fora porque ele poderia ligar alguém ao foco do incêndio.</p>

<blockquote>
  <p>Não fui eu</p>

  <p><cite>- Shaggy</cite></p>
</blockquote>

<p>É difícil encontrar alguém com mais informações sobre um problema do que a pessoa que o criou inicialmente. Se esta pessoa se sentir confortável o suficiente para assumir o erro, sua ajuda pode ser crucial para a solução do mesmo.</p>

<p>Quando não há espaço para erros eles não desaparecem, <strong>eles apenas somem de vista</strong>: vão para debaixo do tapete.</p>

<p>É por isso que retrospectivas são essenciais: elas abrem um espaço para falarmos sobre nossos erros e aprender com eles. É onde aprendemos a limpar a poeira que às vezes fica acumulada embaixo do tapete.</p>
]]>
    </content>
    <author>
      <name>Mario Melo</name>
    </author>
    
    <category term="Teamwork" />
    
    <category term="Culture" />
    
    <summary type="html">Michael Caine como Alfred Pennyworth</summary>
  </entry>
  
</feed>
