<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Raffael Eloi</title>
    <description>The latest articles on Forem by Raffael Eloi (@raffaeleloi).</description>
    <link>https://forem.com/raffaeleloi</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%2F939281%2Ff5257644-7bfd-4fd9-a2a7-7d33d1ec4598.jpeg</url>
      <title>Forem: Raffael Eloi</title>
      <link>https://forem.com/raffaeleloi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/raffaeleloi"/>
    <language>en</language>
    <item>
      <title>Stop Using Switch Statements: Keyed Services in .NET - A Practical Approach</title>
      <dc:creator>Raffael Eloi</dc:creator>
      <pubDate>Fri, 06 Mar 2026 00:09:04 +0000</pubDate>
      <link>https://forem.com/raffaeleloi/stop-using-switch-statements-keyed-services-in-net-a-practical-approach-iej</link>
      <guid>https://forem.com/raffaeleloi/stop-using-switch-statements-keyed-services-in-net-a-practical-approach-iej</guid>
      <description>&lt;p&gt;Have you heard of Keyed Services? Do you know when to use them? Have you ever needed multiple implementations of the same interface and ended up writing a big &lt;code&gt;switch&lt;/code&gt; or &lt;code&gt;if-else&lt;/code&gt; block to decide which one to use?&lt;/p&gt;

&lt;p&gt;Today, I'll show you a new tool for your software engineering toolbox and a hands-on approach using a POC project on my GitHub, where you can see the full implementation.&lt;/p&gt;

&lt;p&gt;In this article, I'll show you how Keyed Services work and how they can simplify event-driven designs using a practical example.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Keyed Services?
&lt;/h2&gt;

&lt;p&gt;Before .NET 8, registering multiple implementations of the same interface was possible, but resolving a specific implementation was not straightforward.&lt;/p&gt;

&lt;p&gt;Typically, you would inject IEnumerable and manually choose the correct implementation using conditions or metadata.&lt;/p&gt;

&lt;p&gt;But with Keyed Services, a built-in dependency injection feature introduced in .NET 8, you can register multiple classes for the same interface using a key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is that important?
&lt;/h2&gt;

&lt;p&gt;There are scenarios where we can reduce the number of if-else statements and achieve a cleaner solution using these keys.&lt;/p&gt;

&lt;p&gt;Especially when handling events, we can build a solid implementation that is easy to extend using Keyed Services.&lt;/p&gt;

&lt;h2&gt;
  
  
  When should you use Keyed Services?
&lt;/h2&gt;

&lt;p&gt;Keyed Services are useful when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have multiple implementations of the same interface&lt;/li&gt;
&lt;li&gt;The correct implementation depends on runtime data&lt;/li&gt;
&lt;li&gt;You want to avoid switch / if-else logic&lt;/li&gt;
&lt;li&gt;You want a solution that is easy to extend&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Common scenarios include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Event handlers&lt;/li&gt;
&lt;li&gt;Notification channels (Email, SMS)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How does it work?
&lt;/h2&gt;

&lt;p&gt;Bear with me for this example:&lt;/p&gt;

&lt;p&gt;I have an EventHandlerFactory that receives an event and then redirects it to the responsible handler.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Incoming Event
      │
      ▼
EventHandlerFactory
      │
      ▼
Keyed DI Resolution
      │
      ▼
Specific EventHandler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's an interface that represents that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IEventHandlerFactory&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;HandleEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;eventName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;eventData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each event handler should implement this interface&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IEventHandler&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;HandleAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;eventData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's create three event handlers for our mock scenario: PurchaseOrderEventHandler, InvoiceEventHandler, and PaymentEventHandler.&lt;/p&gt;

&lt;p&gt;Each handler will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentEventHandler&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IEventHandler&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;HandleAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;eventData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Implement the logic to handle payment events here&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CompletedTask&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, here's the first implemenation of the &lt;code&gt;EventHandlerFactory&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EventHandlerFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceProvider&lt;/span&gt; &lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IEventHandlerFactory&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;PurchaseOrder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"PurchaseOrder"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;PaymentProcessed&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"PaymentProcessed"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;InvoiceProcessed&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"InvoiceProcessed"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IServiceProvider&lt;/span&gt; &lt;span class="n"&gt;_serviceProvider&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;HandleEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;eventName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;eventData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;CancellationToken&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eventName&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;PurchaseOrder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;IEventHandler&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetRequiredKeyedService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IEventHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;PurchaseOrder&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;HandleAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eventData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eventName&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;PaymentProcessed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;IEventHandler&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetRequiredKeyedService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IEventHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;PaymentProcessed&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;HandleAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eventData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eventName&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;InvoiceProcessed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;IEventHandler&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetRequiredKeyedService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IEventHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;InvoiceProcessed&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;HandleAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eventData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;


        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;InvalidOperationException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"No handler found for event: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;eventName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For dependency injection, the only thing we need to do is pass the key when registering the dependency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;serviceCollection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddKeyedScoped&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IEventHandler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PurchaseOrderEventHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;EventHandlerFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PurchaseOrder&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;serviceCollection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddKeyedScoped&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IEventHandler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PaymentEventHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;EventHandlerFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PaymentProcessed&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;serviceCollection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddKeyedScoped&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IEventHandler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;InvoiceEventHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;EventHandlerFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InvoiceProcessed&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a good implementation. We can clearly see which event handler is responsible for each eventName. However, we can make it even better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EventHandlerFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IKeyedServiceProvider&lt;/span&gt; &lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IEventHandlerFactory&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;HandleEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;eventName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;eventData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;CancellationToken&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;IEventHandler&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetRequiredKeyedService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IEventHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;eventName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;HandleAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eventData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;I hope you learned something new today. This concept was pretty new to me until a couple of weeks ago.&lt;/p&gt;

