<?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: Lucca Mabel</title>
    <description>The latest articles on DEV Community by Lucca Mabel (@eusoumabel).</description>
    <link>https://dev.to/eusoumabel</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%2F683088%2F5ad0d0c1-c38a-496d-b62a-ab935f554ad3.png</url>
      <title>DEV Community: Lucca Mabel</title>
      <link>https://dev.to/eusoumabel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eusoumabel"/>
    <language>en</language>
    <item>
      <title>The Universe of Exceptions in Dart: An Uncomplicated Guide</title>
      <dc:creator>Lucca Mabel</dc:creator>
      <pubDate>Thu, 07 Dec 2023 21:08:43 +0000</pubDate>
      <link>https://dev.to/eusoumabel/the-universe-of-exceptions-in-dart-an-uncomplicated-guide-1dko</link>
      <guid>https://dev.to/eusoumabel/the-universe-of-exceptions-in-dart-an-uncomplicated-guide-1dko</guid>
      <description>&lt;p&gt;Developing in Dart is an exciting journey full of challenges, and one of the crucial aspects of this journey is exception handling. In this article, we'll dive head first into these topics, demystifying exception handling to make it more accessible for our end users.&lt;/p&gt;

&lt;p&gt;The importance of implementing exception handling is to be able to deal with situations that we cannot always predict, so that our users are not impacted. From this we were able to build more robust applications, capable of dealing with unexpected situations effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Success Only Programming&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A common approach in the world of programming is to program a solution targeting only the path that works, where everything always works out. However, by thinking only about success, we end up not preparing our application to deal with real-world situations, where things may not work the way we expect. By neglecting these problems, we end up with a highly unpredictable and low-quality application.&lt;/p&gt;

&lt;p&gt;It is important to think beyond the success story, and prepare the system for extraordinary, exceptional situations.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Let's understand the difference between Errors and Exceptions&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In the Dart documentation, we can understand in more depth about &lt;a href="https://dart.dev/language/error-handling#exceptions" rel="noopener noreferrer"&gt;Error Handling&lt;/a&gt; and some definitions that we will cover now, but in order to be objective:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Exceptions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Situations that can be anticipated and that the software must be prepared to deal with.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Errors&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Situations that should not occur and that the developer should have avoided.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Try On-Catch-Finally: Dealing with the Unexpected&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now, how can we anticipate and deal with exceptional situations? Within Dart, and many other programming languages, we have a code structure precisely designed to help us deal with this: &lt;strong&gt;Try On-Catch-Finally&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Try&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Try&lt;/code&gt; is used when we have a block of code that we know can cause a failure. So, we wrap the code with the &lt;code&gt;Try&lt;/code&gt; structure, so that it can be properly handled.&lt;/p&gt;

&lt;p&gt;In the example below, we can see that the &lt;code&gt;toInt()&lt;/code&gt; method was structured with only the happy path in mind, however, if an error occurs, the system will simply ‘crash’.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"5"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//Works perfectly&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"not a number"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//Uncaught Error: FormatException: not a number&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How can we prepare the system to deal with this situation?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Using the &lt;code&gt;Try&lt;/code&gt; structure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"not a number"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// we'll need to complete this with 'catch', 'on' or 'finally'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;On&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Now that we purposely caused an exception, and started the process of handling it so that our user is not impacted, let's understand how to handle it when we know exactly the exception that will be thrown.&lt;/p&gt;

&lt;p&gt;We know that if we pass a String &lt;code&gt;“not a number”&lt;/code&gt;, the &lt;code&gt;toInt()&lt;/code&gt; method will throw a &lt;code&gt;FormatException&lt;/code&gt;. To be able to catch this exception, we will use the &lt;strong&gt;on&lt;/strong&gt; structure.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;on&lt;/code&gt; is ideal for use in situations where we know which exception can be triggered or when we want to define special treatment for a certain type of exception.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"not a number"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kd"&gt;on&lt;/span&gt; &lt;span class="n"&gt;FormatException&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The value is not a valid number."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Catch&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Using &lt;code&gt;catch&lt;/code&gt; is another way to capture an exception.&lt;/p&gt;

&lt;p&gt;Catching an exception means that it will not be propagated further. It is an opportunity to address it so that the user understands what went wrong.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"not a number"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kd"&gt;on&lt;/span&gt; &lt;span class="n"&gt;FormatException&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;catch&lt;/code&gt; provides the parameter &lt;code&gt;e&lt;/code&gt; which is equivalent to &lt;code&gt;error&lt;/code&gt; or &lt;code&gt;exception&lt;/code&gt;. With it, we have access to the triggered object that can help us understand what went wrong.&lt;/p&gt;

&lt;p&gt;💡 If the captured object is a FormatException, ‘e’ is of type FormatException.&lt;/p&gt;

&lt;p&gt;It is important to highlight that in Dart, anything can be thrown as an &lt;code&gt;exception&lt;/code&gt;, so it is important to know how they work in order to handle them in the best possible way.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Finally&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;finally&lt;/code&gt; is a clause that guarantees that a given piece of code is executed regardless of whether an exception is triggered or not. If an exception is thrown, it is only triggered after.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"not a number"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// 1º&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kd"&gt;on&lt;/span&gt; &lt;span class="n"&gt;FormatException&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// 2º&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"we reached the end"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 3º&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;we&lt;/span&gt; &lt;span class="n"&gt;reached&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;Uncaught&lt;/span&gt; &lt;span class="nl"&gt;Error:&lt;/span&gt; &lt;span class="nl"&gt;FormatException:&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Throwing Exceptions with Throw&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A very common situation is when we try to indicate the success or failure of an operation using booleans, or returning some value that represents success or error. But in cases like this, when an error is returned, finding its exact source can be like looking for a needle in a haystack.&lt;/p&gt;

&lt;p&gt;Below, we can see that the &lt;code&gt;toInt()&lt;/code&gt; method does not give us any information if something exceptional happens.&lt;/p&gt;

&lt;p&gt;For example, I created the rule that &lt;strong&gt;the passed String cannot be empty&lt;/strong&gt;. However, the only way I can check is if the &lt;code&gt;toInt()&lt;/code&gt; method returns &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This ends up being a problem when I inform, for example, &lt;code&gt;toInt("0")&lt;/code&gt;. How do I know when the result returned is a success or error &lt;code&gt;0&lt;/code&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// return 0 - success&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// return 0 - error&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;- indicates an error&lt;/span&gt;

   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;- indicates success&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To facilitate this process, let's understand the concept of throwing exceptions with &lt;code&gt;throw&lt;/code&gt;. This practice will help us improve the clarity of our codes and also provide a clear path to understanding and solving problems, without the uncertainty of abstract values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kd"&gt;on&lt;/span&gt; &lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The provided value is empty."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the adjustment we made above, we can validate within the method itself that &lt;strong&gt;the String passed cannot be empty&lt;/strong&gt;, and if it is, an &lt;code&gt;exception&lt;/code&gt; will be thrown informing the user that the rule was not met. Otherwise, the method continues normally.&lt;/p&gt;

&lt;p&gt;It is also important to take into account that &lt;code&gt;int.parse(value)&lt;/code&gt; can still trigger any type of exception. Therefore, we have our &lt;code&gt;try {} on Exception catch (e) {}&lt;/code&gt; structure in the &lt;code&gt;main&lt;/code&gt; method.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Creating Custom Exceptions&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To further improve the clarity of our code, and the projects we work on in our daily lives, we can create customized exceptions.&lt;/p&gt;

&lt;p&gt;I will create an exception for each rule:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The value provided can't be empty;&lt;/li&gt;
&lt;li&gt;The value provided can't be negative.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InformedValueIsEmptyException&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nd"&gt;@override&lt;/span&gt;
   &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;'The provided value is empty.'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InformedValueIsUnderLimitException&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="n"&gt;InformedValueIsUnderLimitException&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="kd"&gt;required&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;value&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

   &lt;span class="nd"&gt;@override&lt;/span&gt;
   &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"The provided value can't be less than 0. You entered '&lt;/span&gt;&lt;span class="si"&gt;$value&lt;/span&gt;&lt;span class="s"&gt;'."&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;By organizing our &lt;code&gt;toInt()&lt;/code&gt; method with the appropriate exceptions being referenced, we can clearly see the possible situations we have and how we can handle them clearly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="n"&gt;InformedValueIsEmptyException&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

   &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="n"&gt;InformedValueIsUnderLimitException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;value:&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Properties for Exceptions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Sometimes, as an exception, it is necessary to provide the user with information that may be useful so that they can have a better understanding of the problem. For example, in the exception below, we make it clear to the user that the value &lt;strong&gt;x&lt;/strong&gt; they provided don't satisfy our rule that this value can't be negative.&lt;/p&gt;

&lt;p&gt;💡 To identify the necessary parameters, think about how to clearly communicate the information to the user.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InformedValueIsUnderLimitException&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;InformedValueIsUnderLimitException&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="kd"&gt;required&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;value&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nd"&gt;@override&lt;/span&gt;
&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"The provided value can't be less than 0. You entered '&lt;/span&gt;&lt;span class="si"&gt;$value&lt;/span&gt;&lt;span class="s"&gt;'."&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Saving in memory
&lt;/h2&gt;

&lt;p&gt;Throughout this article, we explored the world of exception handling in Dart. Understanding how to implement exception handling strengthens our applications, preparing them to effectively deal with unexpected situations.&lt;/p&gt;

&lt;p&gt;When programming, it's common to only focus on everything working perfectly. It's important not to neglect preparing for real-world situations. The best possible approach involves thinking beyond the success case, preparing the system to deal with exceptional situations.&lt;/p&gt;

