<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lucas Coelho</title>
    <description>The latest articles on DEV Community by Lucas Coelho (@lcoelho_dev).</description>
    <link>https://dev.to/lcoelho_dev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F906538%2F8ffc7d2f-95cf-45de-ad17-c5e448fab7bf.png</url>
      <title>DEV Community: Lucas Coelho</title>
      <link>https://dev.to/lcoelho_dev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lcoelho_dev"/>
    <language>en</language>
    <item>
      <title>Fitness Functions - O Check-up contínuo de seu Software</title>
      <dc:creator>Lucas Coelho</dc:creator>
      <pubDate>Thu, 20 Mar 2025 08:00:00 +0000</pubDate>
      <link>https://dev.to/lcoelho_dev/fitness-functions-o-check-up-continuo-de-seu-software-13k4</link>
      <guid>https://dev.to/lcoelho_dev/fitness-functions-o-check-up-continuo-de-seu-software-13k4</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Para esta primeira publicação, quero começar com algo que venho lendo atualmente: o livro &lt;em&gt;Arquitetura de Software: As Partes Difíceis&lt;/em&gt;. Esse livro me fez perceber que já aplicava alguns conceitos sem conhecê-los formalmente. Você já teve essa sensação ao ler algo e notar que já fazia aquilo intuitivamente? 😬&lt;/p&gt;

&lt;h2&gt;
  
  
  O que são Fitness Functions? 👋
&lt;/h2&gt;

&lt;p&gt;No capítulo 1 do livro, é mencionado o conceito de Fitness Functions, que foi popularizado pelo livro Building Evolutionary Architectures (Neal Ford, Rebecca Parsons e Patrick Kua).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;trecho do livro&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Eles definiram o conceito de uma fitness function de uma arquitetura: qualquer mecanismo que realize uma avaliação objetiva da integridade de alguma característica da arquitetura ou a combinação de características da arquitetura".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nada mais são do que mecanismos, automatizados ou não, que medem continuamente a qualidade de um aspecto arquitetural de um sistema. A ideia é definir métricas que garantam que a arquitetura evolua de forma controlada, sem degradar características essenciais. São feitas verificações contínuas para testar se um sistema ainda está "em forma" (fitness), em relação a critérios como performance, segurança, modularidade, disponibilidade, entre outros.&lt;br&gt;
Pensando nas funcionalidades core ou críticas do sistema.  &lt;/p&gt;
&lt;h2&gt;
  
  
  Exemplos de Fitness Functions
&lt;/h2&gt;

&lt;p&gt;Abaixo, listo algumas categorias onde Fitness Functions podem ser aplicadas, trazendo exemplos concretos para facilitar a compreensão e implementação.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhf1cg0q44uorjp9rb1yr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhf1cg0q44uorjp9rb1yr.png" alt="Code Quality" width="800" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Porque fitness functions pode ajudar nesta etapa? Quais fitness functions podemos criar para garantir uma qualidade do software?&lt;/p&gt;

&lt;p&gt;Durante o desenvolvimento, Fitness Functions podem ser usadas para garantir padrões de qualidade e facilitar a manutenção do código.&lt;br&gt;
Criar Fitness Functions para garantir a qualidade do software pode trazer alguns benefícios para manutenibilidade do código, organizado e fácil de entender, código bem separado em módulos reutilizáveis e etc. e também ajuda a novos membros na equipe a seguir os padrões já definidos, garantindo por exemplo que as camadas da aplicação sejam respeitadas.&lt;/p&gt;

&lt;p&gt;Pensando nas fitness functions para garantir a qualidade de código, podemos criar as seguintes:&lt;/p&gt;
&lt;h2&gt;
  
  
  Fitness Functions Code Quality
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Cobertura de testes unitários nunca fique abaixo de um certo limite. &lt;a href="https://www.eclemma.org/jacoco" rel="noopener noreferrer"&gt;Jacoco&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Linters e analisadores de código estático para garantir padrões de nomenclatura e evitar complexidade excessiva. &lt;a href="https://github.com/google/google-java-format" rel="noopener noreferrer"&gt;Google Java format&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Testes unitários para garantir que módulos em um projeto não criem dependências circulares ou até mesmo não crie acoplamentos desnecessários &lt;a href="https://www.archunit.org" rel="noopener noreferrer"&gt;ArchUnit&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No livro ele menciona uma biblioteca em Java, o que achei bem interessante, realizar testes unitários para validar camadas ou até boas práticas de programação pode ajudar no processo de desenvolvimento e prevenir essas analises no processo de code review. (um passo a menos) &lt;/p&gt;