&lt;p&gt;Here's the repository with the full implementation of the POC scenario:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Raffael-Eloi/keyed-services-poc" rel="noopener noreferrer"&gt;https://github.com/Raffael-Eloi/keyed-services-poc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, feel free to follow me on GitHub and LinkedIn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Github: &lt;a href="https://github.com/Raffael-Eloi" rel="noopener noreferrer"&gt;https://github.com/Raffael-Eloi&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Linkedin: &lt;a href="https://linkedin.com/in/raffael-eloi" rel="noopener noreferrer"&gt;https://linkedin.com/in/raffael-eloi&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;My site: &lt;a href="https://raffaeleloi.dev" rel="noopener noreferrer"&gt;https://raffaeleloi.dev&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you enjoy topics like this, follow me here or connect with me on LinkedIn. I regularly share content about .NET, software architecture, and engineering practices.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>programming</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>The cost of AI in your career</title>
      <dc:creator>Raffael Eloi</dc:creator>
      <pubDate>Thu, 22 Jan 2026 09:41:52 +0000</pubDate>
      <link>https://forem.com/raffaeleloi/the-cost-of-ai-in-your-career-dfe</link>
      <guid>https://forem.com/raffaeleloi/the-cost-of-ai-in-your-career-dfe</guid>
      <description>&lt;p&gt;For the past three years, we have been in the AI era. In the beginning, it was hard to adopt AI, and only a small portion of people were using it, but now it is the biggest trend, and is present in almost all areas.&lt;/p&gt;

&lt;p&gt;I remember when I was in college and we started using AI in our subjects. At the time, the answers were not very good and were followed by a lot of mistakes. However, my teachers were already predicting that this would be the "future of search". &lt;/p&gt;

&lt;p&gt;I believe AI is really powerful, and also can improve your productivity, but, it can also be your downfall. Using AI in the way that I see many people using it can cause long-term damage that, unfortunately, they are not even aware of.&lt;/p&gt;

&lt;p&gt;The cliché, but still relevant quote: "With great power comes great responsibility".&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn by doing
&lt;/h2&gt;

&lt;p&gt;How many times in your life you truly learned something just by listening to it? or even by reading it? or only by passively watching things get done?&lt;/p&gt;

&lt;p&gt;My first question right here is: How much can we learn by passively watching AI do everything? &lt;/p&gt;

&lt;p&gt;I think this question can be broken down into different levels. &lt;/p&gt;

&lt;p&gt;If you have never done something and you ask AI to do everything for you, I really believe you cannot extract much from that experience. I'm going to use programming as an example: if you want to create something from scratch and you do not fully know how to do it, using AI to build everything for you is a very bad long-term choice.&lt;/p&gt;

&lt;p&gt;All the learning that comes from making mistakes is gone, and you may start thinking that everything works like magic all the time, which is definitely not true.&lt;/p&gt;

&lt;p&gt;When we delegate the possibility to learn something new to AI, we are also delegating mistakes, risks, fun, knowledge, confidence, mindset and growth.&lt;/p&gt;

&lt;p&gt;You make your choices, and then your choices make you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Curiosity and Critical thinking
&lt;/h2&gt;

&lt;p&gt;Are you only interested in getting things done, or do you also care about &lt;strong&gt;how&lt;/strong&gt; things get done? How do you know the way you did something was the best choice? How can you know different approaches?&lt;/p&gt;

&lt;p&gt;Unfortunately, this topic is not discussed as much anymore. I think the fast-delivery industry is trying to shut this topic down, this is no longer how the world wants to work. I can see a tendency to get things done as quickly as possible, and this approach bypasses critical thinking. The end result? A long-term damage, as we discussed.&lt;/p&gt;

&lt;p&gt;In the new AI world, we do have more power in our hands, but what the industry seems to care about most is velocity, and the number of things we can get done. At this pace, using AI, we are producing bad outputs, and the reason is easy to find: We don't want to think anymore.&lt;/p&gt;

&lt;p&gt;But why would we think? We have a tool that builds everything we want, why would we care about that?&lt;/p&gt;

&lt;p&gt;If you want to overcome this new tendency, here are a few things you can do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learn how the sausage is made&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do not take every answer or output for granted. Learn the pros and cons of the choice and understand why that choice was made. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do not take the easy road&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is very easy to see things working without thinking about how they work, but don't do that, swim against the tide, learn the basics behind what you are building, try to go deeper, read books, take notes yourself.&lt;/p&gt;

&lt;p&gt;Sometimes, it is better to do something manually that you have never done than to use AI and extract nothing from the experience you had. &lt;/p&gt;

&lt;p&gt;When was the last time you did something by yourself? How long has it been since you wrote something yourself, really paying attention to every detail, instead of writing the minimum possible version and asking AI to improve it?&lt;/p&gt;

&lt;h2&gt;
  
  
  Developer vs User
&lt;/h2&gt;

&lt;p&gt;This section is more related to the software engineering area. &lt;/p&gt;

&lt;p&gt;As developers, we build software and solve things that do not necessarily involve code. At the same time, writing code, in most cases, is the biggest part of our job. &lt;/p&gt;

&lt;p&gt;The question, "How do you spend most of your time, as a developer or as a user?", which I heard during a college seminar presentation, has stuck with me since then. I remember taking some actions in my career after hearing it, it made me realize that I wanted to invest more time thinking and building things as a producer, and not as a consumer of the technology.&lt;/p&gt;

&lt;p&gt;When we delegate everything to AI, we put ourselves back into the consumer/user perspective again. Sometimes, we give up our greatest power.&lt;/p&gt;

