<?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: bryam vega</title>
    <description>The latest articles on DEV Community by bryam vega (@bryam_vega_487231d2d7c62e).</description>
    <link>https://dev.to/bryam_vega_487231d2d7c62e</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%2F2733664%2F98e877a6-e15f-4838-80c9-5fb8295c2812.jpg</url>
      <title>DEV Community: bryam vega</title>
      <link>https://dev.to/bryam_vega_487231d2d7c62e</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bryam_vega_487231d2d7c62e"/>
    <language>en</language>
    <item>
      <title>Streams in Java: Mastering or abuse?</title>
      <dc:creator>bryam vega</dc:creator>
      <pubDate>Wed, 22 Jan 2025 22:24:54 +0000</pubDate>
      <link>https://dev.to/bryam_vega_487231d2d7c62e/streams-in-java-mastering-or-abuse-34h1</link>
      <guid>https://dev.to/bryam_vega_487231d2d7c62e/streams-in-java-mastering-or-abuse-34h1</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;It looked elegant, concise, and modern. But when we revisited the code six months later, nobody understood what it did. Was it mastery? Or just over-engineered cleverness?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Java Streams have become a hallmark of modern Java development. Introduced in Java 8, they offer a functional approach to working with collections, enabling developers to write concise and expressive code. But as with any tool, their effectiveness depends on how and when they are used.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Stream?
&lt;/h2&gt;

&lt;p&gt;The Streams were introduced in &lt;strong&gt;Java 8&lt;/strong&gt;, and although Java is currently in versions higher than 21, this version &lt;strong&gt;marked an inflection point&lt;/strong&gt; in the way Java is used nowadays. Within it is the &lt;strong&gt;API Stream&lt;/strong&gt; that nowadays is too much used by Java programmers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Streams&lt;/strong&gt; provide a functional and declarative way of processing data. They allow to manipulate data collections efficiently, using operations such as map, filter, reduce, among others. For example:&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="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// whitout streams&lt;/span&gt;
&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;evenNumbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;evenNumbers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;span class="c1"&gt;// with streams&lt;/span&gt;
&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;evenNumbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                                   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                                   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach is modern because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It reduces boilerplate code.&lt;/li&gt;
&lt;li&gt;It promotes functional programming.&lt;/li&gt;
&lt;li&gt;It allows parallel operations easily with &lt;code&gt;parallelStream()&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But in my experience, the excessive use of streams ends up complicating the understanding of the code, &lt;strong&gt;so simplicity does not always mean clarity, and that is where the problems arise&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The senior-junior dilemma: elegant but incomprehensible vs. simple but robust
&lt;/h2&gt;

&lt;p&gt;When trying to explain the importance of Streams, most of the time I've come across images like this:&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%2Fbm1tfjroasid2h9z2yfm.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%2Fbm1tfjroasid2h9z2yfm.gif" alt="jrsr" width="800" height="867"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And I ask myself... 🤔 &lt;strong&gt;why is Senior level using Stream to solve this problem?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s break it down.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The "junior" approach:&lt;/strong&gt; A straightforward loop, simple and clear. It works, it’s easy to read, and any developer—junior or senior—can understand it without much effort.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The "senior" approach:&lt;/strong&gt; Using Streams to achieve the same result but with more compact, declarative code. At first glance, it might seem more sophisticated or "modern."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But here’s the catch: &lt;strong&gt;Does using Streams in this scenario actually add value?&lt;/strong&gt; Or does it introduce unnecessary complexity, just to showcase a tool?&lt;/p&gt;

&lt;p&gt;Let's go with another much more crazy example that I saw and it made my head hurt 😵‍💫😵‍💫. &lt;/p&gt;

&lt;p&gt;Imagine that you are watching programming videos and suddenly a guy appears and presents you with the following code.&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CodeVerification&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;private&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;String&lt;/span&gt; &lt;span class="no"&gt;NUMBERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"12345"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;private&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;Integer&lt;/span&gt; &lt;span class="no"&gt;LENGTH_CODE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;;&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;Random&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;CodeVerification&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Random&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;random&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;generateCode&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StringBuilder&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;LENGTH_CODE&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;NUMBERS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
      &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;NUMBERS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;charAt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;();&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;Now, this developer asks you to &lt;strong&gt;refactor&lt;/strong&gt; the &lt;code&gt;generateCode()&lt;/code&gt; method. He presents the following solution:&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="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;generateCode&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;IntStream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;range&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;LENGTH_CODE&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mapToObj&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;NUMBERS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;()))&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;NUMBERS:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;charAt&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;StringBuilder:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;StringBuilder:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="nl"&gt;StringBuilder:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&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;h3&gt;
  
  
  Do you see it now? 🧐🧐 You do realize what I mean right!!!!
&lt;/h3&gt;

&lt;p&gt;Both codes work exactly the same, but &lt;strong&gt;what happens??&lt;/strong&gt; We go from a perfectly &lt;strong&gt;understandable, readable and maintainable&lt;/strong&gt; code to a code that is difficult to understand and that does not add value or improve the performance of the code. Also, the code is not refactored, that's a topic we can talk about in another post.&lt;/p&gt;