&lt;p&gt;Dart's &lt;strong&gt;Try On-Catch-Finally&lt;/strong&gt; structure is a powerful tool for dealing with the unexpected. Using &lt;code&gt;try&lt;/code&gt; to wrap blocks of code that may fail, &lt;code&gt;on&lt;/code&gt; to catch specific exceptions, &lt;code&gt;catch&lt;/code&gt; to handle exceptions and &lt;code&gt;finally&lt;/code&gt; to guarantee code execution, even after an exception occurs.&lt;/p&gt;

&lt;p&gt;We learned about throwing exceptions with &lt;code&gt;throw&lt;/code&gt;, abandoning the common practice of indicating success or failure using booleans or special values. We also created custom exceptions, such as &lt;code&gt;InformedValueIsEmptyException&lt;/code&gt; and &lt;code&gt;InformedValueIsUnderLimitException&lt;/code&gt;, that helped provide clarity about the problems we encountered, making our code easier to understand and maintain.&lt;/p&gt;

&lt;p&gt;In short, by adopting good exception handling practices and creating custom exceptions, we increase the quality of our code, promoting more robust, secure and understandable applications.&lt;/p&gt;

&lt;p&gt;💡 This article was produced based on notes from my studies on the Alura course &lt;a href="https://www.alura.com.br/curso-online-dart-lidando-exceptions-null-safety" rel="noopener noreferrer"&gt;Dart: Dealing with Exceptions and Null Safety&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>dart</category>
      <category>learning</category>
      <category>flutter</category>
    </item>
    <item>
      <title>From Chaos to Consistency: How I Improved My Productivity</title>
      <dc:creator>Lucca Mabel</dc:creator>
      <pubDate>Thu, 09 Nov 2023 17:27:45 +0000</pubDate>
      <link>https://dev.to/eusoumabel/from-chaos-to-consistency-how-i-improved-my-productivity-3g5d</link>
      <guid>https://dev.to/eusoumabel/from-chaos-to-consistency-how-i-improved-my-productivity-3g5d</guid>
      <description>&lt;p&gt;For a while, I was looking for ways to improve my productivity. It's a topic that has always fascinated me because the idea of doing more with less effort is very appealing. However, the ideal vision of &lt;strong&gt;"being productive"&lt;/strong&gt; often led me astray. The process of trying to do more, deliver more, be aware of everything, multitask, be a reference, study everything, and know everything became quite exhausting.&lt;/p&gt;

&lt;p&gt;This approach ended up yielding results opposite to what I was aiming for. I wanted to do more with less effort, but I ended up in a cycle of doing much more and using up all my energy to keep up.&lt;/p&gt;

&lt;p&gt;When I began to realize this was happening, after bouts of anxiety from feeling like I wasn't delivering enough and having no energy left for anything in my life, I decided to reevaluate my concepts about &lt;strong&gt;"what it means to be productive."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the past, I used about eight different software applications to organize things like notes, calendars, studies, routines, habits. I must admit it was quite chaotic. Another thing I noticed that disrupted my routine was the lack of a strategic schedule.&lt;/p&gt;

&lt;p&gt;I knew what I needed to do during the week, but I didn't know which days to do what. Did something have a deadline? I didn't know. Did something have priority? I didn't know. Furthermore, I had a smartphone addiction and didn't stick to my chaotic routine's schedule. All of this led to information overload, workflow congestion, fatigue, lack of maintainability, and an ever-increasing list of tasks because almost nothing got done in line.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Decided to Change and Believe Has Improved My Productivity and Energy Levels
&lt;/h2&gt;

&lt;p&gt;First, I sat down and put on paper what I wanted to adjust. For me, the things that became a priority were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learning&lt;/li&gt;
&lt;li&gt;Nutrition&lt;/li&gt;
&lt;li&gt;Physical activity&lt;/li&gt;
&lt;li&gt;Sleep&lt;/li&gt;
&lt;li&gt;Personal projects&lt;/li&gt;
&lt;li&gt;Free time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After defining these priorities, the next step, which was organizing a routine, became much easier. For my routine, I established rules. These rules help me set boundaries for what is feasible and what is not, to maintain a level of consistency in my day, and not overexert myself. Some of these rules include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wake-up time: Allow space for a morning routine that prepares me for the day (e.g., waking up, showering, walking the dog, having breakfast, ...).&lt;/li&gt;
&lt;li&gt;Study time: Allocate one hour of study every workday.&lt;/li&gt;
&lt;li&gt;Planning the workday: Allocate the first 30 minutes of work to define priorities for the day and review what was done the previous day.&lt;/li&gt;
&lt;li&gt;Off-duty time: Allow space for personal projects, physical activity, therapy, or free time (especially on weekends).&lt;/li&gt;
&lt;li&gt;Bedtime: Allow space for a nighttime routine that helps me rest for the next day (e.g., setting the alarm, meditating, reading, ...).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After I started incorporating these rules into my routine, I felt it became much easier to get through the day. However, some other things have also helped me maintain this consistency. Remember when I mentioned using eight apps and being addicted to my smartphone? Well, I decided to be a bit more radical about addressing this issue.&lt;/p&gt;

&lt;p&gt;First and foremost, I cleaned up my smartphone. I deleted all the apps I didn't use, removed all non-essential app notifications, deleted social media apps, and set up "Focus" modes. Focus is an Apple feature that allows the phone to behave differently based on specific rules. In my case, I set Focus modes for Study, Work, Exercise, and Sleep. Each one has its specific rules, but the idea is that my phone doesn't remind me of its existence during these times when I need to focus my energy on something else.&lt;/p&gt;

&lt;p&gt;Once the Focus modes were set up, I went on to clean up and redefine my entire workflow and establish my routine once and for all, following the rules and focusing on my current goals. I now use only four apps to manage my overall routine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://cron.com/" rel="noopener noreferrer"&gt;Cron&lt;/a&gt;&lt;/strong&gt;: A calendar with a practical and clean interface. I use it to create and check fixed appointments (e.g., study time, regular meetings, time to work on side projects, physical activity time, meal prep for the week, ...).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://noteplan.co/" rel="noopener noreferrer"&gt;NotePlan&lt;/a&gt; + &lt;a href="https://www.stayinsession.com/" rel="noopener noreferrer"&gt;Session&lt;/a&gt;&lt;/strong&gt;: A powerful note-taking app aimed at helping with daily organization, creating time blocks, and tracking activity progress, combined with a Pomodoro technique software that allows note-taking at the end of each session and setting focus goals. I use this combination to manage my workdays. These are apps I was able to access through a &lt;a href="https://go.setapp.com/invite/9kqfbxg9" rel="noopener noreferrer"&gt;Setapp&lt;/a&gt; subscription, and they have definitely made a difference in this process.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.notion.so/" rel="noopener noreferrer"&gt;Notion&lt;/a&gt;&lt;/strong&gt;: A highly versatile note-taking tool that allows documenting various things in various ways. I use it to store all kinds of information and to manage Is It Safe?, a project I've been leading for almost two years.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How Has This Helped Me?
&lt;/h2&gt;

&lt;p&gt;I started this process seven months ago, taking it one step at a time and maintaining the determination to be consistent, even if I can't always follow the routine to the letter. I have been trying to do my best.&lt;/p&gt;

&lt;p&gt;However, now I feel more energized during the day, I can see progress in my health and eating habits. I no longer have the constant need to check my phone or social media. I've started to read more, and, more importantly, I don't feel exhausted when the day is over.&lt;/p&gt;

&lt;p&gt;What has helped me the most in this process is having a set bedtime and waking time and effectively using my calendar to keep my commitments recorded, preventing me from wasting energy every day wondering &lt;strong&gt;"What do I have to do today?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This post isn't a set of rules or a one-size-fits-all guide. It's simply an account of what went very wrong for me and what has been working so far. I believe that over the long term, more solid changes will be visible as I adjust to these new habits I've created. However, regardless of the process you use, it's essential to keep two things in mind: &lt;strong&gt;consistency is key, and take your bedtime seriously.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>career</category>
    </item>
    <item>
      <title>Entendendo Algoritmos: Recursão</title>
      <dc:creator>Lucca Mabel</dc:creator>
      <pubDate>Fri, 20 Oct 2023 21:16:51 +0000</pubDate>
      <link>https://dev.to/eusoumabel/entendendo-algoritmos-recursao-db6</link>
      <guid>https://dev.to/eusoumabel/entendendo-algoritmos-recursao-db6</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Ao longo da minha leitura do Entendendo Algoritmos, eu tenho revisitado muitos conceitos e técnicas que eu já havia me esquecido que existiam e algumas que eu nunca consegui entender (até agora haha). Dentro desse post (e em mais alguns outros q vão vir ao longo da minha leitura) eu vou trazer esses conceitos sob uma análise de estudos pessoais.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  O que é 'Recursão'?
&lt;/h2&gt;

&lt;p&gt;Imagine que você chegou na academia e tava tão empolgado com o treino que colocou sua carteira no primeiro armário vazio que você achou. Quando acabou o treino, você não consegue mais lembrar em qual armário você guardou suas coisas então, vai abrindo um de cada vez até você encontrar.&lt;/p&gt;

&lt;p&gt;Recursão começa por aí, executar uma função de forma repetida até encontrar o resultado correto. &lt;/p&gt;

&lt;p&gt;Mas... isso também não seria um loop?&lt;/p&gt;

&lt;p&gt;Sim, um loop pode ser uma alternativa para resolver tipos de situações como essa. Inclusive, há casos em que loops são mais benéficos pois, recursão não trás nenhum bônus em termos de desempenho.&lt;/p&gt;

&lt;p&gt;E por mais não-atrativo que eu esteja fazendo recursão parecer, ela tem uma qualidade sem igual: &lt;strong&gt;Objetividade&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Mas, resumindo:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Recursão é quando uma função chama a si mesma.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Como estruturar uma recursão?
&lt;/h2&gt;