&lt;p&gt;I was making some commits using the github interface, and when I was creating a pull request, Copilot suggested a commit message. At first glance, I thought, "that's cool", but then I noticed that I hadn't really thought about what I had built. I was just clicking buttons automatically, without reflecting on my work.&lt;/p&gt;

&lt;p&gt;The next time you are building something, ask yourself: "Am I being a developer in control and aware of what I'm building? or am I just a user consuming every output AI gives me?"&lt;/p&gt;

&lt;h2&gt;
  
  
  The cost of the HYPE
&lt;/h2&gt;

&lt;p&gt;Every time I open my browser or linkedin, I see a lot of articles, courses, videos, and content about prompt engineering and how to get better at using AI. &lt;/p&gt;

&lt;p&gt;I know it is good to learn the basics and understand how to get more assertive answers and outputs from AI. However, in my experience, the fundamentals and the basics related to your field are the most valuable.&lt;/p&gt;

&lt;p&gt;In the software engineer context, there are topics that never get old, and this knowledge makes the biggest difference in your career. Learning about DNS, memory management, software architecture, code design, CI/CD, cloud computing, and so on will sharpen you more than any prompt you learn.&lt;/p&gt;

&lt;p&gt;You don't need to ignore the hype, I would only suggest learning the basics before jumping into the hype. &lt;/p&gt;

&lt;h2&gt;
  
  
  The cost of AI in your company
&lt;/h2&gt;

&lt;p&gt;Have you thought about the impact of AI in your company? What is the cost of coding faster using AI? Is there any impact on the teams using AI? What about the domain knowledge, is it still relevant? How do you measure code quality when using AI?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Measuring code quality using AI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Well, that's a tricky one. AI has been trained on a large amount of code from many sources, and it is hard to define what good code and bad code really are. &lt;/p&gt;

&lt;p&gt;Would you trust AI to decide whether code is good or not? and based on which concepts? I think most of the discussions in the software engineering area are about principles and concepts we have, and whether or not we should follow them.&lt;/p&gt;

&lt;p&gt;AI can read entire codebases easily... Humans cannot.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The impact on teams using AI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;First, I would like to start talking about the domain knowledge. Companies used to care more about the domain knowledge, and from my experience, it plays a huge role in day-to-day operations, bug fixing, and generating value through new features.&lt;/p&gt;

&lt;p&gt;If we start using AI to solve problems in day-to-day operations instead of training people to build strong domain knowledge, the long-term outcome can be harmful. What if you need to fix something urgent in production? Would you trust AI entirely to do it? How likely is it that AI will fully understand the context and provide the best solution for the scenario? &lt;/p&gt;

&lt;p&gt;The combination of AI and someone with strong domain knowledge is powerful, but choosing only AI is not a wise decision.&lt;/p&gt;

&lt;p&gt;Second, if we start isolating people to work only with AI,  how will knowledge sharing happen? There are things that only day-to-day conversations or a pair programming session can provide. Also, if we isolate people to work only on AI, we lose interactions and, consequently, teamwork.&lt;/p&gt;

&lt;p&gt;The cost of replacing a good employee is far higher than the cost of an AI tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;I am not advocating against AI. I really believe AI is a great tool that can help us and speed things up for us a lot. I use AI daily, and I feel productive when using it. &lt;/p&gt;

&lt;p&gt;My main point here is that we should always be in control of it, not the other way around. We should criticize its outputs, learn the basics and foundations, and sometimes do things by ourselves, embracing the learn by doing process. &lt;/p&gt;

&lt;p&gt;Do not delegate your entire career to AI, take ownership of your decisions. This path will require one of the hardest things in life: discipline. But don't give up on it, the more you exercise discipline, the easier it becomes.&lt;/p&gt;

&lt;p&gt;Let's create more original content, thoughts, and ideas in an AI world where so much feels generic.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;SwimAgainstTheTide&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>career</category>
      <category>ai</category>
      <category>software</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Creating my portfolio with Antigravity AI</title>
      <dc:creator>Raffael Eloi</dc:creator>
      <pubDate>Thu, 15 Jan 2026 21:25:25 +0000</pubDate>
      <link>https://forem.com/raffaeleloi/creating-my-portfolio-with-antigravity-ai-40pe</link>
      <guid>https://forem.com/raffaeleloi/creating-my-portfolio-with-antigravity-ai-40pe</guid>
      <description>&lt;p&gt;I decided to write a detailed article describing my entire journey creating my portfolio with Antigravity.&lt;/p&gt;

&lt;p&gt;The sequence:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Idea&lt;/li&gt;
&lt;li&gt;Approach / Strategy&lt;/li&gt;
&lt;li&gt;AI Choice&lt;/li&gt;
&lt;li&gt;Key concepts and choices for the frontend app&lt;/li&gt;
&lt;li&gt;Experience / Journey&lt;/li&gt;
&lt;li&gt;AI workflow&lt;/li&gt;
&lt;li&gt;Result&lt;/li&gt;
&lt;li&gt;Final thoughts&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. Idea
&lt;/h2&gt;

&lt;p&gt;While I was searching for opinions about the &lt;a href="https://www.wearedevelopers.com" rel="noopener noreferrer"&gt;WeAreDevelopers&lt;/a&gt; event, which I would like to participate in one day, I found an interesting opinion on the dev.to website. After reading it, I came across a pop-up from the dev.to promoting a &lt;a href="https://dev.to/devteam/join-the-new-year-new-you-portfolio-challenge-3000-in-prizes-feedback-from-google-ai-team-4e7g?bb=259942"&gt;Frontend challenge using AI&lt;/a&gt;. &lt;br&gt;
I already wanted to create my portfolio and understand AI better, so it was a perfect opportunity to kill two birds with one stone.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Approach
&lt;/h2&gt;