&lt;p&gt;So, with that, I come to the conclusion that a Senior is not someone who knows how to use Streams perfectly and applies them everywhere with the justification of "refactoring" the code. &lt;em&gt;Being a Senior is understanding that refactoring doesn’t always mean making the code more "modern" or "functional," but rather making it clearer, more efficient, and easier to maintain&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;A Senior knows when to use a simple &lt;code&gt;for&lt;/code&gt; loop because it’s the most straightforward and effective solution, and when to choose Streams when they truly add clarity or performance benefits. The key is understanding &lt;strong&gt;the problem&lt;/strong&gt;, not &lt;strong&gt;the tool&lt;/strong&gt;. If the traditional solution is simpler and keeps the code readable, there’s no need to complicate it with Streams just to follow a trend.&lt;/p&gt;

&lt;p&gt;The real value of a Senior lies in their ability to make pragmatic decisions, based on the project's context and the team's needs, rather than just showing off skills with a tool. A Senior understands that sometimes &lt;u&gt;&lt;em&gt;less is more&lt;/em&gt;&lt;/u&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With the above example, does this mean that we should not use Streams?&lt;/strong&gt; 😢😢😢 Absolutely NOT, here I show you a way to use streams to solve the same problem, keeping code readability, &lt;em&gt;however this does not mean that it is more optimal&lt;/em&gt;.&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="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;generateCode&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
    &lt;span class="nc"&gt;IntStream&lt;/span&gt; &lt;span class="n"&gt;randomIndexes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ints&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;LENGTH_CODE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;NUMBERS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

    &lt;span class="nc"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Character&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;characters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;randomIndexes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mapToObj&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;NUMBERS:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;charAt&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;characters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;valueOf&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;joining&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; 
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;This is more readable, right?&lt;/strong&gt; This is simply because we separate the stream into steps, one of the best practices of Streams is to &lt;strong&gt;❌ NOT CONCATENATE SEVERAL STEPS IN A SINGLE STEP&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best practices: How to use Streams without abuse
&lt;/h2&gt;

&lt;p&gt;Here are some tips that I have acquired throughout my experience in working with streams&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prioritize Readability Over Conciseness:&lt;/strong&gt;If a Stream is difficult to understand at first glance, it probably needs refactoring.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid Excessive Nesting of Operations:&lt;/strong&gt; Break complex operations into intermediate steps with descriptive names&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don’t Use Streams When a Simple Loop Is Enough:&lt;/strong&gt; For simple tasks like modifying a single element or performing basic calculations, Streams may be unnecessary&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Parallel Streams with Caution:&lt;/strong&gt; While parallel Streams &lt;code&gt;(parallelStream())&lt;/code&gt; can improve performance, incorrect use may lead to concurrency issues or performance degradation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add Comments Where Necessary:&lt;/strong&gt; If you use a complex operation in a Stream, document its purpose so others can understand it quickly.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Streams are a powerful feature in modern Java, but their true value lies in knowing when and how to use them effectively. There is no "seniority" in using or not using Streams—it’s just a different way of programming. A Senior developer understands that it’s not about the tool, but about choosing the right solution for the problem. Whether that means using Streams, loops, or any other approach, the key is writing code that is clean, maintainable, and easy to understand.&lt;/p&gt;

&lt;p&gt;The goal should always be clean, maintainable, and understandable code, remember: &lt;strong&gt;clarity always comes first&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Streams can be incredibly powerful when used correctly, but overusing them can lead to unnecessary complexity and remember: &lt;strong&gt;less is often more&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Happy coding!! ❤️&lt;/p&gt;

</description>
      <category>java</category>
      <category>discuss</category>
      <category>development</category>
      <category>programming</category>
    </item>
    <item>
      <title>Implementing Feature Flags with Spring: A Step-by-Step Guide for Feature Deployment</title>
      <dc:creator>bryam vega</dc:creator>
      <pubDate>Tue, 21 Jan 2025 18:27:16 +0000</pubDate>
      <link>https://dev.to/bryam_vega_487231d2d7c62e/implementing-feature-flags-with-spring-a-step-by-step-guide-for-feature-deployment-301</link>
      <guid>https://dev.to/bryam_vega_487231d2d7c62e/implementing-feature-flags-with-spring-a-step-by-step-guide-for-feature-deployment-301</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Feature flags, also known as feature toggles, are a software development technique that allows teams to enable or disable features dynamically. By decoupling feature deployment from code releases, they provide enhanced control over the application’s behavior and mitigate risks associated with new feature rollouts.&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%2F7zgypz4plz6iatkjxv9i.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%2F7zgypz4plz6iatkjxv9i.png" alt="flag" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of Feature Flags:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Controlled Rollouts:&lt;/strong&gt; Gradually introduce new features to a subset of users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A/B Testing:&lt;/strong&gt; Compare variations of a feature to improve user experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quick Rollbacks:&lt;/strong&gt; Disable malfunctioning features without a full redeployment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Continuous Deployment:&lt;/strong&gt; Safely deploy code even if certain features are not yet complete.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to work Feature-flags
&lt;/h2&gt;

&lt;p&gt;Feature flags operate by introducing conditional logic into your application code. Here’s a step-by-step breakdown of how they work:&lt;/p&gt;