&lt;p&gt;Ao estruturar uma recursão, temos duas sub-estruturas: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Caso recursivo: Quando a função chama ela mesma.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ex: Abrir um armário de cada vez, de forma contínua.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;- Caso-base: Quando a função não chama ela mesma, evitando um loop infinito.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ex: Parar de abrir os armários quando encontrar a carteira. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Como assim um loop infinito?&lt;/strong&gt; Pse, quando mal implementado, pode acontecer de uma função recursiva ficar chamando ela de novo e de novo para sempre. E como não queremos isso, vamos entender como estruturar uma.&lt;/p&gt;

&lt;p&gt;Esse é um exemplo de loop infinito. Presta atenção em como os números continuam reduzindo para sempre.&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%2F2wxm8zncr7ld59hpxuuy.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%2F2wxm8zncr7ld59hpxuuy.png" alt="Image description" width="517" height="515"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  #MinhaPrimeiraRecursão
&lt;/h2&gt;

&lt;p&gt;Vamos exemplificar recursão ao calcular o fatorial (!) de um número (num).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;num = 3, portanto 3! = 3 x 2 x 1 =&amp;gt; 6.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Problema:&lt;/strong&gt; Descobrir o fatorial de um número.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solução:&lt;/strong&gt; Multiplicar esse número por: ele mesmo - 1, até ele ser igual a 1.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Caso recursivo:&lt;/strong&gt; Multiplicar esse número por: ele mesmo - 1.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Caso-base:&lt;/strong&gt; até ele ser igual a 1.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Isso em código fica assim:&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%2Fgkbnf0qyuz67qixgl974.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%2Fgkbnf0qyuz67qixgl974.png" alt="Image description" width="507" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pilha e o lado sombrio da recursão
&lt;/h2&gt;

&lt;p&gt;Recursão é estruturada em cima de pilhas, assim como muitas coisas no seu computador. E, o que é uma pilha?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pilha é uma estrutura de dados onde o último dado inserido, é o primeiro a sair. Por exemplo, você tem uma &lt;strong&gt;pilha&lt;/strong&gt; de livros para ler, quando for iniciar a leitura, você pega o livro que está no topo, e assim sucessivamente até a pilha não existir mais. Para entender mais sobre pilhas, &lt;a href="https://dev.to/cristuker/estrutura-de-dados-o-que-e-uma-pilha-296p"&gt;aqui&lt;/a&gt; tem um material massa!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Contudo, ainda que recursão traga a magia da &lt;strong&gt;Objetividade&lt;/strong&gt;  tem a desvantagem de que você pode acabar sobrecarregando a sua pilha (da uma olhada &lt;a href="https://ricardo-reis.medium.com/pilha-de-chamadas-javascript-call-stack-19f1c89925d3" rel="noopener noreferrer"&gt;nesse artigo&lt;/a&gt; para entender porque isso acontece), como no exemplo abaixo:&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%2Fp561go37sdmc2xbv2s8f.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%2Fp561go37sdmc2xbv2s8f.png" alt="Image description" width="800" height="207"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mas, não precisa temer. Tem sempre outras duas alternativas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Voltar para o bom e velho loop;&lt;/li&gt;
&lt;li&gt;Utilizar Recursão de Cauda.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Recursão de Cauda
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Se você utiliza dart, já vou deixar adiantado que isso não vai dar certo e &lt;a href="https://github.com/dart-lang/language/issues/1159" rel="noopener noreferrer"&gt;aqui&lt;/a&gt; e &lt;a href="https://stackoverflow.com/questions/66356967/does-dart-feature-tail-call-optimization-tco" rel="noopener noreferrer"&gt;aqui também&lt;/a&gt; vão ter descritivos melhores das informações referentes à isso.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mas, caso você utilize uma linguagem que tenha suporte para Recursão de Cauda, ou curiosidade em como funciona, vamos aos trabalhos.&lt;/p&gt;

&lt;p&gt;O que diferencia a recursão de cauda da recursão normal é que a primeira utiliza menos memória durante o processo de empilhamento, fazendo com que ela seja mais rápida. &lt;/p&gt;

&lt;p&gt;Comparando de forma prática, ao calcular 5!, que é igual a 120, vemos uma diferença importante entre a recursão simples e a recursão de cauda. Na recursão comum, são necessárias 120 variáveis para rastrear as chamadas. Porém, na recursão de cauda, isso não é preciso, uma vez que a chamada recursiva é a última operação executada pela função. Isso simplifica o processo e economiza recursos, tornando o código mais eficiente. &lt;/p&gt;

&lt;p&gt;E ainda que dart não tenha a otimização de recursão em cauda, ainda sim temos o exemplo abaixo de como ela seria estruturada.&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%2Ff4syad76emb5am2fil6d.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%2Ff4syad76emb5am2fil6d.png" alt="Image description" width="548" height="549"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Recursão é quando uma função chama a si mesma;&lt;/li&gt;
&lt;li&gt;Recursão é uma boa alternativa para loops quando você está buscando mais &lt;strong&gt;objetividade&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;Às vezes pode acontecer de sua pilha ficar muito grande quando utilizar recursão;&lt;/li&gt;
&lt;li&gt;Você pode contornar o problema da pilha grande com loops ou com recursão de cauda.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.ic.unicamp.br/~oliveira/doc/mc102_2s2004/Aula19.pdf" rel="noopener noreferrer"&gt;Notas de Aula – Algoritmos e Programação de Computadores&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/hugaomarques/recursao-de-cauda-para-iniciantes-4da8"&gt;Recursão de cauda para iniciantes&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>algorithms</category>
      <category>dart</category>
      <category>learning</category>
    </item>
    <item>
      <title>Entendendo Algoritmos: Ordenação por Seleção</title>
      <dc:creator>Lucca Mabel</dc:creator>
      <pubDate>Wed, 18 Oct 2023 19:54:12 +0000</pubDate>
      <link>https://dev.to/eusoumabel/entendendo-algoritmos-ordenacao-por-selecao-p5d</link>
      <guid>https://dev.to/eusoumabel/entendendo-algoritmos-ordenacao-por-selecao-p5d</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Ao longo da minha leitura do Entendendo Algoritmos, eu tenho revisitado muitos conceitos e técnicas que eu já havia me esquecido que existiam e algumas que eu nunca consegui entender (até agora haha). Dentro desse post (e em mais alguns outros q vão vir ao longo da minha leitura) eu vou trazer esses conceitos sob uma análise de estudos pessoais.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  O que eu preciso saber sobre 'memória'?
&lt;/h2&gt;

&lt;p&gt;Bem... o mais simples de tudo é que a memória armazena informações. Mas, como ela faz isso?&lt;/p&gt;

&lt;p&gt;Imagine que você quer ir no cinema assistir o último lançamento. Ao comprar seu ingresso, tem uma seleção de assentos disponíveis para você escolher. Você seleciona o seu, finaliza a compra e recebe o código do seu assento.&lt;/p&gt;

&lt;p&gt;A memória funciona da mesma maneira! Você precisa armazenar algo, dentre os espaços disponíveis um é selecionado e você recebe um código falando qual espaço foi o escolhido.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;O código retornado é chamado de &lt;em&gt;endereço&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;O espaço escolhido é chamado de &lt;em&gt;slot&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Arrays x Listas Encadeadas
&lt;/h2&gt;

&lt;p&gt;Agora que entendemos 'memória' vamos nos aprofundar um pouco em 'Listas'.&lt;/p&gt;

&lt;p&gt;Simplificando, 'Listas' é quando você precisa armazenar mais de um elemento na memória. Por exemplo, ao invés de você ir só ao cinema, vai você e mais 3 amigos. Um único assento já não dá para todo mundo, vão precisar de mais!&lt;/p&gt;

&lt;p&gt;Mas, qual tipo de 'Lista' eu escolho? Um Array ou uma Lista Encadeada?&lt;/p&gt;

&lt;p&gt;Bem... depende de qual problema você quer resolver. &lt;/p&gt;

&lt;p&gt;Vamos entender melhor!&lt;/p&gt;

&lt;h3&gt;
  
  
  Arrays
&lt;/h3&gt;

&lt;p&gt;Quando utilizamos um array, significa que colocamos todas as nossas informações em slots um do lado do outro (contiguamente). Como se no cinema, sentasse você e seus amigos na mesma fileira, um do lado do outro.&lt;/p&gt;

&lt;p&gt;Mas isso acaba virando um problema quando aparece mais 2 amigos de surpresa e não tem mais espaço na fileira. Então, se ainda quiserem ficar todos juntos, todo mundo vai ter que mudar de lugar. E, isso demora.&lt;/p&gt;

&lt;p&gt;Mas tem duas formas de resolver esse problema. O primeiro é comprando ingressos a mais (reservando locais extras na memória). Mas, caso ninguém extra apareça, vai ser um disperdício. Ou pior, se aparecer mais gente do que você havia antecipado. Vai ter que mover todo mundo de novo.&lt;/p&gt;

&lt;p&gt;E a outra maneira é sentar em locais separados um dos outros. Assim todo mundo consegue ver o filme, sem precisar ficar movendo de fileira caso mais alguém apareça. Portanto, fazer uso de uma lista encadeada.&lt;/p&gt;

&lt;h3&gt;
  
  
  Listas encadeadas
&lt;/h3&gt;

&lt;p&gt;As listas encadeadas podem estar em qualquer lugar da memória. Cada um dos itens armazena o local do item seguinte e dessa forma, eles estão conectados em cadeia.&lt;/p&gt;

&lt;p&gt;Com elas, você não precisa ficar movendo seus itens caso precise armazenar mais coisas do que havia previsto.&lt;/p&gt;