&lt;p&gt;My idea was to use the &lt;em&gt;learn by doing&lt;/em&gt; method. I didn't want to spend many hours learning about the AI, instead, I wanted to see how intuitive my chosen AI is and how far I could go without having to provide very technical prompts.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. AI Choice
&lt;/h2&gt;

&lt;p&gt;In the challenge, we had three AI options (from Google), and I chose Antigravity. I'm going to be honest here: I chose it because I liked the name (you've probably done something similar at some point in your life, so don't judge me).&lt;/p&gt;

&lt;p&gt;I watched the introduction video on the &lt;a href="https://antigravity.google" rel="noopener noreferrer"&gt;Antigravity website&lt;/a&gt;, and they presented the following method:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implementation plan&lt;/li&gt;
&lt;li&gt;Pre-requisites&lt;/li&gt;
&lt;li&gt;Proposed Architecture&lt;/li&gt;
&lt;li&gt;Implementation steps&lt;/li&gt;
&lt;li&gt;Verification plan&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  4. Key concepts and choices for the frontend app
&lt;/h2&gt;

&lt;p&gt;Frontend: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next.js (I don't have much familiarity with it, so that's why I chose it)&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Key concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easy to change&lt;/li&gt;
&lt;li&gt;Separation of concerns&lt;/li&gt;
&lt;li&gt;MVC Architecture&lt;/li&gt;
&lt;li&gt;Pretty UI&lt;/li&gt;
&lt;li&gt;Feature-based layout (&lt;del&gt;atomic design&lt;/del&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  5. Experience / Journey
&lt;/h2&gt;

&lt;p&gt;I will highlight some moments in the process of creating the portfolio that made me reflect on certain AI approaches. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Downgrading Node version&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In order to use the latest version of Next.js, the node version installed on my machine was not compatible. Instead of suggesting an upgrade, the AI decided to downgrade Next.js (I stopped it before that).&lt;br&gt;
This caught my attention: why didn’t the AI suggest upgrading Node.js instead?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accessing web pages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;During the process of creating my portfolio, I gave the AI some public links to my GitHub and LinkedIn profiles. The AI opened up a browser and fetched the information.&lt;br&gt;
That was pretty impressive, and it was interesting to watch the steps it took.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All the entities in a single file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The AI's first choice was to create all the entities inside a single file. Although this is a very basic issue, I often notice the AI choosing the most "cheap" and "compact" solutions. We need to pay attention to that. AI can read an entire codebase easily, we cannot.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Atomic design... literally&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This one is kind of funny. In the prerequisites I provided to the AI, I defined the Atomic Design, but it turns out the AI built the following structure:&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%2Fm1i3s15nkl5xlqogkryo.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%2Fm1i3s15nkl5xlqogkryo.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, that was not my intention. I wanted to use Atomic Design, but not the literal folder names. I preferred a more organic separation instead of using concept names for each folder.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Component delegation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I don't know Next.js very well, so it was not clear to me how things were working. After some back and forth with the AI, we came up with the idea of component delegation, which I really enjoyed.&lt;/p&gt;
&lt;h2&gt;
  
  
  6. AI workflow
&lt;/h2&gt;

&lt;p&gt;I really liked Antigravity's approach. It consists of two or three steps, depending on the prompts you provide. These steps are represented as markdown files and require your approval.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Proposal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The AI provides a markdown file containing some ideas and options you can choose from, followed by the pros and cons of each choice.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implementation plan&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before getting your hands dirty, the AI shows you the plan, the steps, and the goal for the action it is trying to implement. &lt;br&gt;
Having this step gave me a really good feeling about what the AI is thinking and how it plans to achieve the result. It is much better than letting the AI do everything and reviewing the output only at the end.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Walk Through&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After you approve the implementation plan proposed by AI, you can see what has been implemented and the final result. &lt;br&gt;
Overall, this is a pretty good idea.&lt;/p&gt;
&lt;h2&gt;
  
  
  7. Result
&lt;/h2&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__cloud-run"&gt;
  &lt;iframe height="600px" src="https://portifolio-updated-485096414492.europe-west1.run.app"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;




&lt;p&gt;This is my application, and I'm going to break down the architecture and explain my choices.&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%2F6m55rvauagvbbnpdu87o.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%2F6m55rvauagvbbnpdu87o.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;app: It contains the pages&lt;/li&gt;
&lt;li&gt;components: related to the UI and the feature-based approach&lt;/li&gt;
&lt;li&gt;models: entities representing the domain&lt;/li&gt;
&lt;li&gt;services and data: I decided to mock a JSON file with the resume structure as follows:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Resume&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic info&lt;/li&gt;
&lt;li&gt;Experiences&lt;/li&gt;
&lt;li&gt;Education&lt;/li&gt;
&lt;li&gt;Extras&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this section, I mocked the file with my data, but I kept it this way because, in the future, it can retrieve data from an API and generate the profile automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Final thoughts
&lt;/h2&gt;

&lt;p&gt;In the end, it was a really fun experience. I was able to learn more about Antigravity AI, Next.js, and Google Cloud Run. I believe that the more we expose ourselves to challenges, the more we sharpen our minds and skills.&lt;/p&gt;

&lt;p&gt;Antigravity surprised me. It was a good experience using it, especially with the implementation plan, which was a really cool idea. &lt;/p&gt;

&lt;p&gt;I bought a domain, and it was pretty easy to link it to my portfolio using Google Cloud. Check it out: (&lt;a href="https://raffaeleloi.dev" rel="noopener noreferrer"&gt;https://raffaeleloi.dev&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Also, I was able to learn more about the turbo pack (&lt;a href="https://nextjs.org/docs/app/api-reference/turbopack" rel="noopener noreferrer"&gt;a really fast compiler written in Rust&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;I didn't spend a lot of time on this challenge, but even so, I had fun and managed to build my portfolio, which has been on my to-do list for a long time.&lt;/p&gt;

&lt;p&gt;Before I forget, I have been searching for a text editor that would help me avoid distractions, and I found this one &lt;a href="https://zenpen.io" rel="noopener noreferrer"&gt;zenpen.io&lt;/a&gt;. I used to write down my ideas, and I really recommend it. &lt;/p&gt;

&lt;p&gt;My repo: &lt;a href="https://github.com/Raffael-Eloi/portifolio-updated" rel="noopener noreferrer"&gt;https://github.com/Raffael-Eloi/portifolio-updated&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Any comments or suggestions are welcome.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>googleaichallenge</category>
      <category>portfolio</category>
      <category>gemini</category>
    </item>
    <item>
      <title>Building better softwares: The power of building effective abstraction</title>
      <dc:creator>Raffael Eloi</dc:creator>
      <pubDate>Sat, 18 May 2024 23:35:42 +0000</pubDate>
      <link>https://forem.com/raffaeleloi/building-better-softwares-the-power-of-building-effective-abstraction-3de4</link>
      <guid>https://forem.com/raffaeleloi/building-better-softwares-the-power-of-building-effective-abstraction-3de4</guid>
      <description>&lt;p&gt;The first time I heard about abstraction was in my programming classes during my degree. We were studying the four pillars of object-oriented programming: Abstraction, Encapsulation, Polymorphism, and Inheritance. &lt;/p&gt;

&lt;p&gt;I was fascinated by the idea of modeling the real world in the software we were building. It was a new concept for me, and it took a lot of practice to get used to thinking this way.&lt;/p&gt;

&lt;p&gt;However, my understanding of abstraction has grown. It's more than just replicating the real world in software, as we learned in our object-oriented programming classes. Abstraction can be applied at different levels, and while it might seem complex at first, it doesn't have to be.&lt;/p&gt;

&lt;p&gt;In this article, I'll explain how abstraction applies to code design and how it can help you gain a better understanding of the technology world. By using effective abstractions, you can build better software that is easier to maintain and understand.&lt;/p&gt;

&lt;h2&gt;
  
  
  The levels of abstraction
&lt;/h2&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%2Fq5qkd77hq54pkbhwpcwa.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%2Fq5qkd77hq54pkbhwpcwa.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As software engineers, it's crucial to handle abstraction appropriately for different scenarios. We need to adjust our communication and focus based on the context we are in.&lt;/p&gt;

&lt;p&gt;When meeting with stakeholders, we can't use the same technical language that we use within our engineering team. In these situations, the main goal is to understand the business, domain, and strategy as thoroughly as possible.&lt;/p&gt;

&lt;p&gt;On the other hand, when discussing solutions, infrastructure, and architecture with the team, we should avoid focusing on specific code or programming languages. These are high-level conversations aimed at determining the best ways to manage our microservices and applications.&lt;/p&gt;

&lt;p&gt;Therefore, there are various levels of abstraction to consider, and we must tailor our questions and thinking to the right level at the right time with the right people. Recognizing these levels of abstraction has helped me understand the power of context.&lt;/p&gt;

&lt;p&gt;But what about low-level solutions? How can we identify abstraction in the software we are building, and how does it work?&lt;/p&gt;

&lt;h2&gt;
  
  
  Abstraction is life
&lt;/h2&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%2Fm5yup8crvtsu77f3zlty.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%2Fm5yup8crvtsu77f3zlty.png" alt=" " width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When designing software, we deal with use cases that represent user actions within our system. Abstraction is essential. By defining the responsibility of an abstraction, we shape it based on the context and purpose we've established.&lt;/p&gt;

&lt;p&gt;Creating a new abstraction is like bringing something to life. We need to clearly define its responsibility and purpose. This is why I particularly enjoy working with interfaces. They allow us to define clear contracts for our abstractions, ensuring that each part of the system has a specific role and interacts with others.&lt;/p&gt;

&lt;h2&gt;
  
  
  Working with interfaces
&lt;/h2&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%2Fzfq5spdga8148tx2kta9.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%2Fzfq5spdga8148tx2kta9.png" alt=" " width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A well-defined interface acts as a contract for our abstraction. It's like bringing something to life and saying, "Your purpose is to only do this, and do it well." We don't need to worry about the details of how it will be done; the interface provides a stable contract that defines what the abstraction is and what it offers.&lt;/p&gt;

&lt;p&gt;This approach aligns with the "D" in the SOLID principles: the Dependency Inversion Principle (DIP). DIP states that we should depend on abstractions rather than concretions. By following this principle, we create flexible and maintainable systems that can adapt to change more easily.&lt;/p&gt;

&lt;h2&gt;
  
  
  The combination of pieces
&lt;/h2&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%2Fu0t9n0bj4gkeyrznwu4x.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%2Fu0t9n0bj4gkeyrznwu4x.png" alt=" " width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In software design, I think of interfaces like puzzle pieces. Each piece has a well-defined contract and purpose, allowing us to use them precisely where needed.&lt;/p&gt;

&lt;p&gt;Working with interfaces provides stability when making changes to the code. No matter how much a concrete class changes, as long as it adheres to the contract, the consumers of that interface remain unaffected.&lt;/p&gt;

&lt;p&gt;Using interfaces to define abstractions also supports TDD. With the mockist approach, I can mock the behavior of external abstractions and focus on the expected behavior of the current abstraction I am building. This ensures that each piece of the puzzle fits perfectly and functions as intended.&lt;/p&gt;

&lt;h2&gt;
  
  
  Whose responsibility is this ?
&lt;/h2&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%2Fx3uezju12bz3kunac765.gif" 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%2Fx3uezju12bz3kunac765.gif" alt=" " width="498" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When designing use cases, we often tend to centralize all behaviors and business rules in a single service or use case. However, a well-designed use case is actually a combination of multiple abstractions working together.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
In a finance software, consider a use case that generates an invoice. The flow might look like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Verify if the requested user has permission&lt;/li&gt;
&lt;li&gt;Get the invoice&lt;/li&gt;
&lt;li&gt;Calculate the tax&lt;/li&gt;
&lt;li&gt;Generates the invoice&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's not ideal for this use case to handle all business rules. Instead, it should delegate specific responsibilities to abstractions designed for those tasks.&lt;br&gt;
Building a high quality software requires high quality questions.&lt;br&gt;
To create cohesive use cases, we need to ask the right questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whose responsibility is this ?&lt;/li&gt;
&lt;li&gt;How many reasons does this use case have to change ?&lt;/li&gt;
&lt;li&gt;Should we create an abstraction to handle this specific business rule?&lt;/li&gt;
&lt;li&gt;Is this business rule within the scope of the abstraction I am building?&lt;/li&gt;
&lt;li&gt;Is this cohesive?&lt;/li&gt;
&lt;li&gt;Can someone without much context understand this use case?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A possible solution:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Have a dependency on an abstraction that handles permission verification&lt;/li&gt;
&lt;li&gt;Get the invoice value &lt;/li&gt;
&lt;li&gt;Have a dependency on an abstraction that handles tax calculation&lt;/li&gt;
&lt;li&gt;Have a dependency on an abstraction that generates the invoice in the required format&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The beauty of this approach is that it allows you to see things from different perspectives and at various levels of abstraction. Understanding which level to focus on helps in establishing better communication and a clearer understanding of both problems and opportunities within the business.&lt;br&gt;
Good design begins with asking the right questions, and the ultimate goal is simplicity. Designing software is an ongoing process; there is always room for improvement. We can continuously refine our designs by learning from our mistakes and through regular practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://youtu.be/gNj8I4uSTgc?si=5He2gvibs8Yzlp8d" rel="noopener noreferrer"&gt;The Lost Art of Software Design - Simon Brown&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/aWZFRk-w3ng?si=NCNDlaIwPN5gpgSl" rel="noopener noreferrer"&gt;Build Abstractions Not Illusions - Gregor Hohpe
&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/llGgO74uXMI?si=XKXXWSNKZ79HfHfv" rel="noopener noreferrer"&gt;Core Design Principles for Software Developers - Venkat Subramaniam&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>softwareengineering</category>
      <category>softwaredevelopment</category>
      <category>career</category>
      <category>design</category>
    </item>
    <item>
      <title>How the ego hinders growth in your software engineering career</title>
      <dc:creator>Raffael Eloi</dc:creator>
      <pubDate>Sun, 28 Apr 2024 13:50:56 +0000</pubDate>
      <link>https://forem.com/raffaeleloi/how-the-ego-hinders-growth-in-your-software-engineering-career-1n4m</link>
      <guid>https://forem.com/raffaeleloi/how-the-ego-hinders-growth-in-your-software-engineering-career-1n4m</guid>
      <description>&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%2Ffa33s0m7xtkbxarn969v.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%2Ffa33s0m7xtkbxarn969v.png" alt=" " width="800" height="571"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the fast-paced world of software engineering there is always a great amount of work to do, backlogs to implement, new products to be developed, bugs to fix and refactors to be made. And when we sum this up with the velocity that the technologies grow and evolve today, we can see that this area is not only about skill but mindset.&lt;/p&gt;

&lt;p&gt;To deal with this amount of responsibilities, it’s crucial that we continue to learn and be open to new ways to do things, read and observe how the others are doing and always try to search ways to optimize our work and reduce our cognitive load.&lt;/p&gt;

&lt;p&gt;I think that is in this point that the most people fail, I’m not saying that if you do not do that you will not be successful or something like that, but what I’ll try to show you is that while we have a strict and not flexible mindset it can be really probably that you’re not using all the potential and capacity that your mind can have.&lt;/p&gt;

&lt;h2&gt;
  
  
  “I only use this technology because it is the best”
&lt;/h2&gt;

&lt;p&gt;Usually in this area we have a lot of discussion and repercussion about what is the best technology and tool to use, and we be only strict to a single tool or language we lose some opportunities to learn something new and have a better and experienced opinion for when and which scenario is the best for each tool or technology. &lt;/p&gt;

&lt;p&gt;All the time when I worked with someone that is really specialist in some tool, language or area I can see a lot of things from a different perspective, and I came to the conclusion to myself that we tend to not like the things that we don’t know. &lt;br&gt;
Despite my preferences in terms of language and tools, it would be really prepotent to affirm that these are the best options available in the market if I haven’t tried a lot of options that exist today.&lt;/p&gt;

&lt;p&gt;Give yourself a chance to learn something that you don’t like or think you don’t like and take your own conclusion. It will be a win-win situation because if you try and really do not like it you now have a real experience with that and can really argue with a better pov the reasons you don’t like it, but otherwise if you like it, that’s the magic, you won against your pride and can be humble enough to admit that in this area exist great tools to be used.&lt;/p&gt;

&lt;h2&gt;
  
  
  “I will not accept the opinion/suggestion of someone with a lower position”
&lt;/h2&gt;

&lt;p&gt;Sometimes we are really attached to the title of our position in our jobs and we tend to think that we are our position instead of we are occupying the position that we have and it can change overnight. &lt;/p&gt;

&lt;p&gt;The first question that I observe people do when they get together with a group of people from the same area is “what is your position in the company?”. I don’t particularly like this question, because it tends to imply that the level of credibility of your opinions will be characterized by the answer of this question.&lt;/p&gt;

&lt;p&gt;Once I saw a video of Celest Headlee in a TED presentation in youtube (&lt;a href="https://youtu.be/R1vskiVDwl4?si=KaASYDMKjy67DoG0" rel="noopener noreferrer"&gt;10 ways to have a better conversation | TED&lt;/a&gt;) which tells that everyone knows something we don’t.&lt;br&gt;
In this video in the same way that we can learn a lot talking to the people and knowing their histories we can learn from everyone from whatever level of seniority.&lt;br&gt;
Every senior started as an intern or junior.&lt;/p&gt;

&lt;h2&gt;
  
  
  “My way of doing things is the only right way”
&lt;/h2&gt;

&lt;p&gt;Today we have many videos, books and courses talking about different ways of doing things, which methodology to use and why we should use it. But the truth is that none of this is a universal truth and each company carries out the process according to its own scenario.&lt;/p&gt;

&lt;p&gt;The problem in my opinion is when we have the opportunity to try something different that can generate more value and we don’t do it because of the status quo “we always did like that” or because of our ego “I cannot go back in my opinion because I already said that the other way of doing is better”. In either case the result is a lose-lose or a stagnant performance. &lt;/p&gt;

&lt;p&gt;One presentation that really opened my mind about it was the Simon Brown &lt;a href="https://youtu.be/gNj8I4uSTgc?si=oBXlJQvdUBiQaeWE" rel="noopener noreferrer"&gt;The lost art of software design&lt;/a&gt; that talked about Up Front Design and how we can create models and diagrams that facilitate the way we see our product and abstraction we’re building. In this video it is good to know that in addition to having a broad opinion about certain terms, you can still be flexible and have an open mind to the possibility of creating a middle ground.&lt;/p&gt;

&lt;h2&gt;
  
  
  “If I ask for help I will be seen as a bad professional”
&lt;/h2&gt;

&lt;p&gt;If you are truly immersed in the world of ego, simple things that boost us and our careers can be seen as a threat and prevent you from achieving better prospects.&lt;/p&gt;

&lt;p&gt;The phrase “If all you have is a hammer, everything looks like a nail” fits very well here, if your ego is not regulated everything can seem like a threat, and for me the best thing we can do for ourselves is to be in the position of an apprentice.&lt;/p&gt;

&lt;p&gt;Don't be afraid to ask for help and accept your own ignorance, we can only improve the things we are not good at, so if you have nothing to improve, perhaps your view of yourself is a little distorted.&lt;/p&gt;

&lt;h2&gt;
  
  
  “I will not listen to this opinion because I do not agree with it”
&lt;/h2&gt;

&lt;p&gt;This one is really interesting, because I struggle with this regularly, sometimes i think about it “why should I see this video if I do not agree with this topic” and when I accept that the video can teach me something I don’t know and I watch the video I always gain something, I either reinforce what I really don’t agree with or I learn something new. &lt;/p&gt;

&lt;p&gt;One of the great personal examples I can give is the practice of TDD. I never thought about using this methodology because it didn't make sense to me, but today I can't see myself without it and it's perhaps the best thing I've learned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this post I tried to talk about my experience and my feelings regarding my career. All opinions have a very partial and personal point of view, but also contain references to videos, presentations and also books I have read.&lt;/p&gt;

&lt;p&gt;Despite being labeled as a software engineering topic, this topic can be applied to any area of your life and career (if you agree, of course).&lt;/p&gt;

&lt;p&gt;By transcending ego and embracing a growth mindset, we unlock our full potential in all aspects of life and career.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://youtu.be/gNj8I4uSTgc?si=oBXlJQvdUBiQaeWE" rel="noopener noreferrer"&gt;The Lost Art of Software Design - Simon Brown&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/R1vskiVDwl4?si=KaASYDMKjy67DoG0" rel="noopener noreferrer"&gt;10 ways to have a better conversation | TED - Celeste Headlee&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Recommendations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://a.co/d/eEfqCxP" rel="noopener noreferrer"&gt;Ego is the enemy - Ryan Holiday&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/zajUPJI19ZQ" rel="noopener noreferrer"&gt;Refactor your language knowledge portifolio - We are what we can code in - Venkat Subramaniam &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/oeqPrUmVz-o?si=HXIMMsMgADMUQD_d" rel="noopener noreferrer"&gt;Steve Jobs Insult Response - Highest Quality&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>softwareengineering</category>
      <category>softwaredevelopment</category>
      <category>career</category>
      <category>software</category>
    </item>
    <item>
      <title>The benefits of TDD that go beyond the code</title>
      <dc:creator>Raffael Eloi</dc:creator>
      <pubDate>Sun, 18 Jun 2023 12:21:24 +0000</pubDate>
      <link>https://forem.com/raffaeleloi/the-benefits-of-tdd-that-go-beyond-the-code-egd</link>
      <guid>https://forem.com/raffaeleloi/the-benefits-of-tdd-that-go-beyond-the-code-egd</guid>
      <description>&lt;p&gt;As software developers, we are constantly faced with the task of solving problems and constructing new solutions through code. So all the time there’s something to do and in general even the small things are a sequence of a lot of steps to get the things done.&lt;br&gt;
This raises important questions: Where do we begin? Which task should we prioritize for development? How can we effectively organize our thoughts to maximize productivity and maintain control over the development flow?&lt;/p&gt;

&lt;p&gt;One of the best options to solve this issue is to use the TDD process. The TDD practice is not about tests or coverage, it can be one of the things that you win when you use that, but that’s not the main point, if you think that TDD is just about testing you misunderstood the real meaning. &lt;/p&gt;

&lt;p&gt;The TDD can be a guide to develop the business rules needed. When we use TDD thinking about scenarios and abstractions instead of tests and coverage we can have a lot of benefits that are not only code related but also benefits even to our mental health.&lt;br&gt;
Here’s some benefits that you can get using the TDD practise:&lt;/p&gt;

&lt;h2&gt;
  
  
  Scenarios serve as valuable guides
&lt;/h2&gt;

&lt;p&gt;We always have some behaviors and scenarios to implement and the best way to start implementing is to set up an expected scenario that will force you to think in a different perspective because you need to imagine what is the best input and output for the abstraction that you are building. That’s really powerful because you start to think about business rules and abstraction instead of implementation’s details and by distancing ourselves from the small details of code we can get the big picture. When we start to develop something we should not be driven by “How” we can do it, but “What” we need because thinking in a high level of abstraction can put you in a software engineer position with an abroad vision instead of a software developer just focused on code and syntax.&lt;/p&gt;

&lt;h2&gt;
  
  
  You get constant feedback
&lt;/h2&gt;

&lt;p&gt;Sometimes it is hard to know if the features that we are building are working correctly and we don’t get the feedback of the status until we finish. When we use TDD it can be a relief because we can divide the feature in small parts and use the scenarios as a guide. For each step of the process we get the feedback (RED, GREEN, REFACTOR) what is good for our brain mechanism of reward.&lt;/p&gt;

&lt;h2&gt;
  
  
  It helps you with anxiety
&lt;/h2&gt;

&lt;p&gt;Almost all of the software developers have anxieties when they have to build something. It’s pretty common, we want to get things done to get another task and so on, but that’s not healthy and the TDD can help you with that. When we define that we’ll start with a scenario and we have constant feedback is a nice way to work. It gives you the feeling that you are in control and you also know that what you’re building is working.&lt;/p&gt;

&lt;h2&gt;
  
  
  You are able to improve your software whenever you want
&lt;/h2&gt;

&lt;p&gt;As we evolve over time, our past versions become stepping stones towards better expertise and experience. It's natural to reflect on our software design and envision superior solutions compared to our previous work. However, without the practice of TDD, making changes becomes arduous and prone to disastrous outcomes.&lt;/p&gt;

&lt;p&gt;TDD empowers developers to embrace constant change and enhance their code design at any given moment. By adhering to the "boy scout rule" of leaving the code cleaner than we found it, TDD enables a mindset of continuous improvement. This freedom to make changes instills a gratifying sense of control, especially when it allows us to challenge the status quo and strive for better solutions.&lt;/p&gt;

&lt;p&gt;In Venkat Subramaniam's conference video, "Refactor your language knowledge portfolio - we are what we can code," he offers profound insights into how the programming language we use shapes our thoughts, and how our environment influences our growth as software developers. This prompts contemplation on how software practices, principles, and processes can impact our lives as a whole. If we fail to adopt good practices that ensure the expected behavior of our systems and neglect to make necessary changes, we are forced to accept the status quo. This acceptance can permeate into our personal lives, limiting our potential for growth and improvement.&lt;/p&gt;

&lt;h2&gt;
  
  
  You can divide the problem in small steps
&lt;/h2&gt;

&lt;p&gt;Instead of trying to tackle all the tasks simultaneously, TDD encourages a more systematic and efficient workflow. By following TDD principles, you can enhance your development process and create small, simple components. This aligns with the famous quote by Julius Caesar, "Divide and conquer," which emphasizes the power of breaking down larger problems into smaller, more manageable ones. Adopting TDD not only helps you prioritize and focus on crucial features but also promotes an essentialist mindset, allowing you to build robust solutions step by step.&lt;/p&gt;

&lt;p&gt;Illustration by Liz Fosslien&lt;br&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%2Fifgjsvu0ngji3ai0ig26.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%2Fifgjsvu0ngji3ai0ig26.png" alt="De um lado, uma pessoa olhando para uma escada alta, sentindo-se sobrecarregada pensando em quão grande é a escada, do outro lado, uma pessoa apenas focada no próximo passo se sentindo melhor" width="750" height="750"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This publication about the benefits and perception of TDD is not a scientific study. All the information, perception and opinion is based on my experience using this practice every day. &lt;/p&gt;

&lt;p&gt;I would like to thank Marcelo Torres and Kassio Santana who are amazing people for all their help and support during the writing process. I'm very happy to have you in my life.&lt;/p&gt;

&lt;p&gt;In the references, I will let everyone know that it was important to consolidate the concept and value of the practice of TDD in my life.&lt;/p&gt;

&lt;h2&gt;
  
  
  References:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Illustration by Liz Fosslien - &lt;a href="https://www.fosslien.com/" rel="noopener noreferrer"&gt;https://www.fosslien.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dave Farley - &lt;a href="https://www.youtube.com/@ContinuousDelivery" rel="noopener noreferrer"&gt;https://www.youtube.com/@ContinuousDelivery&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Otavio Lemos - &lt;a href="https://www.youtube.com/@otaviolemos" rel="noopener noreferrer"&gt;https://www.youtube.com/@otaviolemos&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dev Eficiente - &lt;a href="https://www.youtube.com/@DevEficiente" rel="noopener noreferrer"&gt;https://www.youtube.com/@DevEficiente&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Venkat Subramaniam’s video - &lt;a href="https://youtu.be/zajUPJI19ZQ" rel="noopener noreferrer"&gt;https://youtu.be/zajUPJI19ZQ&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tdd</category>
      <category>softwareengineering</category>
      <category>career</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