&lt;p&gt;Step 1: Define a Feature Flag&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Decide on a meaningful name for your feature flag (e.g., &lt;code&gt;new-feature&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Identify the scope of the flag: whether it will be applied globally, for specific users, or for particular environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 2: Add Conditional Logic&lt;/p&gt;

&lt;p&gt;Modify your application code to check the status of the feature flag before executing a feature. This is a simple representation about how could be works a feature flag and could be the most simple way to implement. For example:&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="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;featureFlagService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEnabled&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"new-feature"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// New feature logic&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Fallback logic&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 3: Store and Manage the Flag&lt;/p&gt;

&lt;p&gt;Use one of the following methods to store feature flags:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Configuration Files:&lt;/strong&gt; Use application properties or YAML files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remote Service:&lt;/strong&gt; Utilize a feature flag management tool like &lt;strong&gt;&lt;em&gt;Unleash. (For me this is the best way)&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database:&lt;/strong&gt; Store flags in a database for runtime updates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 4: Control Flag States&lt;/p&gt;

&lt;p&gt;Dynamically update the feature flag state (enabled or disabled) using the chosen storage method or management tool.&lt;/p&gt;

&lt;p&gt;Step 5: Evaluate Flags at Runtime&lt;/p&gt;

&lt;p&gt;The application checks the flag’s state dynamically during execution and activates or deactivates features accordingly.&lt;/p&gt;

&lt;p&gt;Step 6: Monitor Usage&lt;/p&gt;

&lt;p&gt;Use analytics tools or dashboards provided by feature flag services to track the flag’s impact on users and application performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to implement Feature-Flags with Spring Boot and Unleash
&lt;/h2&gt;

&lt;p&gt;This time, we are going to put into practice the use of Feature-Flags using the Spring Boot framework and using the Unleash platform as our flags handler. Quickly, what we are going to do is the following:&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%2Faxu94hx2d6a1ohxqc0to.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%2Faxu94hx2d6a1ohxqc0to.png" alt="architecture" width="800" height="188"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a service in Spring Boot: This service is going to be a simple API that demonstrates the deployment of feature flags, it is going to have the unleash SDK installed to be able to work with it.&lt;/li&gt;
&lt;li&gt;We are going to create 2 beans that are going to be our features or different functionalities.&lt;/li&gt;
&lt;li&gt;Finally we are going to raise an unleash server to configure our flags to enable and disable the functionality to be tested in our Spring service.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Gradle&lt;/li&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;IDE of java (IntelliJ, Eclipse …)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Unleash Configuration
&lt;/h3&gt;

&lt;p&gt;In order to configure Unleash, we will download the following repository using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git clone https://github.com/Unleash/unleash.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, we access the folder of the downloaded repository and execute the following command to be able to run our unleash server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;unleash
&lt;span class="nv"&gt;$ &lt;/span&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once up, we access through the address &lt;a href="http://localhost:4242" rel="noopener noreferrer"&gt;http://localhost:4242&lt;/a&gt; where the credentials are the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Username: admin
Password: unleash4all
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this we will be able to access the following platform, and we have the unleash server up and ready for use:&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%2Fqgp06hiq28lef4xyfapx.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%2Fqgp06hiq28lef4xyfapx.png" alt="step 1" width="800" height="209"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create Feature-Flag
&lt;/h3&gt;

&lt;p&gt;To create a flag, we are going to access the default project that is in our unleash server, since we are working with the free version and we cannot create new projects.&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%2Fpqdfo2k9pr73rxlex5k6.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%2Fpqdfo2k9pr73rxlex5k6.png" alt="step 2" width="800" height="185"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create new feature flag
&lt;/h3&gt;

&lt;p&gt;Once in the default project, select the &lt;code&gt;new feature flag option&lt;/code&gt;. Once this option is selected, we proceed to create our own feature flag. Something interesting as you can see in the image, is that in case we do not want to use the &lt;code&gt;unleash sdk&lt;/code&gt;, we can communicate through API requests to the unleash server. In this case our feature flag is going to be called &lt;code&gt;featureFlagExample&lt;/code&gt;.&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%2Fq7gzq0z9utmwrwio38wq.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%2Fq7gzq0z9utmwrwio38wq.png" alt="step 3" width="800" height="185"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With our feature flag created we will see the following screen, which contains information about our flag as well as the different strategies we can configure to deploy the features to our end users (that will be another post)&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%2Fgzww79seldw0jtd98muj.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%2Fgzww79seldw0jtd98muj.png" alt="step 4" width="800" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To activate our feature flag, we will simply activate the &lt;code&gt;development&lt;/code&gt; option. These environments will allow us to configure our flags depending on the environment we are in, in this case only development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create Project API Key
&lt;/h3&gt;

&lt;p&gt;To be able to communicate with our unleash server and its APIs, it is necessary to create a token that allows us to access its endpoints in order to use our configured flags.&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%2Fyyjuj4wiritrhcqu0mic.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%2Fyyjuj4wiritrhcqu0mic.png" alt="step 5" width="800" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To do this, we go to Project Settings and in this section we have the option New API token, which will allow us to generate our authentication token to consume our flags.&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%2F3lxxu7fhfk8szrqycs36.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%2F3lxxu7fhfk8szrqycs36.png" alt="step 6" width="800" height="596"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We configure it as shown in the image below, if we notice, on the right side of the image, we are presented with how to create an api token through the API unleash, which is also another option.&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%2Fzduniwddd46ukoinweby.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%2Fzduniwddd46ukoinweby.png" alt="step 7" width="763" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This in turn gives us a token created, &lt;em&gt;&lt;strong&gt;which we will have to copy anywhere on our computer, since we will only be able to see it that time.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With this, we are now ready to proceed to create our Spring Boot project and configure our feature flag with unleash in our project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Spring Boot Project (product discount)
&lt;/h2&gt;

&lt;p&gt;A company’s service developed with Spring exposes a REST endpoint that allows consulting the list of available products. The company wants that during discount seasons, the list of products automatically shows the prices with the discount applied, without the end customer having to perform additional calculations. Outside these seasons, the prices should be displayed unchanged.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The project we are going to take as an example is this one:&lt;/strong&gt; &lt;a href="https://github.com/bvegaM/spring-unleash-feature-flag?source=post_page-----028ff145b29a--------------------------------" rel="noopener noreferrer"&gt;github repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To download the repository we use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;https://github.com/bvegaM/spring-unleash-feature-flag.git
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;spring-unleash-feature-flag
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We open it in the IDE of preference or the one you prefer, in my case, I will use IntellIJ Idea.&lt;/p&gt;

&lt;h3&gt;
  
  
  Structure of project
&lt;/h3&gt;

&lt;p&gt;The structure of this project is based on a layered architecture which has the following package tree:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;├── HELP.md
├── build.gradle
├── settings.gradle
└── src
    ├── main
    │   ├── java
    │   │   └── ec
    │   │       └── com
    │   │           └── vega
    │   │               └── spring_unleash
    │   │                   ├── SpringUnleashFeatureFlagApplication.java
    │   │                   ├── config
    │   │                   │   └── SpringUnleashFeatureFlagConfiguration.java
    │   │                   ├── controller
    │   │                   │   └── ProductController.java
    │   │                   ├── domain
    │   │                   │   └── Product.java
    │   │                   ├── repository
    │   │                   │   ├── ProductRepository.java
    │   │                   │   └── impl
    │   │                   │       └── ProductRepositoryImpl.java
    │   │                   ├── service
    │   │                   │   ├── ProductService.java
    │   │                   │   └── impl
    │   │                   │       ├── ProductServiceImpl.java
    │   │                   │       └── ProductServiceWithDiscountImpl.java
    │   │                   └── utils
    │   │                       └── Constant.java
    │   └── resources
    │       ├── application.yaml
    │       ├── static
    │       └── templates
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following project has the following classes and interfaces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;SpringUnleashFeatureFlagApplication&lt;/code&gt;: Main class of the Spring Boot application. Contains the main method that starts the application. It sets up the Spring context and runs the application.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SpringUnleashFeatureFlagConfiguration&lt;/code&gt;: Class that contains a bean method to initialize a list of products, which can be injected into the repository as a temporary database.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Configuration&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;SpringUnleashFeatureFlagConfiguration&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@Bean&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;initProducts&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Product 1"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Description 1"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
    &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Product 2"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Description 2"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
    &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Product 3"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Description 3"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="o"&gt;;&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;ul&gt;
&lt;li&gt;
&lt;code&gt;ProductController&lt;/code&gt;: Class that exposes REST endpoints for the product service, specifically for retrieving all products.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Product&lt;/code&gt;: Product class that contains the attributes of the object and also includes a method to calculate the discount for the product.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Getter&lt;/span&gt;
&lt;span class="nd"&gt;@Setter&lt;/span&gt;
&lt;span class="nd"&gt;@AllArgsConstructor&lt;/span&gt;
&lt;span class="nd"&gt;@NoArgsConstructor&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;Product&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;BigDecimal&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Product&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Product&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDescription&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getQuantity&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPrice&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;applyDiscount&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BigDecimal&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;BigDecimal&lt;/span&gt; &lt;span class="n"&gt;discountValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;multiply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;subtract&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;discountValue&lt;/span&gt;&lt;span class="o"&gt;);&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;ul&gt;
&lt;li&gt;
&lt;code&gt;ProductRepository&lt;/code&gt;: Repository interface that simulates database transactions and contains a single method.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ProductRepositoryImpl&lt;/code&gt;: Class that implements the &lt;code&gt;ProductRepository&lt;/code&gt; interface and uses the bean created in &lt;code&gt;SpringUnleashFeatureFlagConfiguration&lt;/code&gt; to retrieve the list of products.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ProductService&lt;/code&gt;: Interface that defines the method to retrieve all products. This interface is critical because it sets up the feature flag to determine which implementation to use when the flag is active.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ProductServiceImpl&lt;/code&gt;: Class that implements the &lt;code&gt;ProductService&lt;/code&gt; interface and returns the products.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ProductServiceWithDiscountImpl&lt;/code&gt;: Class that implements the &lt;code&gt;ProductService&lt;/code&gt; interface and returns the products with a discount applied.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Constant&lt;/code&gt;: Class that contains constant variables.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Install Unleash library
&lt;/h3&gt;