&lt;h3&gt;
  
  
  Observações importantes
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Listas encadeadas são boas quando:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Você quer ler todos os itens da sua lista;&lt;/li&gt;
&lt;li&gt;Você quer priorizar inserção/deleção do que leitura;&lt;/li&gt;
&lt;li&gt;Você precisa inserir algo no meio da lista.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Arrays são bons quando:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Você quer acessar itens aleatórios da sua lista;&lt;/li&gt;
&lt;li&gt;Você quer priorizar leitura do que inserção.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ordenação por seleção
&lt;/h2&gt;

&lt;p&gt;Vamos para a prática!&lt;/p&gt;

&lt;p&gt;Imagine que você tem uma lista de livros, e você categorizou eles com notas de 0 à 10. Você gostaria de ordenar essa lista do seu livro favorito, para o menos favorito.&lt;/p&gt;

&lt;p&gt;Uma forma de fazer isso é pegando seu livro mais bem avaliado e colocando em uma outra lista. E fazendo isso até sua primeira lista não ter mais itens. No final, você vai ter uma lista ordenada pelo critério que você queria.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;O tempo para isso ser executado é de O(n&lt;sup&gt;2&lt;/sup&gt;).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A ordenação por seleção vai resolver o seu problema, mas ele não é um algoritmo rápido.&lt;/p&gt;

&lt;h3&gt;
  
  
  Como implementar?
&lt;/h3&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%2F1s0jrrrzjqokqqh559so.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%2F1s0jrrrzjqokqqh559so.png" alt="Image description" width="685" height="817"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com.br/Entendendo-Algoritmos-Ilustrado-Programadores-Curiosos/dp/8575225634" rel="noopener noreferrer"&gt;Entendendo Algoritmos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lucasfemartins.medium.com/desvendando-arrays-e-listas-encadeadas-e0818d81cb1d" rel="noopener noreferrer"&gt;Desvendando Arrays e Listas Encadeadas&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>algorithms</category>
      <category>dart</category>
      <category>learning</category>
    </item>
    <item>
      <title>Entendendo Algoritmos: Introdução a Algoritmos</title>
      <dc:creator>Lucca Mabel</dc:creator>
      <pubDate>Thu, 05 Oct 2023 20:57:11 +0000</pubDate>
      <link>https://dev.to/eusoumabel/entendendo-algoritmos-introducao-a-algoritmos-3d2n</link>
      <guid>https://dev.to/eusoumabel/entendendo-algoritmos-introducao-a-algoritmos-3d2n</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Ao longo da minha leitura do &lt;a href="https://www.amazon.com.br/Entendendo-Algoritmos-Ilustrado-Programadores-Curiosos/dp/8575225634" rel="noopener noreferrer"&gt;Entendendo Algoritmos&lt;/a&gt;, eu tenho revisitado muitos conceitos e técnicas que eu já havia me esquecido que existiam e algumas que eu nunca consegui entender (até agora haha). Dentro desse post (e em mais alguns outros q vão vir ao longo da minha leitura) eu vou trazer esses conceitos sob uma análise de estudos pessoais.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  O que é um algoritmo?
&lt;/h2&gt;

&lt;p&gt;O mais simples possível é que:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Um algoritmo é um conjunto de instruções que realizam uma tarefa."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Os algortmos são utilizados para facilitar o processo de resolver um problema. &lt;/p&gt;

&lt;p&gt;Dado que, em um contexto de programação, um problema pode se repetir várias vezes em diferentes partes do seu sistema (ou da sua jornada técnica), ter uma solução (ou um meio para chegar na sua solução) já pré-definido aceleraria e facilitaria mais o processo, correto? &lt;/p&gt;

&lt;p&gt;Bem, é ai que os algoritmos entram. Contudo, eles não se limitam à isso.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Cada trecho de código poderia ser chamado de um algoritmo."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Porquê algoritmos são importantes?
&lt;/h2&gt;

&lt;p&gt;Antes de partirmos para a prática, vamos entender porque é importante entendermos como os algoritmos funcionam.&lt;/p&gt;

&lt;p&gt;Vamos imaginar um &lt;strong&gt;problema&lt;/strong&gt; onde eu precise verificar se (a + b) é par.&lt;/p&gt;

&lt;p&gt;Com certeza, deve ter várias maneiras de implementar uma solução para esse problema. Mas como eu sei se uma solução é melhor que outra?&lt;/p&gt;

&lt;p&gt;Ainda que ambas retornem o resultado correto, uma pode ser mais rápida, a outra pode gastar menos memória. &lt;/p&gt;

&lt;p&gt;A partir do estudo de algoritmos, podemos aprender diversas técnicas de análise que nos permitam comparar soluções e definir qual delas faz mais sentido para resolver o problema.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ex: Ao precisar verificar se (a +b) é par. Se eu adicionar que preciso do resultado em até 2ms. De todos as soluções existentes, quais delas ainda solucionaria o meu problema?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Por isso é importante nos aprofundarmos além do que o algoritmo faz, e levar em conta também, como ele funciona.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solucionando problemas com Algoritmos
&lt;/h2&gt;

&lt;p&gt;Agora sim, vamos para prática! O primeiro algoritmo que vamos dar uma analisada é o de Pesquisa Binária. Ele facilita o processo de busca em listas ordenadas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pesquisa Binária
&lt;/h3&gt;

&lt;p&gt;Vamos introduzir com um exemplo que o livro trás:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Você está procurando um nome (Mabel) em uma agenda com 100 contatos. Você poderia começar da letra A e ir descendo até chegar na letra M. Mas, é mais provável que você comece ali pela metade da lista, porquê é mais perto de onde a letra M fica.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Bem.. vamos destrinchar:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problema:&lt;/strong&gt; Achar um nome na minha agenda de contatos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solução:&lt;/strong&gt; Começar da metade da lista para achar o resultado mais rápido.&lt;/p&gt;

&lt;p&gt;Isso tem nome e é &lt;strong&gt;Pesquisa Binária&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Pesquisa Binária é um algoritmo de busca que recebe uma lista ordenada de elementos e retorna a localização do item que você está buscando, caso ele esteja na lista."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Então... &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ex: Se entre 1 e 10, eu quero saber onde está o número 5, ele vai me retornar a posição dele da lista. E se eu quiser saber onde está o número 21, ele não vai me retornar nada.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Porquê Pesquisa Binária e não Pesquisa Simples?
&lt;/h4&gt;

&lt;p&gt;Lembra do exemplo das diversas soluções para verificar se (a + b) é par? Então, mesmo conceito. Ao comparar ambas, a Pesquisa Binária vai resolver meu problema da agenda de contatos muito mais rápido.&lt;/p&gt;

&lt;p&gt;Mas... como eu sei que isso é verdade?&lt;/p&gt;

&lt;p&gt;Na Pesquisa Simples, o que pode acontecer é:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ex 1: Eu querer o nome Aaron e o algoritmo ir la num pulo e me devolver que é o primeiro contato da lista. &lt;/p&gt;

&lt;p&gt;Ex 2: Eu querer o nome Zakarias, o último contato.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;E é ai (Ex 2) que as coisas complicam...&lt;/p&gt;

&lt;p&gt;Na Pesquisa Simples, meu algoritmo vai ir la, de um em um, até o fim da lista para poder me falar, que Zakarias ta lá na última posição, levando mais tempo. &lt;/p&gt;

&lt;p&gt;Já na Pesquisa Binária, começando pelo meio, &lt;strong&gt;se o nosso chute  não for a resposta, é só verificar se ta mais para cima ou para baixo, eliminar a outra metade e partir do meio novamente&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ex: Eu ainda quero o contato de Zakarias (100). Se começarmos do contato 50, vemos que o 100 ta mais pra cima. Então agora, eu busco entre 50 e 100, e minha nova metade é 75. E assim sucessivamente até que o resultado seja exibido.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Então, enquanto na Pesquisa Simples, foi preciso 99 etapas. Na Pesquisa Binária, foi preciso somente 7. Uma baita diferença né?!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Obs: O número de etapas de uma Pesquisa Simples é igual ao tamanho da lista (n). Enquanto o número de etapas de uma Pesquisa Binária é log2(n).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Como implementar um algoritmo de Pesquisa Binária?
&lt;/h4&gt;

&lt;p&gt;O exemplo abaixo foi originalmente implementado no livro. A única coisa alterada é a sintaxe, pois abaixo está em #Dart.&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%2Ftbh6xrui69bopu4prqic.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%2Ftbh6xrui69bopu4prqic.png" alt="Image description" width="634" height="868"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>beginners</category>
      <category>learning</category>
      <category>dart</category>
    </item>
    <item>
      <title>Best practices for refactoring legacy code to make it more maintainable and easier to work with</title>
      <dc:creator>Lucca Mabel</dc:creator>
      <pubDate>Wed, 12 Apr 2023 20:14:57 +0000</pubDate>
      <link>https://dev.to/eusoumabel/best-practices-for-refactoring-legacy-code-to-make-it-more-maintainable-and-easier-to-work-with-5cem</link>
      <guid>https://dev.to/eusoumabel/best-practices-for-refactoring-legacy-code-to-make-it-more-maintainable-and-easier-to-work-with-5cem</guid>
      <description>&lt;p&gt;It is quite common for us developers, especially those newer to the field, to have an idea that when entering a new company, a new project, they will come across clean, well-organized, well-structured, and easy-to-navigate and maintain code (or maybe just me in my naivety haha).&lt;/p&gt;

&lt;p&gt;With the emphasis on using the best practices in the tech market, every agile development process adopted by many companies, numerous materials on how to write quality code available, it is common to think that the scenario of the previous paragraph is the reality. However, it's not. It's much more common to find a scenario of outaded code, with outdated dependencies, outdated stack, difficult-to-read code, and confusing architecture (maybe not so chaotic haha but you get it...).&lt;/p&gt;