&lt;p&gt;Abaixo, um exemplo de código em Java usando para verificar se os tratamentos de erro estão sendo feitos corretamente, sem exceções genéricas, e se as camadas Controller, Usecases e Gateways estão sendo respeitadas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@AnalyzeClasses&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;packages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"com.coelho.api"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ModuleTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@ArchTest&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;ArchRule&lt;/span&gt; &lt;span class="n"&gt;no_throw_generic_exceptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;NO_CLASSES_SHOULD_THROW_GENERIC_EXCEPTIONS&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@ArchTest&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;ArchRule&lt;/span&gt; &lt;span class="n"&gt;layer_dependencies_are_respected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;layeredArchitecture&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;consideringAllDependencies&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;layer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Controllers"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;definedBy&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.coelho.api.controllers.."&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;layer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Usecases"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;definedBy&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.coelho.api.usecases.."&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;layer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Gateways"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;definedBy&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.coelho.api.gateways."&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;whereLayer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Controllers"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;mayNotBeAccessedByAnyLayer&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;whereLayer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Usecases"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;mayOnlyBeAccessedByLayers&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Controllers"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;whereLayer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Gateways"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;mayOnlyBeAccessedByLayers&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Usecases"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr6vb2v5al3ax1nhalb90.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr6vb2v5al3ax1nhalb90.png" alt="Security" width="800" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Security é uma parte importante não podemos esquece-las e Fitness Functions com processos automatizados nos previnem de vulnerabilidades.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fitness Functions Security
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Vulnerabilidades em dependências. &lt;a href="https://github.com/dependency-check/dependency-check-gradle" rel="noopener noreferrer"&gt;OWASP&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Exposição de dados sensíveis. &lt;a href="https://github.com/gitleaks/gitleaks" rel="noopener noreferrer"&gt;Gitleaks&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Codigo com falhas de segurança. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faibz7s138hfwkx9f4afg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faibz7s138hfwkx9f4afg.png" alt="Performance" width="800" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A perfomance ou saúde do sistema tenho na minha visão que é o ponto chave se não tem algo funcionando alguém vai te chamar!! E não queremos isso haha&lt;br&gt;
Ela pode ser analisada de várias maneiras, porém vou dar um foco para a ferramenta &lt;a href="https://opentelemetry.io/" rel="noopener noreferrer"&gt;Open Telemtry&lt;/a&gt;, ela nasceu no projeto Cloud Native Foundation totalmente Open Source e bem consolidada. Na real eles padronizaram as APIs para que seja analogo a implementação para que você seja livre de trocar as ferramentas onde analisa os dados, seja Jaeger ou zipkin, Loki ou Kibana, enfim... A observabilidade pode nos mostrar se a aplicação esta saúdavel ou não, temos muitas métricas para analisar isso porém vou deixar algumas para exemplificar: &lt;/p&gt;

&lt;h2&gt;
  
  
  Fitness Functions Performance
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://opentelemetry.io/" rel="noopener noreferrer"&gt;Open Telemtry&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monitoramento para garantir tempos de resposta aceitáveis. (ex: P95 &amp;lt; 500ms)&lt;/li&gt;
&lt;li&gt;Controle da taxa de erros 5xx.&lt;/li&gt;
&lt;li&gt;Monitoramento de CPU e memória.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;increase(http_server_request_duration_seconds_count{http_server_request_duration_seconds_count=~"5.."}[5m]) &amp;gt;= 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;histogram_quantile(0.95, rate(http_server_request_duration_seconds_bucket[5m])) &amp;gt; 0.5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) &amp;gt; 80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Bom, depois dos exemplos acima, espero que você tenha tido ideias para incluí-las nos seus projetos (eu espero que sim hahaha). já utilizamos esses conceitos sem percebê-los formalmente, como alertas automáticos sobre problemas na saúde da aplicação.&lt;/p&gt;

&lt;p&gt;O ideal é identificar pontos críticos de uma aplicação e criar Fitness Functions para avaliá-los. Sempre tenha objetivos e métricas claras. Exemplo: O tempo de resposta do serviço Y deve ser menor que 300ms em 95% das requisições. A observabilidade do sistema é muito importante (isso é até um spoiler do próximo conteúdo 🫢). Porém também é importante avaliar os casos, não queremos trazer mais complexidas no desenvolvimento e deixar algo ingesado por isso é bom ponderar.&lt;/p&gt;

&lt;p&gt;Espero que esta publicação sobre Fitness Functions tenha sido útil para você! Se você já usa algo parecido ou tem outras ideias, compartilhe nos comentários! 🚀&lt;/p&gt;

</description>
      <category>softwarequality</category>
      <category>bestpractices</category>
      <category>fitnessfunctions</category>
      <category>observability</category>
    </item>
  </channel>
</rss>