&lt;p&gt;In our downloaded project we go to the &lt;code&gt;build.gradle&lt;/code&gt; file and we will notice that in the &lt;code&gt;dependencies&lt;/code&gt; section we will have the unleash library installed.&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="n"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
 &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;springframework&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;boot&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;boot&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;starter&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;web&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;
 &lt;span class="n"&gt;compileOnly&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;projectlombok&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;lombok&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;
 &lt;span class="n"&gt;annotationProcessor&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;projectlombok&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;lombok&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;
 &lt;span class="n"&gt;testImplementation&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;springframework&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;boot&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;boot&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;starter&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;
 &lt;span class="n"&gt;testRuntimeOnly&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;junit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;junit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;platform&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;launcher&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;

 &lt;span class="c1"&gt;//unleash library&lt;/span&gt;
 &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getunleash&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;springboot&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;unleash&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nl"&gt;starter:&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Setting communication service with Unleash server
&lt;/h3&gt;

&lt;p&gt;Once our unleash dependency is installed, we are going to proceed to configure the communication with the Unleash server. To do this we go to the &lt;code&gt;application.yaml&lt;/code&gt; and we will see the following configuration.&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="nl"&gt;io:&lt;/span&gt;
  &lt;span class="nl"&gt;getunleash:&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;demo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;flag&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nf"&gt;unleash&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;could&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nl"&gt;id:&lt;/span&gt; &lt;span class="n"&gt;demo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;
    &lt;span class="nl"&gt;environment:&lt;/span&gt; &lt;span class="n"&gt;development&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;enviroment&lt;/span&gt; &lt;span class="nc"&gt;Unleash&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;deploy&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;development&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nl"&gt;url:&lt;/span&gt; &lt;span class="nl"&gt;http:&lt;/span&gt;&lt;span class="c1"&gt;//localhost:4242/api # Unleash server URI&lt;/span&gt;
    &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nl"&gt;token:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;your_token&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="n"&gt;or&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;created&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;previous&lt;/span&gt; &lt;span class="n"&gt;section&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Interface to getProducts