&lt;p&gt;So, considering all this, what to do in the face of this chaos? How to work with legacy code? How to know where to modify? How to know if the system won't break?&lt;/p&gt;

&lt;p&gt;These are great questions, and I hope to address them well in this article by bringing points from my personal experiences and lessons learned from the book &lt;a href="https://www.amazon.com.br/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052/ref=asc_df_0131177052/?tag=googleshopp00-20&amp;amp;linkCode=df0&amp;amp;hvadid=379787788238&amp;amp;hvpos=&amp;amp;hvnetw=g&amp;amp;hvrand=11675990182565464509&amp;amp;hvpone=&amp;amp;hvptwo=&amp;amp;hvqmt=&amp;amp;hvdev=c&amp;amp;hvdvcmdl=&amp;amp;hvlocint=&amp;amp;hvlocphy=1001533&amp;amp;hvtargid=pla-452008857537&amp;amp;psc=1" rel="noopener noreferrer"&gt;Working Effectively With Legacy Code&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is 'Legacy Code'?
&lt;/h2&gt;

&lt;p&gt;Let's start by identifying our problem, understanding what legacy code is, and some reasons why it is generated.&lt;/p&gt;

&lt;p&gt;We can think of legacy code as messy, unreadable, difficult to make changes to, and hard to find code. But this type of code takes time to become what we call legacy, right?&lt;/p&gt;

&lt;p&gt;It starts off beautiful, clean, and harmonious, until someone, for example, starts implementing duplicated methods in several classes, uses abstract names for variables, implements giant methods that do many things, forgets to implement a test, doesn't perform periodic refactorings, and submits a pull request for all of this, which is approved without scrutiny for reasons X, Y, or Z. Afterwards, the person who implemented all of this leaves the team or changes projects/companies and didn't leave any documentation behind.&lt;/p&gt;

&lt;p&gt;However, despite all of this being true, the book "Working Effectively With Legacy Code" brings a perspective that legacy code is basically code without &lt;u&gt;tests&lt;/u&gt;. So, no. It doesn't take a lot of time to call any code legacy, you can write legacy code right now.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;But why are &lt;u&gt;tests&lt;/u&gt; so important in a software? &lt;a href="https://blog.betrybe.com/tecnologia/testes-unitarios/" rel="noopener noreferrer"&gt;The importance of implementing unit tests&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I think now the path we are following is a little clearer... so let's go.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why refactor?
&lt;/h2&gt;

&lt;p&gt;To understand the importance of refactoring, it's also important to understand the importance and cost of code rewriting.&lt;/p&gt;

&lt;p&gt;I understand the problems that arise from working with legacy code. It's not a productive flow, it's not easy to find anything, you never know if you changes one thing it will break the entire system, requirements are confusing to understand, and often support is limited.&lt;/p&gt;

&lt;p&gt;So, for these reasons, I know we think it will be easier to simply rewrite the entire system to make it clean and harmonious again. However, it's often more costly and something the company isn't willing to do at the moment. Therefore, it's important to know when to rewrite and when to refactor.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/" rel="noopener noreferrer"&gt;Things you should never do, Part I&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Getting straight to the point...
&lt;/h3&gt;

&lt;p&gt;So, why refactor?&lt;/p&gt;

&lt;p&gt;It will take less time, and therefore, less cost. The idea in this scenario is not an extensive refactoring, it's more like "adjusting as you go".&lt;/p&gt;

&lt;p&gt;If you're going to implement something in a method, it already helps a lot to take extra time to refactor the method you're working on and make the necessary adjustments. But, it doesn't mean you need to allocate more time to refactor the whole class, for example. Do you understand what I mean?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nevertheless, it's important to have refactoring as a constant practice and do it whenever possible.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  When to refactor?
&lt;/h2&gt;

&lt;p&gt;Before starting the refactoring process, it's important to have in mind the current behavior and the expected behavior of the feature that you're going to implement/modify.&lt;/p&gt;

&lt;p&gt;This can be easily verified with &lt;u&gt;tests&lt;/u&gt;. But sometimes they don't exist within the system we're working on. Therefore, in order to evaluate the risks we will face when performing the refactoring process, it's important to have very clear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The changes that will be made&lt;/li&gt;
&lt;li&gt;  How it will be verified that they were made correctly&lt;/li&gt;
&lt;li&gt;  How it will be verified that, by making the changes, nothing will break&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After evaluating these cases, it's noticeable that refactoring is not always simple, and that's why many people say "if it's working, don't touch it."&lt;/p&gt;

&lt;p&gt;But, as tempting as it may be to avoid everything, software problems will only increase over time and come back worse. And without practice, it becomes increasingly difficult to make necessary changes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://dev.to/estermabel/evolucao-de-software-e-a-importancia-da-refatoracao-198h"&gt;Software Evolution and the Importance of Refactoring&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  How to refactor?
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://www.amazon.com.br/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052/ref=asc_df_0131177052/?tag=googleshopp00-20&amp;amp;linkCode=df0&amp;amp;hvadid=379787788238&amp;amp;hvpos=&amp;amp;hvnetw=g&amp;amp;hvrand=11675990182565464509&amp;amp;hvpone=&amp;amp;hvptwo=&amp;amp;hvqmt=&amp;amp;hvdev=c&amp;amp;hvdvcmdl=&amp;amp;hvlocint=&amp;amp;hvlocphy=1001533&amp;amp;hvtargid=pla-452008857537&amp;amp;psc=1" rel="noopener noreferrer"&gt;book&lt;/a&gt; presents two approaches to making changes in the system: Edit and Pray and Cover and Modify.&lt;/p&gt;

&lt;h3&gt;
  
  
  Edit and Pray
&lt;/h3&gt;

&lt;p&gt;This practice is the most common. You try to understand the code that will be changed, are careful with the modifications, make them, and when finished, run the system to verify if what was modified is visible and try a bit more to check if nothing broke.&lt;/p&gt;

&lt;p&gt;It's modifying with hope and faith that everything will work out and using extra time to confirm that everything really did work out.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cover and Modify
&lt;/h3&gt;

&lt;p&gt;On the other hand, this practice brings more security when making modifications. The idea is to have confidence in the changes and to know for sure that nothing will break.&lt;/p&gt;

&lt;p&gt;For this, it is important to check if what you are looking to modify is covered by tests, so that it is possible to guarantee that the modification works as expected and does not have any other effect. With tests, it is much easier to make changes carefully and assertively.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to test?
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://www.amazon.com.br/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052/ref=asc_df_0131177052/?tag=googleshopp00-20&amp;amp;linkCode=df0&amp;amp;hvadid=379787788238&amp;amp;hvpos=&amp;amp;hvnetw=g&amp;amp;hvrand=11675990182565464509&amp;amp;hvpone=&amp;amp;hvptwo=&amp;amp;hvqmt=&amp;amp;hvdev=c&amp;amp;hvdvcmdl=&amp;amp;hvlocint=&amp;amp;hvlocphy=1001533&amp;amp;hvtargid=pla-452008857537&amp;amp;psc=1" rel="noopener noreferrer"&gt;book&lt;/a&gt; presents The Legacy Code Change Algorithm, which provides a structure for making functional changes that add value through testing.&lt;/p&gt;

&lt;h4&gt;
  
  
  Identify the points of change
&lt;/h4&gt;

&lt;p&gt;Locate the areas where you need to implement changes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Find the test points
&lt;/h4&gt;

&lt;p&gt;Identify where you need to implement tests for the changes you will make.&lt;/p&gt;

&lt;h4&gt;
  
  
  Separate dependencies
&lt;/h4&gt;

&lt;p&gt;Perhaps this part is where you will encounter the most difficulty. There are some techniques to perform this separation, but I won't go into it at the moment. However, I believe that &lt;a href="https://www.frederikbanke.com/breaking-dependencies/" rel="noopener noreferrer"&gt;this material&lt;/a&gt; can provide a good starting point.&lt;/p&gt;

&lt;h4&gt;
  
  
  Write tests
&lt;/h4&gt;

&lt;p&gt;Separate the test cases and write them to cover as many scenarios as possible.&lt;/p&gt;

&lt;h4&gt;
  
  
  Make modifications and refactor
&lt;/h4&gt;

&lt;p&gt;The &lt;a href="https://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052" rel="noopener noreferrer"&gt;book&lt;/a&gt; recommends using TDD for making changes in legacy code. It is a way of validating your code as you go along with the implementation. A good recommendation on how to start this practice is &lt;a href="https://marciofrayze.medium.com/como-consegui-come%C3%A7ar-a-praticar-tdd-df4aa74d6d9a" rel="noopener noreferrer"&gt;How I managed to start practicing TDD&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;In summary, legacy code is a combination of situations that happen in a developer's daily life, but it's basically code without tests.&lt;/p&gt;

&lt;p&gt;In this scenario, it is important to know when to refactor and when to rewrite code. And when refactoring, be aware of the current state of the functionality and the expected state, as well as prepare for verification scenarios to ensure that the changes were made correctly.&lt;/p&gt;

&lt;p&gt;It's also important to know when to perform refactorings; they do not need to be extensive, but they need to be constant. When left aside, the problems arising from it will only increase over time, and you will lose the practice of solving them.&lt;/p&gt;

&lt;p&gt;Additionally, it is important to verify if the code you want to modify has test coverage before starting a refactoring process. Only in this way, it's possible to ensure that nothing beyond the expected will be changed, and the system will work as expected.&lt;/p&gt;

&lt;p&gt;If there isn't test coverage in the system or the piece of code you want to modify, it's possible to implement them by following The Legacy Code Change Algorithm.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052" rel="noopener noreferrer"&gt;Working Effectively With Legacy Code&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.frederikbanke.com/book-review-working-effectively-with-legacy-code/" rel="noopener noreferrer"&gt;Working Effectively With Legacy Code - Book Review&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882" rel="noopener noreferrer"&gt;Clean Code: A Handbook of Agile Software Craftsmanship&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/estermabel/evolucao-de-software-e-a-importancia-da-refatoracao-198h"&gt;Software Evolution and the Importance of Refactoring&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/" rel="noopener noreferrer"&gt;Things you should never do, Part I&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.frederikbanke.com/breaking-dependencies/" rel="noopener noreferrer"&gt;Breaking Dependencies&lt;/a&gt;&lt;br&gt;
&lt;a href="https://marciofrayze.medium.com/como-consegui-come%C3%A7ar-a-praticar-tdd-df4aa74d6d9a" rel="noopener noreferrer"&gt;How I managed to start practicing TDD&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cleancode</category>
      <category>refactoring</category>
      <category>productivity</category>
      <category>testing</category>
    </item>
    <item>
      <title>Evolução de Software e a Importância da Refatoração</title>
      <dc:creator>Lucca Mabel</dc:creator>
      <pubDate>Mon, 26 Dec 2022 19:33:53 +0000</pubDate>
      <link>https://dev.to/eusoumabel/evolucao-de-software-e-a-importancia-da-refatoracao-198h</link>
      <guid>https://dev.to/eusoumabel/evolucao-de-software-e-a-importancia-da-refatoracao-198h</guid>
      <description>&lt;h1&gt;
  
  
  Evolução de Software
&lt;/h1&gt;

&lt;h2&gt;
  
  
  O que é Evolução de Software?
&lt;/h2&gt;

&lt;p&gt;Evolução de Software é o processo de desenvolvimento, modificações  e atualizações que o software sofre ao longo do tempo.&lt;/p&gt;

&lt;h2&gt;
  
  
  A importância da Evolução de Software
&lt;/h2&gt;

&lt;p&gt;Com o passar do tempo, a complexidade de um software aumenta e junto com ela, o seu tamanho também. Ou seja, mais código para realizar manutenção e maior dificuldade de encontrar e solucionar bugs.&lt;/p&gt;

&lt;p&gt;O envelhecimento de um software é inevitável, portanto é preciso que os conceitos da evolução de software estejam presentes em seu processo de desenvolvimento.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como prevenir futuros problemas?
&lt;/h2&gt;

&lt;p&gt;Algumas maneiras de prevenir os problemas que o tempo de vida de um software pode trazer são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Transparência&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Manter todas as partes envolvidas no software cientes do escopo, propósito e regras de negócio do sistema em desenvolvimento. Inclusive de possíveis modificações ao passar do tempo.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Realizar abstrações&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Sempre que possível, realizar abstrações para agilizar o desenvolvimento e diminuir repetição de código&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Modularização&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Dividir o sistema em módulos para facilitar a manutenção ao longo do tempo. Além de facilitar detecção de erros, realização de testes e permitir o desenvolvimento independente dos módulos&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Amputação&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Em casos extremos, quando algo está apresentando muitos problemas e não é possível resolver, talvez seja melhor analisar a possibilidade de remover a feature por completo&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Manutenção x Desenvolvimento
&lt;/h2&gt;

&lt;p&gt;A partir disso, é importante abrir espaço entre, ou durante, as etapas de desenvolvimento para realizar manutenção do software para que, no futuro, não ocorram problemas decorrentes disso.&lt;/p&gt;

&lt;p&gt;Para realizar as devidas manutenções, é preciso passar por algumas etapas para entender o propósito das mesmas.&lt;/p&gt;

&lt;p&gt;É preciso, primeiramente, de um conhecimento profundo da estrutura do sistema, ou da funcionalidade em questão, isso podemos adquirir a partir de documentações muito bem escritas ou designando esta tarefa para a pessoa que mais teve contato com a funcionalidade.&lt;/p&gt;

&lt;p&gt;Também é bastante importante entender e levantar o impacto que mexer nessa funcionalidade pode causar. Por isso reforço a importância da documentação, que é possível evitar novos erros a partir do histórico de problemas antigos.&lt;/p&gt;

&lt;p&gt;Em sequência, é necessário realizar as estimativas de custo ou de tempo que essa manutenção pode causar para que ela seja devidamente incluída dentro da sprint e, por fim, documentar todas as mudanças realizadas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problemas que a falta de manutenção pode causar:
&lt;/h3&gt;

&lt;p&gt;É importante destacarmos que a manutenção é extremamente importante para garantir a Manutenibilidade do software, que é a facilidade com que é possivel modificar o sistema.&lt;/p&gt;

&lt;p&gt;Quando não há manutenção, ou há manutenção ruim, pode coasionar em perda de tempo para desenvolver novas funcionalidades, um cliente insatisfeito, redução na qualidade do produto e até mesmo insatisfação do próprio time de desenvolvimento pois irá gerar dificuldade para corrigir o problema futuramente e novamente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Coisas que podem afetar a manutenibilidade do sistema:
&lt;/h3&gt;

&lt;p&gt;Por si só a evolução do software é dificil de se manter por muitos anos e isso deve ser levado em consideração. São muitos processos, classes, linhas de código e a complexidade aumenta com o passar do tempo. Isso impacta diretamente na manutenilibidade. Por isso é fundamental estabelecer padrões referentes a linguagem de programação, realizar testes e versionar o código.&lt;/p&gt;

&lt;p&gt;Assim como, é dificil documentar todas as alterações e processos de forma que todos os desenvolvedores estejam 100% cientes de tudo. &lt;/p&gt;

&lt;p&gt;E por fim, a visão que algumas pessoas tem de que manutenção é sinônimo de um trabalho ruim. O que não é verdade! Código cresce com o passar do tempo, a complexidade aumenta e a manutenção é fundamental para que o software continue vivo e funcionando da maneira esperada. É preciso haver, ou criar, espaço para aprimorar a manutenibilidade.&lt;/p&gt;

&lt;h1&gt;
  
  
  Refatoração
&lt;/h1&gt;

&lt;p&gt;Dentro da engenharia de software, temos muitas formas de realizar a manutenção do código. Diversos conceitos, ferramentas e metodologias, contudo, hoje vamos focar na Refatoração.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é refatoração?
&lt;/h2&gt;

&lt;p&gt;Refatoração é o processo de alterar um sistema afim que seu comportamento não seja modificado, mas sua estrutura interna seja melhorada. O objetivo por trás disso é reduzir a complexidade e tornar o software mais compreensível, basicamente é melhorar a qualidade do software.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quando podemos refatorar?
&lt;/h2&gt;

&lt;p&gt;Alguns momentos ideiais para realizar a refatoração de um código, são quando:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Houver tempo entre as etapas de desenvolvimento&lt;/li&gt;
&lt;li&gt;Durante a etapa de Code Review (seja ao enviar o MR ou na revisão que fazemos enquanto desenvolvemos)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quando não refatorar?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Quando está muito perto do prazo final de entrega&lt;/li&gt;
&lt;li&gt;Quando o código tá muito confuso (neste caso é recomendado a reescrita total)&lt;/li&gt;
&lt;li&gt;Quando o código apresenta muitos bugs&lt;/li&gt;
&lt;li&gt;Depois&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  O “Consertar Depois”
&lt;/h3&gt;

&lt;p&gt;Sempre que possível, refatore e aprimore o código no momento que você identificar algum indicativo que é preciso. Pois, muito provavelmente, se você deixar para depois, as chances de retomar para refatorar são menores.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Poque não deixar para “depois”?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Perda de contexto e confiaça&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Quanto mais você estiver removido do ponto em que o código foi escrito, menos você o entende. E se você não consegue lembrar todos os casos de uso, não tem mais a mesma confiança em alterar por medo de quebrar a funcionalidade. Portanto o risco de quebrar não  "vale” o benefício da melhoria.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Normalização&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Quanto mais você convive com algo, mais acostumado você está com isso e cada vez menos é uma prioridade.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Maior Prioridade&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sempre há uma coisa nova que queremos construir ou melhorar. Eventualmente, o que antes era um problema, acaba virando o normal e outra coisa ganha prioridade.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Agora você está confiando naquele código&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mesmo sabendo que o código é ruim, ainda sim é preciso implementar coisas novas. Isso acaba criando um ciclo onde tudo que vem de novo, acaba ficando dependente daquele código ruim e acaba ficando mais dificil de realizar manutenção.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Como identificar se o código precisa de refatoração?
&lt;/h2&gt;

&lt;p&gt;Uma forma de identificar se um código precisa de refatoração a partir da presença de “Bad Smells”.&lt;/p&gt;

&lt;h3&gt;
  
  
  O que é Bad Smell?
&lt;/h3&gt;

&lt;p&gt;Bad Smell é basicamente algumas más práticas de desenvolvimento que podem ser aprimorados com refatoração.&lt;/p&gt;

&lt;h3&gt;
  
  
  Classe Deus
&lt;/h3&gt;

&lt;p&gt;A classe Deus é uma classe que realiza muitas coisas dentro do sistema. Ela pode ter muitos atributos, muitas funções e muitas responsabilidades.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Como resolver?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dividir em classes menores&lt;/li&gt;
&lt;li&gt;Criar subclasses que se relacionem melhor com a classe principal&lt;/li&gt;
&lt;li&gt;Verificar se os atributos e métodos são todos necesários&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Método Deus
&lt;/h3&gt;