&lt;/h3&gt;

&lt;p&gt;This &lt;code&gt;ProductService&lt;/code&gt; interface has a method called &lt;code&gt;getProducts()&lt;/code&gt; which is decorated with a Toggle (a mechanism for handling &lt;strong&gt;feature flags&lt;/strong&gt;). Below is the explanation of the code:&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ProductService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@Toggle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"featureFlagExample"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alterBean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"productServiceWithDiscountImpl"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getProducts&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;The method &lt;code&gt;getProducts()&lt;/code&gt; is a method that returns a list of products &lt;code&gt;(List&amp;lt;Product&amp;gt;)&lt;/code&gt;. It is a critical method in the product service because it allows retrieving all the products. However, the implementation of how the products are retrieved is linked to the state of the feature flag controlled by the Toggle.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;@Toggle&lt;/code&gt; annotation is used to control the behavior of the method based on the activation or deactivation of a feature flag. The feature flag allows changing the functionality of the system without needing to change the code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;**name = "featureFlagExample"**&lt;/code&gt;: This is the name of the &lt;strong&gt;feature flag&lt;/strong&gt; being used. The value &lt;code&gt;featureFlagExample&lt;/code&gt; refers to a flag that is configured in Unleash. If this flag is active, the &lt;code&gt;getProducts()&lt;/code&gt; method will execute different logic, in this case, the implementation of ProductServiceWithDiscountImpl.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;**alterBean = "productServiceWithDiscountImpl"**&lt;/code&gt;: Here, it specifies that when the &lt;strong&gt;feature flag&lt;/strong&gt; &lt;code&gt;(featureFlagExample)&lt;/code&gt; is active, the implementation to be used for the product service is &lt;code&gt;ProductServiceWithDiscountImpl&lt;/code&gt;. This means that, instead of using the default implementation &lt;code&gt;(ProductServiceImpl)&lt;/code&gt;, the system will use a version that likely includes logic for applying discounts to the products.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Implement differents solutions
&lt;/h3&gt;