&lt;p&gt;São métodos extensos que centralizam toda funcionalidade de uma classe. Altamente dificeis de manter e de entender.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Como resolver?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dividir o método em outros menores&lt;/li&gt;
&lt;li&gt;Verificar a possibilidade de transformá-lo em uma classe&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Funcionalidade Invejosa
&lt;/h3&gt;

&lt;p&gt;Parte de uma classe que só utiliza atributos e métodos de outra classe específica.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Como resolver?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verificar a possibilidade de mover os atributos e métodos em questão entre as classes&lt;/li&gt;
&lt;li&gt;Verificar se vale a pena juntar as classes em uma, ou utilizar conceitos de sub-classes para dividir melhor as responsabilidades&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Comentários
&lt;/h3&gt;

&lt;p&gt;Comentários não é necessariamente algo ruim. Eles podem ser utilizados para auxiliar na compreensão do código, contudo, se for em excesso pode atrapalhar a legibilidade do mesmo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Como resolver?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Remover comentários desnecessários&lt;/li&gt;
&lt;li&gt;Simplifique o código (Se algo está muito complexo à nível de necessitar de um texto para compreender, a melhor abordagem é simplificar o código ao invés de escrever um texto explicando o mesmo)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Mudanças Divergentes
&lt;/h3&gt;

&lt;p&gt;Quando uma classe muda frequentemente de forma com razões distintas.&lt;/p&gt;

&lt;p&gt;Por exemplo: Uma classe que originalmente estava responsável por controlar a página de login, foi alterada e agora o novo escopo dela é controlar a página de cadastro, e foi alterada novamente e agora ela é responsável por controlar o fluxo de onBoarding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Como resolver?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dividir a classe: Cada mudança de escopo deve ficar em uma classe separada&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Shotgun Surgery
&lt;/h3&gt;

&lt;p&gt;Quando ao alterar uma classe, é necessário alterar várias outras.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Como resolver?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reorganizar as responsabilidades e divisões das classes afetadas e verificar a possibilidade de junção de classes ou mover os métodos e atributos para se enquadrar melhor ao escopo&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Classe Reclusa
&lt;/h3&gt;

&lt;p&gt;Uma classe que herda atributos e métodos de outra classe, mas não utiliza para nada.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Como resolver?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reformular a hierarquia das classes em questão&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Lista de Parâmetro muito Grande
&lt;/h3&gt;

&lt;p&gt;Uma classe com parâmetros em abundância.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Como resolver?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verificar a possibilidade de remodelar o algoritmo a fim de que não seja preciso parametros em excesso para que a feature funcione de maneira apropriada&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Anti-Patterns
&lt;/h3&gt;

&lt;p&gt;Algumas más práticas que vão de encontro à boas práticas de desenvolvimento.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Blind Faith&lt;/strong&gt;: Não checar a correção de um bug&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Boat Anchor&lt;/strong&gt;: Parte do sistema sem uso&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lava Flow&lt;/strong&gt;: Código ruim colocado em constante mudança sem ser refatorado&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gold Hammer&lt;/strong&gt;: Tecnologia familiar aplicada em todos os problemas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cult Programming&lt;/strong&gt;: Utilizar padrões sem saber o motivo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lasagna Code&lt;/strong&gt;: Código com muitas camadas desnecessárias&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spaghetti Code&lt;/strong&gt;: Estruturas de código pouco compreensíveis&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Como planejar a manutenção?
&lt;/h2&gt;

&lt;p&gt;Uma sugestão para melhor planejar a manutenção do software é, além de aplicar os conceitos mencionados atenriormente quando necessário, também alinhar um período de manutenção dentro da sprint.&lt;/p&gt;

&lt;p&gt;Uma sugestão seria a equipe não passar imediatamente para a próxima feature, mas sim ter um tempo de melhoria para que o que for entregue, tenha menos chances de apresentar problemas e aumente a manutenibilidade do software.&lt;/p&gt;

&lt;p&gt;É claro, que não é preciso alocar esse tempo entre cada sprint. Mas é importante ter essa possibilidade analisada e manter uma certa periodicidade para as necessidades referentes à manutenção do sistema.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como aumentar a periodicidade da necessidade de manutenção?
&lt;/h2&gt;

&lt;p&gt;Algumas formas de aumentar a periodicidade é basicamente tentar se manter fiel aos conceitos de código limpo, planejar bem, entender o problema que você quer resolver e testar bem a solução implementada.&lt;/p&gt;

&lt;h3&gt;
  
  
  Definir Metas Claras
&lt;/h3&gt;

&lt;p&gt;Tenha em mente, de forma clara e visível, as metas que o código quer resolver. Isso é fundamental em situações onde é preciso decidir como adicionar uma feature nova ou se deve ser aceita uma mudança de escopo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Defina as Restrições
&lt;/h3&gt;

&lt;p&gt;Também tenha em mente quais problemas seu código não resolve. Restringir o escopo é importante e é uma forma de te forçar a focar exclusivamente no problema.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dizer Não
&lt;/h3&gt;

&lt;p&gt;Sempre vai ter algo novo e importante para ser implementado. A importância de dizer não, quando couber, garante que o software não cresça de forma descontrolada. &lt;/p&gt;

&lt;h3&gt;
  
  
  Elimine Resíduos
&lt;/h3&gt;

&lt;p&gt;Sempre que possível, remova quaisquer recursos não utilizados e código morto.&lt;/p&gt;

&lt;h3&gt;
  
  
  Minimize Dependências
&lt;/h3&gt;

&lt;p&gt;Ser exigente ao adicionar dependências, considerar prós e contras. Pois dependências podem quebrar, desaparecer, se tornar um risco de segurança. Se a funcionalidade for crucial para o produto, vale a pena avaliar se não é melhor implementar você mesmo.&lt;/p&gt;

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

&lt;p&gt;Para resumir, evolução de software é algo que tem que ser olhado com atenção para que o sistema tenha possibilidade de crescer junto com o tempo. Para isso, é importante garantir a manutenibilidade do sistema com manutenção periódica, que deve ser planejada e não ser feita somente quando a situação ta critica.&lt;/p&gt;

&lt;p&gt;Uma forma de fazer a manutenção é através da refatoração, que melhora o código internamente, sem afetar a funcionalidade para o usuário final. Para identificar se há necessidade de refatoração, é importante se atentar à presença de “Bad Smells”.&lt;/p&gt;

&lt;p&gt;E para aumentar o período em que uma manutenção deve ser feita, é preciso se manter fiel aos conceitos de código limpo, planejar bem, entender o problema que você quer resolver e testar bem a solução implementada.&lt;/p&gt;

&lt;h1&gt;
  
  
  Referências
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://uselessdevblog.wordpress.com/2022/11/10/stop-lying-to-yourself-you-will-never-fix-it-later/" rel="noopener noreferrer"&gt;Stop lying to yourself – you will never “fix it later”&lt;/a&gt;&lt;br&gt;
&lt;a href="https://verygood.ventures/blog/scalable-best-practices" rel="noopener noreferrer"&gt;Best practices for building scalable Flutter applications&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.danielsieger.com/blog/2022/07/25/your-code-doesnt-have-to-be-a-mess.html" rel="noopener noreferrer"&gt;Your Code Doesn't Have to Be a Mess&lt;/a&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Lean_software_development" rel="noopener noreferrer"&gt;Lean software development&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.danielsieger.com/blog/2022/03/30/kiss-over-time.html" rel="noopener noreferrer"&gt;Keep it Simple, Over Time&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gratitude</category>
    </item>
    <item>
      <title>Mudanças que podem ser feitas para tornar aplicativos de celular um ambiente seguro para pessoas LGBTQ+</title>
      <dc:creator>Lucca Mabel</dc:creator>
      <pubDate>Wed, 23 Feb 2022 02:47:01 +0000</pubDate>
      <link>https://dev.to/eusoumabel/mudancas-que-podem-ser-feitas-para-tornar-aplicativos-de-celular-um-ambiente-seguro-para-pessoas-lgbtq-4530</link>
      <guid>https://dev.to/eusoumabel/mudancas-que-podem-ser-feitas-para-tornar-aplicativos-de-celular-um-ambiente-seguro-para-pessoas-lgbtq-4530</guid>
      <description>&lt;p&gt;Há um tempo, eu estava em busca de algumas aplicações que são inclusivas para com a comunidade LGBTQ+, no entanto, depois de muita busca, eu obtive muito poucos resultados. Como membro da comunidade, isso me deixou muito triste e como desenvolvedora, abriu um espaço para que eu falasse sobre isso e talvez mobilizar alguém a acatar mudanças para que suas futuras aplicações sejam mais inclusivas e tenham em vista o conforto e segurança do usuário.&lt;br&gt;
Portanto, dentro de experiência pessoais e pesquisas sobre o assunto, vamos falar um pouco sobre algumas mudanças que podem ser feitas para garantir essa inclusividade.&lt;/p&gt;

&lt;h2&gt;
  
  
  Diversidade de gênero
&lt;/h2&gt;

&lt;p&gt;Uma situação que eu vejo com frequência é a pouca diversidade de gênero quando o usuário está fazendo o cadastro e o gênero é requerido para finalizar, ou até mesmo, nenhum campo de gênero (como por exemplo, substituí-lo por um campo de sexo biológico). Se um campo de gênero é realmente necessário para o cadastro do usuário na sua aplicação, então é importante que o usuário se sinta representado pela disponibilidade de gêneros que a aplicação está fornecendo.&lt;/p&gt;