&lt;p&gt;We implement the ProductService interface in two classes, these are: &lt;code&gt;ProductServiceImpl&lt;/code&gt; and &lt;code&gt;ProductServiceWithDiscountImpl&lt;/code&gt;.&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="c1"&gt;// ProductServiceImpl.java&lt;/span&gt;
&lt;span class="nd"&gt;@Service&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"productServiceImpl"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@RequiredArgsConstructor&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;ProductServiceImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ProductService&lt;/span&gt; &lt;span class="o"&gt;{&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;ProductRepository&lt;/span&gt; &lt;span class="n"&gt;productRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getProducts&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;productRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getProducts&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;span class="c1"&gt;// ProductServiceWithDiscountImpl.java&lt;/span&gt;
&lt;span class="nd"&gt;@Service&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"productServiceWithDiscountImpl"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@RequiredArgsConstructor&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;ProductServiceWithDiscountImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ProductService&lt;/span&gt; &lt;span class="o"&gt;{&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;ProductRepository&lt;/span&gt; &lt;span class="n"&gt;productRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getProducts&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;productsWithDiscount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;productRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getProducts&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Product:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;productsWithDiscount&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;applyDiscount&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Constant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;DISCOUNT&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;productsWithDiscount&lt;/span&gt;&lt;span class="o"&gt;;&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;ul&gt;
&lt;li&gt;
&lt;code&gt;ProductServiceImpl&lt;/code&gt;: In this class, the only thing we do is return the products as they are stored.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ProductServiceWithDiscountImpl&lt;/code&gt;: In this class, the products are retrieved, and after that, the discount for each product is calculated and added to the new price.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Controller to get Products
&lt;/h3&gt;

&lt;p&gt;Finally, let’s check the &lt;code&gt;ProductController&lt;/code&gt; controller that has the endpoint to get all the products. The code is as follows:&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;@RestController&lt;/span&gt;
&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/products"&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;ProductController&lt;/span&gt; &lt;span class="o"&gt;{&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;ProductService&lt;/span&gt; &lt;span class="n"&gt;productService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ProductController&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Qualifier&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"productServiceImpl"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;ProductService&lt;/span&gt; &lt;span class="n"&gt;productService&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;productService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;productService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getProducts&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;productService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getProducts&lt;/span&gt;&lt;span class="o"&gt;());&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;As we can see, the &lt;code&gt;@Qualifier&lt;/code&gt; annotation is present in the constructor of our ProductController.&lt;br&gt;
The &lt;code&gt;@Qualifier&lt;/code&gt; annotation is used to specify which bean implementation should be injected into the &lt;code&gt;ProductController&lt;/code&gt; constructor when there are multiple possible implementations of the &lt;code&gt;ProductService&lt;/code&gt; interface. In this case, we have two implementations, so we want to use &lt;code&gt;ProductServiceImpl&lt;/code&gt; by default.&lt;/p&gt;

&lt;p&gt;With everything reviewed so far, we just need to run our code, and we should be able to execute it via &lt;code&gt;http://localhost:8080.&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;p&gt;With this, we are going to perform the tests to validate that our service is working with our Flag feature implementation. The products that are tested with are those created in the class bean &lt;code&gt;**SpringUnleashFeatureFlagConfiguration**&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Testing with flag enabled
&lt;/h4&gt;

&lt;p&gt;In this case we go to our unleash server and activate our flag (by default it is already activated). To activate our feature flag, we only activate the development option which is the environment where the flag must be activated.&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%2Fptx3lt16p91jojfwydbh.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%2Fptx3lt16p91jojfwydbh.png" alt="test 1" width="800" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once our feature-flag has been activated, we proceed to run a test in postman to validate the operation:&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%2Fen4s31shj42z72vtn6vq.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%2Fen4s31shj42z72vtn6vq.png" alt="test 2" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see, the price parameter is shown with the discount already applied, making the first test case correct. Now, let’s test with the inactive flag&lt;/p&gt;

&lt;h4&gt;
  
  
  Testing with flag disabled
&lt;/h4&gt;

&lt;p&gt;To deactivate the flag, as we did in the previous test, we just deactivate the development option of our flag in our unleash server.&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%2F011fdwhgn920pczfnj7v.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%2F011fdwhgn920pczfnj7v.png" alt="test 3" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once our feature-flag has been deactivate, we proceed to run a test in postman to validate the operation:&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%2F8do50301yugf21cotth5.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%2F8do50301yugf21cotth5.png" alt="test 4" width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see, the prices in the price parameter are the original prices without applying the discount.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With that, we can say that our feature-flag implementation is working correctly!!! 🚀&lt;/strong&gt;&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%2Falsb6p0z481y9gwynsfy.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%2Falsb6p0z481y9gwynsfy.gif" alt="celebrate" width="500" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Feature flags are an invaluable tool for controlling the deployment of new features in a flexible and dynamic manner. They allow teams to enable or disable specific functionality without the need for code redeployments, offering improved control over the application’s behavior.&lt;/p&gt;

&lt;p&gt;In this case, we demonstrated how to implement feature flags with Spring Boot and Unleash. By integrating Unleash to manage feature flags, we can conditionally enable or disable certain features like applying discounts to products based on the status of a feature flag. This provides the ability to control the deployment of features progressively, perform A/B testing, and quickly rollback faulty features without affecting the entire application.&lt;/p&gt;

&lt;p&gt;In the end, the successful implementation of the feature flag system ensures that we can safely deploy new features, test them with specific user groups, and roll back if needed, all while minimizing risk and disruption.&lt;/p&gt;

&lt;p&gt;Happy coding!! ❤️&lt;/p&gt;

</description>
      <category>java</category>
      <category>design</category>
      <category>tutorial</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Design Patterns Serie — Structural Chapter: Proxy Pattern</title>
      <dc:creator>bryam vega</dc:creator>
      <pubDate>Mon, 20 Jan 2025 19:51:17 +0000</pubDate>
      <link>https://dev.to/bryam_vega_487231d2d7c62e/design-patterns-serie-structural-chapter-proxy-pattern-ji0</link>
      <guid>https://dev.to/bryam_vega_487231d2d7c62e/design-patterns-serie-structural-chapter-proxy-pattern-ji0</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Design patterns are solutions to common problems encountered in software development. The objective of these design patterns could be equated with the phrase “not reinventing the wheel” because its purpose is that, to provide solutions to problems that usually appear very frequently.&lt;/p&gt;

&lt;p&gt;However, design patterns are not an absolute solution, I could say that it is a guide on how to solve a problem equal or similar to the moment the pattern was created, from then on, it is up to the developer to adapt the pattern to the business needs.&lt;/p&gt;

&lt;p&gt;Design patterns are now divided into three sections: Creative, Structural and Behavioral. Each of them with its defined characteristics and structure.&lt;/p&gt;

&lt;p&gt;In this article, we are going to learn about one of the most popular software design patterns within the structural patterns section and that is the Proxy Pattern.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Proxy Pattern?
&lt;/h2&gt;

&lt;p&gt;To understand what the proxy pattern is, it is first important to understand the problem behind this pattern.&lt;/p&gt;

&lt;p&gt;Imagine that as developers, we are told that in order to consume some services to obtain some User data, we must first consume a service to obtain a JWT (Json Web Token).&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem
&lt;/h3&gt;

&lt;p&gt;Currently we do not know the use of the proxy pattern, so we imagine that every time we need to consume the service to get the user’s data we will have to call the service to get the JWT that returns a JWT with a expiration time. With this we are doing the following scenario.&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%2Fxmoqnz3wuenycjzg7lfz.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%2Fxmoqnz3wuenycjzg7lfz.png" alt="Proxy fail" width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our &lt;strong&gt;QA&lt;/strong&gt; tells us that the service to get the customer data is taking longer than usual. So, we analyze our service and we see that the service that calls the user data is working correctly, however, the service that provides the JWT is taking too long because we are requesting a token every time we call the service. So the concept of token &lt;strong&gt;expiration&lt;/strong&gt; is not working.&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%2Fma48unt48u4nil304lip.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%2Fma48unt48u4nil304lip.gif" alt="proxy good" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Therefore, they are asking you to fix this problem and you don’t know what to do.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;Luckily, you found this article that talks about how to fix this problem using the proxy pattern&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%2Fnhwdtqbqki60lovwtxpt.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%2Fnhwdtqbqki60lovwtxpt.gif" alt="diagram" width="498" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reviewing in more detail, the &lt;strong&gt;proxy pattern&lt;/strong&gt; consists of creating a control layer called Proxy whose main function is to act as an intermediary between the client and the real object to be accessed, managing or regulating this access in various ways.&lt;/p&gt;

&lt;p&gt;This pattern is commonly used to control the creation of resource-intensive objects, protect them from unauthorized access, or add additional functionality during interaction with the actual objects.&lt;/p&gt;

&lt;p&gt;With this idea, the initial problem using a proxy pattern looks as follows:&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%2Fwg15trx4s4hupx1h6u25.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%2Fwg15trx4s4hupx1h6u25.png" alt="diagram" width="800" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we see it through a higher level diagram, we see how this proxy pattern works through a class diagram to see how to implement it.&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%2Fwsyiuoinxl9nbwe9l85a.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%2Fwsyiuoinxl9nbwe9l85a.png" alt="diagram" width="365" height="566"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see in the class diagram, the proxy pattern is composed of the following classes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Subject&lt;/strong&gt; (JWTService): This is the common interface that both the proxy and the real subject will implement. It defines the operations that the client can perform. In this case we can see that request JWT will be the common method that both classes will implement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real Subject&lt;/strong&gt; (JWTServiceImpl): This is the class that implements the &lt;code&gt;JWTService&lt;/code&gt; interface and provides the real functionality of the service. This object performs the real operations related to JWT tokens, such as generating a token.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proxy&lt;/strong&gt; (JWTServiceProxy): This is the object that controls access to the real object (JWTServiceImpl). The proxy can perform additional tasks such as security handling, logging, or cache handling before or after invoking calls to the real object. In this case it handles the lifecycle of the JWT class that returns the &lt;code&gt;JWTServiceImpl&lt;/code&gt; . If we notice JWT class contains a method called &lt;code&gt;validateJWT&lt;/code&gt; that allows to validate that our JWT is still functional and not to call it every time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I know that the class diagram may seem a bit weird and confusing to understand, but believe me, when we put this into code, everything will be more understandable!&lt;/p&gt;

&lt;h2&gt;
  
  
  Implement Proxy Pattern for JWT generation
&lt;/h2&gt;

&lt;p&gt;The code of this implementation is hosted in this repository in case you want to clone it and try it yourself: &lt;a href="https://github.com/bvegaM/design-pattern-series/tree/structural/proxy?source=post_page-----27b1e55fd08c--------------------------------" rel="noopener noreferrer"&gt;Proxy Pattern Repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Based on our created class diagram, we are going to implement it in code and this way you will see that you will understand the proxy pattern in a faster way.&lt;/p&gt;

&lt;h3&gt;
  
  
  The JWT object
&lt;/h3&gt;

&lt;p&gt;A JWT class that contains the data necessary for a Json Web Token to work. It is presented as follows.&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="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;JWT&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;expirationTime&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;creationTime&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;validateJWT&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
        &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;currentTimeInSeconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;currentTimeInSeconds&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;creationTime&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;expirationTime&lt;/span&gt;&lt;span class="o"&gt;();&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;Since Java 16, the records known as &lt;code&gt;records&lt;/code&gt; are born, which allow the attributes that contain a class to be immutable by default, keeping the same characteristics of a normal class, such as creating methods such as &lt;code&gt;validateJWT()&lt;/code&gt;. This method will be important because it will be used by our proxy method to validate the token lifecycle.&lt;/p&gt;

&lt;h3&gt;
  
  
  The subject
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;subject&lt;/code&gt; is represented by the JWTService interface. This interface defines a single &lt;code&gt;requestJWT()&lt;/code&gt; method that, when implemented, should be responsible for requesting and returning a &lt;code&gt;JWT&lt;/code&gt; (JSON Web Token) object.&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;JWTService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="no"&gt;JWT&lt;/span&gt; &lt;span class="nf"&gt;requestJWT&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;This interface will be implemented by the Real Subject and the proxy, since both require the common operation &lt;code&gt;requestJWT()&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Real Subject
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;JWTServiceImpl&lt;/code&gt; class serves as the &lt;code&gt;RealSubject&lt;/code&gt; within the Proxy pattern, where its primary responsibility is the generation of JSON Web Tokens (JWT).&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;JWTServiceImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;JWTService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="no"&gt;JWT&lt;/span&gt; &lt;span class="nf"&gt;requestJWT&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;JWT&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;generateToken&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;generateToken&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;randomUUID&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;randomUUID&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;randomUUID&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"."&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
                &lt;span class="s"&gt;"."&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="o"&gt;;&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;For this case, we simulate the creation of a JWT using the &lt;code&gt;generateToken()&lt;/code&gt; method, by generating &lt;code&gt;UUID&lt;/code&gt; for the &lt;code&gt;header&lt;/code&gt;, payload and signature, just as an example, in real life, this must be obtained through a security service or a platform such as keycloak or auth0.&lt;/p&gt;

&lt;p&gt;Additionally let’s take into account that our JWT will have a lifetime of 5 seconds and its creation time will be the current time in which we execute the service in seconds, as you can see in the &lt;code&gt;requestJWT()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;Finally we can notice that our &lt;code&gt;RealSubject&lt;/code&gt; is only in charge of generating the JWT, it does absolutely nothing else, so at the beginning,** we did not realize that we had to validate the lifetime of the jwt*&lt;em&gt;, so our **proxy pattern&lt;/em&gt;* will come in to solve our life.&lt;/p&gt;

&lt;h3&gt;
  
  
  The proxy
&lt;/h3&gt;

&lt;p&gt;The proxy, in this case &lt;code&gt;JWTServiceProxy&lt;/code&gt;, serves as an intermediary between the client and the actual service (&lt;code&gt;JWTServiceImpl&lt;/code&gt;). Its role is to manage the JWT token request flow, implementing a caching strategy that improves operational efficiency and reduces the load on system resources.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initialization: The proxy class initializes its concrete dependency on &lt;code&gt;JWTServiceImpl&lt;/code&gt; within its constructor (&lt;strong&gt;composition&lt;/strong&gt;). This ensures all token requests are routed through the proxy before reaching the actual service.&lt;/li&gt;
&lt;li&gt;Token Caching: It maintains a cached instance of the JWT. Before processing a new request, it checks whether it already possesses a valid token. If the stored token is invalid or has expired, it proceeds to request a new token from the real service, &lt;code&gt;JWTServiceImpl&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;JWTServiceProxy&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;JWTService&lt;/span&gt; &lt;span class="o"&gt;{&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;JWTService&lt;/span&gt; &lt;span class="n"&gt;jwtService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="no"&gt;JWT&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;JWTServiceProxy&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jwtService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;JWTServiceImpl&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="no"&gt;JWT&lt;/span&gt; &lt;span class="nf"&gt;requestJWT&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jwt&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;validateJWT&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;jwt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jwtService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;requestJWT&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;;&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;The &lt;code&gt;requestJWT()&lt;/code&gt; method encapsulates the logic for validating and issuing tokens:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Token Validation:&lt;/strong&gt; Checks if the current cached token is valid using &lt;code&gt;jwt.validateJWT()&lt;/code&gt;. This step is crucial to ensure that the tokens are not only present but also secure and reliable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conditional Token Generation:&lt;/strong&gt; If the token is null or invalid, the proxy requests a new token, which is done by calling the real service. This mechanism ensures that the system does not generate tokens unnecessarily, optimizing resource usage.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Test Proxy Pattern
&lt;/h3&gt;

&lt;p&gt;Finally, since we have implemented our proxy pattern, the last thing we have left is to validate to see if this pattern really works. For it we instantiate the &lt;code&gt;Subject&lt;/code&gt; initializing it with the proxy and not with the &lt;code&gt;RealSubject&lt;/code&gt;.&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&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;Logger&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLogger&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&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;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;JWTService&lt;/span&gt; &lt;span class="n"&gt;proxy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;JWTServiceProxy&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="no"&gt;JWT&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;proxy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;requestJWT&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TOKEN: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

        &lt;span class="n"&gt;jwt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;proxy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;requestJWT&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TOKEN TWO: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

        &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;jwt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;proxy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;requestJWT&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TOKEN THREE: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="o"&gt;());&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;If we notice, we can notice that we make &lt;strong&gt;3 requests to get the JWT&lt;/strong&gt;, however, before the last request we use &lt;code&gt;Thread.sleep(5000)&lt;/code&gt; which guarantees that we are going to wait for the thread to sleep for about &lt;strong&gt;5 seconds&lt;/strong&gt;, which is the time configured in our JWT mock to expire.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Nov 27, 2024 9:16:21 PM org.bvega.Main main
INFO: TOKEN: 9b348add-fcca-4187-b7cd-f36e07e97e97.63a81aa0-6c75-4b7e-8178-6488c61a5181.5ae3bea6-9ba9-4727-b183-875baf8de9a8
Nov 27, 2024 9:16:21 PM org.bvega.Main main
INFO: TOKEN TWO: 9b348add-fcca-4187-b7cd-f36e07e97e97.63a81aa0-6c75-4b7e-8178-6488c61a5181.5ae3bea6-9ba9-4727-b183-875baf8de9a8
Nov 27, 2024 9:16:26 PM org.bvega.Main main
INFO: TOKEN THREE: f06eea26-15c7-408b-9a73-1804121cca1f.2f3360be-5cb5-4ac1-be32-d3af242cd998.19e68e66-6f03-493e-8b42-8542347cace7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And what a &lt;strong&gt;surprise&lt;/strong&gt;!!! 😮, as you can see, the first 2 tokens are the same, but the third one is a new one since the life time of the initial token expired, this validates that our proxy pattern worked correctly, &lt;strong&gt;congratulations&lt;/strong&gt; !!!! 😄&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%2Ffiqosbpfzo7jwtmrdozm.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%2Ffiqosbpfzo7jwtmrdozm.gif" alt="exito" width="500" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;The Proxy pattern is a powerful tool in the software developer’s arsenal, offering significant advantages in terms of performance enhancement and security. However, its implementation should be approached with a clear understanding of the system’s architectural needs and operational challenges. Properly utilized, the Proxy pattern can lead to more maintainable, secure, and efficient software systems, making it a worthwhile consideration for projects requiring controlled access and optimized resource management.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy coding!!&lt;/strong&gt; ❤️&lt;/p&gt;

</description>
      <category>java</category>
      <category>design</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