&lt;p&gt;Foram pouquíssimas aplicações que eu utilizei em que era disponibilizado mais que 2 gêneros (Homem, Mulher), menos ainda que eu vi que era disponibilizado mais de 3 alternativas (Homem, Mulher, Prefiro não dizer/Outro). E ai, encontramos 2 problemas: o primeiro é a pouca diversidade de gêneros, que estamos discutindo agora. O segundo é sobre a alternativa “prefiro não dizer”. Não vou generalizar em dizer que todes querem expor o gênero que se identificam, mas muita gente quer e muita gente não tem a oportunidade. Em complemento, quanto a opção de “Outro”, é possível ver que tem um espaço para a pessoa colocar como ela se identifica, no entanto, a minha experiência pessoal é que, ainda que essa alternativa esteja lá, eu não me sinto representada.&lt;/p&gt;

&lt;p&gt;É importante fazer com que o usuário se sinta contemplado, seguro e confortável. Isso melhora a experiência que ele vai ter durante o uso da aplicação, pois a aplicação foi feita pensando nele, também.&lt;/p&gt;

&lt;p&gt;Atualmente, a Comissão dos Direitos Humanos reconhece 31 diferentes tipos de gênero. Portanto, não assuma o gênero do seu usuário, é muito provável que você vai errar. Ao invés disso, disponibilize uma quantidade maior de gêneros para o seu usuário, deixe que ele se auto-declare como ele se sentir melhor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pronomes
&lt;/h2&gt;

&lt;p&gt;Se a diversidade de gênero é pouco explorada, a utilização de pronomes diversos muito mais. Assim como você não deve assumir o gênero do seu usuário, também não deve assumir os pronomes dele.&lt;/p&gt;

&lt;p&gt;Nem sempre pronomes estão presentes dentro de uma aplicação, mas sempre que são, a linguagem é voltada para o masculino (predominantemente) ou feminino, poucas foram as vezes que eu presenciei o uso de linguagem neutra dentro de alguma aplicação, muito menos foram às vezes em que eu presenciei o uso correto da linguagem neutra, acredito que é possível que eu nunca tinha visto na verdade.&lt;/p&gt;

&lt;p&gt;Portanto, se sua aplicação possuir diálogos com o usuário ou fizer uso de pronomes em seus textos, o ideal é deixar o usuário escolher o pronome em que quer ser tratado e adaptar os diálogos e textos, de forma correta, para que o usuário se sinta respeitado, confortável e tenha uma boa experiência de uso.&lt;/p&gt;

&lt;h2&gt;
  
  
  Diversidade de Orientações Sexuais
&lt;/h2&gt;

&lt;p&gt;Assim como os tópicos anteriores, a pouca diversidade de orientações sexuais dentro das aplicações é muito presente. Apesar de que poucas aplicações fazem o requerimento desse dado, as poucas que fazem, possuem uma limitação enorme de alternativas para seus usuários. A maioria das vezes, dentro de onde eu tive acesso, as alternativas variam entre Heterossexual ou Homossexual e Heterossexual, Gay ou Lésbica e isso deixa uma lacuna enorme para as pessoas que se identificam com uma sexualidade diferente dessas.&lt;/p&gt;

&lt;p&gt;A comunidade possui tanta diversidade que a sigla possui uma sigla. Limitando alternativas de sexualidade, gênero e pronome vai somente causar desconforto para os usuários fora das alternativas presentes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Diversidade de Formação de Família
&lt;/h2&gt;

&lt;p&gt;Em aplicativos que solicitam informações sobre os pais do usuário, é importante levar em consideração que existem diversas formas de se construir uma família. Colocar um campo com o label “Mãe” e outro com o label “Pai”, está longe de se adequar as diversas famílias atuais.&lt;/p&gt;

&lt;p&gt;As famílias podem ser constituídas por duas pessoas de mesmo gênero, de gêneros diferentes, com somente 1 responsável legal, com mais de 2 responsáveis legais. Portanto, modificar a forma que esses dados são capturados é essencial.&lt;/p&gt;

&lt;h2&gt;
  
  
  Desenvolva apps voltado para comunidade
&lt;/h2&gt;

&lt;p&gt;Mesmo que não seja membro da comunidade, com certeza você possui alguma pessoa a sua volta que é. A falta de conteúdo e tecnologia voltada para comunidade LGBTQ+ é enorme. Apesar de avanços significativos que aconteceram nos últimos tempos, ainda é importante que os avanços continuem vindo e mais conteúdo e tecnologia seja produzido. Seja para informar, alertar, entreter, protejer, fazer uma diferença.&lt;/p&gt;

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

&lt;p&gt;Para tornar seu aplicativo um ambiente seguro para pessoas LGBTQ+, é preciso considerar essas pessoas durante o processo de desenvolvimento. É preciso analisar os casos e respeitar eles para promover segurança, acolhimento, representatividade e individualidade para elas.&lt;/p&gt;

</description>
      <category>lgbtq</category>
      <category>mobile</category>
      <category>app</category>
    </item>
    <item>
      <title>8 projetos iniciantes para aprender Flutter e expandir seu portfólio</title>
      <dc:creator>Lucca Mabel</dc:creator>
      <pubDate>Wed, 23 Feb 2022 02:45:10 +0000</pubDate>
      <link>https://dev.to/eusoumabel/8-projetos-iniciantes-para-aprender-flutter-e-expandir-seu-portfolio-55cm</link>
      <guid>https://dev.to/eusoumabel/8-projetos-iniciantes-para-aprender-flutter-e-expandir-seu-portfolio-55cm</guid>
      <description>&lt;p&gt;Flutter é um framework open source de desenvolvimento criado pelo Google, que possibilita a criação de aplicativos para múltiplas plataformas com um único código. Por conta de sua possibilidade multi-plataforma, acessibilidade e facilidade de aprendizado, Flutter tem se tornado bastante popular no mundo do desenvolvimento. Tendo isso, e a diminuição de custo, em vista, muitas empresas estão buscando iniciar projetos em Flutter ou migrar os já existentes. Pensando na grande comunidade crescente do Flutter, esse artigo foi feito com a ideia de trazer 8 apps de nível introdutório/iniciante para começar sua jornada com o framework.&lt;/p&gt;

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

&lt;p&gt;Um app de calculadora básico é o projeto perfeito para iniciar sua jornada com Flutter. O app em si, não precisa ter layouts ou widgets complexos (a menos que queira), basta somente um display para mostrar o caminho e resultado das operações, botões para os números e para os tipos de operação.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Login UI
&lt;/h2&gt;

&lt;p&gt;Seguindo a linha de uma jornada de aprendizagem introdutória, uma tela de Login é fundamental. É o tipo de feature que é necessária na maioria dos projetos Flutter, portanto, é fundamental tê-la em seu currículo. Além de que, não é uma feature complexa de ser realizada.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Pedra, Papel e Tesoura
&lt;/h2&gt;

&lt;p&gt;Um joguinho de pedra, papel e tesoura pode ser um app de treinamento perfeito para começar a aprofundar suas habilidades de lógica em Dart. Além de ser um diferencial para seu portfólio, pode ser o inicio para aplicações com conceitos um pouco mais complexos.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Jogo da velha
&lt;/h2&gt;

&lt;p&gt;O app do jogo da velha é um clássico para quem está aprendendo quase qualquer linguagem de programação/framework do zero. Isso porque: ele cumpre bem seu papel. O jogo da velha possibilita aprofundar mais na parte lógica da aplicação, fazer uso de widgets mais complexos e modificar o estado e layout das telas com mais propriedade.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Pomodoro Timer
&lt;/h2&gt;

&lt;p&gt;A ideia do pomodoro timer é fortalecer o uso de lógica e inicializar a utilização de widgets mais complexos e pacotes. Se você não conhece um pomodoro timer, ele funciona assim (de forma padrão): O usuário define uma quantidade de ciclos em que o timer vai rodar, um ciclo é composto por: período de trabalho (25 minutos) e período de descanso (5 minutos), começando pelo período de trabalho. Assim que um ciclo acaba, outro, automaticamente, começa. Isso perdura até que todos os ciclos tenham sido realizados.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. ToDo List
&lt;/h2&gt;

&lt;p&gt;Um app de ToDo List é clássico na vida de todo desenvolvedor mobile (ou pelo menos de muitos rsrs) com ele é possível agregar outros conceitos da programação para dentro da estrutura do seu app, por exemplo: arquitetar seu app de forma orientada à objetos (OO), que é um conceito essencial para se trabalhar com desenvolvimento de software. Além de poder agregar mais complexidade e domínio ao seu código, podendo fazer uso de um banco local, construtores de lista, construtores de grid e gerenciadores de estado.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Clone de Algum App Existente
&lt;/h2&gt;

&lt;p&gt;Talvez um dos projetos introdutórios mais comuns que eu observo são clones de outros apps. E é super válido! Dessa forma é possível explorar conceitos de UI que talvez não tenham sido explorados em projetos prévios e fortalecer os que você já tem, além possibilidade de entrar em contato com arquiteturas e fluxos de lógica diferentes.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Portfólio
&lt;/h2&gt;

&lt;p&gt;Depois de desenvolver todos, ou alguns desses, projetos, é importante mostrar para o mundo o que você produziu. E que melhor forma de fazer isso do que construindo a plataforma que você vai exibi-los? Um outro motivo que torna o Flutter tão prático é que com todos os conhecimentos adquiridos no processo de desenvolvimento desses projetos (graças ao Flutter Web), você pode utilizar-los para construir seu site sem nenhuma complicação. Além disso, pode facilmente, com algumas linhas de comando, hospeda-lo no firebase gratuitamente e conectar ao domínio que você quiser.&lt;/p&gt;

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

&lt;p&gt;Tendo isso em vista, realizando, pelo menos alguns, projetos eu tenho certeza que seus conhecimentos em Flutter vão alavancar de forma rápida. E logo você será capaz de desenvolver layouts e aplicações mais complexas. Não existe melhor forma de aprender do que praticando a todo momento.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>beginners</category>
      <category>mobile</category>
    </item>
  </channel>
</rss>
