<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title>Chemaclass - clean-code</title><subtitle>Tech Lead sharing practical insights on software craftsmanship, TDD, leadership, Bitcoin, and AI. Blog posts, book summaries, and conference talks.</subtitle><link rel="self" type="application/atom+xml" href="https://chemaclass.com/tags/clean-code/atom.xml"/><link rel="alternate" type="text/html" href="https://chemaclass.com"/><generator uri="https://www.getzola.org/">Zola</generator><updated>2024-04-02T00:00:00+00:00</updated><id>https://chemaclass.com/tags/clean-code/atom.xml</id><entry xml:lang="en"><title>Learning Concurrency in Golang</title><subtitle>A horse racing emulator explained step by step</subtitle><category term="golang" scheme="https://chemaclass.com/tags/golang/" label="Golang"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><published>2024-04-02T00:00:00+00:00</published><updated>2024-04-02T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/learning-concurrency-in-golang/"/><id>https://chemaclass.com/blog/learning-concurrency-in-golang/</id><summary type="html">I wanted to learn a new programming language, so after trying some, I ended up with Golang as one of my favorites for its simplicity and capabilities. It has features I haven’t used in years, like multithreading and concurrency.</summary><content type="html">&lt;p>I wanted to learn a new language, so after trying some, I ended up with Golang as one of my favorites for its simplicity and capabilities. It has features I haven’t used in years, like multithreading and concurrency.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>&lt;a rel="external" href="https://go.dev/">Golang&lt;/a> (or &lt;code>Go&lt;/code>) supports concurrency through lightweight threads called goroutines. These are different from traditional multithreading, like in Java, where you have to handle sync and coordination to manage shared resources safely. In contrast, Go’s goroutines are lightweight, managed by the Go runtime, and cheaper to create and manage.&lt;/p>
&lt;p>While parallelism is &lt;strong>doing&lt;/strong> several things simultaneously, concurrency is about &lt;strong>dealing&lt;/strong> with several things at the same time. When we talk about concurrency and parallelism, we don’t know the order of things. We don’t know what’s going to happen first or what’s going to end first. There is an undefined order of execution.&lt;/p>
&lt;blockquote>
&lt;p>Imagine you cooking: preparing a soup, a salad and an omelet. You would be one single unit, but you are preparing different dishes. You might finish the salad first or the soup or the omelet… We cannot guarantee that! This would be concurrency, as you are alone dealing with several things. As soon as your partner comes and helps you cook, then we will be talking about parallelism.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;img src="/images/blog/2024-04-02/concurrency-vs-multithreading.jpg" alt="concurrency vs multithreading" />&lt;/p>
&lt;p>I remember building a similar game in &lt;code>Java&lt;/code> when I was learning multithreading ten years ago… let’s use this opportunity to do it again with modern &lt;code>Go&lt;/code>.&lt;/p>
&lt;p>I built a terminal game emulator that mimics one horse racing. Each horse is a goroutine that runs in a shared bidimensional matrix. Once a horse reaches the end, it notifies the shared channel between all other horses (running in different processes) and they all stop, showing in the terminal the winner of the race.&lt;/p>
&lt;p>I separated the code into four areas to help visualize it:&lt;/p>
&lt;ul>
&lt;li>Entry point&lt;/li>
&lt;li>Generating the board&lt;/li>
&lt;li>Rendering the game&lt;/li>
&lt;li>Moving the horses&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="/images/blog/2024-04-02/race-horses-demo.gif" alt="horse racing terminal demo" />&lt;/p>
&lt;h3 id="entry-point">Entry point
&lt;a class="heading-anchor" href="#entry-point" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>The struct &lt;code>Horse&lt;/code> represents each Horse in the race.
The game consists of a list of lines, in which each Horse is running.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="go">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">type&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> Horse&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> struct&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> Name&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> string&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> The name of the horse&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> Line&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> int&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> The competition line&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span> (&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);">h &lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> Letter&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> string&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> return&lt;/span>&lt;span> fmt&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Sprintf&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">%c&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>,&lt;/span>&lt;span> h&lt;/span>&lt;span>.&lt;/span>&lt;span>Name&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">0&lt;/span>&lt;span>]&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span> (&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);">h &lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> Equals&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);">other&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> *&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> bool&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> return&lt;/span>&lt;span> other&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> !=&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> nil&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> &amp;amp;&amp;amp;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> h&lt;/span>&lt;span>.&lt;/span>&lt;span>Line&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> ==&lt;/span>&lt;span> other&lt;/span>&lt;span>.&lt;/span>&lt;span>Line&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> &amp;amp;&amp;amp;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> h&lt;/span>&lt;span>.&lt;/span>&lt;span>Name&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> ==&lt;/span>&lt;span> other&lt;/span>&lt;span>.&lt;/span>&lt;span>Name&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span> (&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);">h &lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> String&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> string&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> return&lt;/span>&lt;span> fmt&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Sprintf&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">%s&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> (line:&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">%d&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">)&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>,&lt;/span>&lt;span> h&lt;/span>&lt;span>.&lt;/span>&lt;span>Name&lt;/span>&lt;span>,&lt;/span>&lt;span> h&lt;/span>&lt;span>.&lt;/span>&lt;span>Line&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>You can spawn a new process using the keyword &lt;code>go&lt;/code> when invoking any function.
In this game, this is used 1) to render the game &lt;code>RenderGame()&lt;/code> and 2) for each horse’s movement &lt;code>startRuningHorseInLine()&lt;/code>. The goal is to keep the “rendering” and “movement logic” working in parallel.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="go">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> main&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> const&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> lines&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> lineLength&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 12&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 30&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span> board&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> NewRaceBoard&lt;/span>&lt;span>(&lt;/span>&lt;span>lines&lt;/span>&lt;span>,&lt;/span>&lt;span> lineLength&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> go&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> RenderGame&lt;/span>&lt;span>(&lt;/span>&lt;span>board&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span> winnerChan&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> make&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">chan&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> Horse&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> for&lt;/span>&lt;span> line&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> range&lt;/span>&lt;span> board&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> each horse will be moved in different processes&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> go&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> startRunningHorseInLine&lt;/span>&lt;span>(&lt;/span>&lt;span>board&lt;/span>&lt;span>,&lt;/span>&lt;span> line&lt;/span>&lt;span>,&lt;/span>&lt;span> winnerChan&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> wait until one horse reaches the end&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> winner&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> &amp;lt;-&lt;/span>&lt;span>winnerChan&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> render one last time to ensure the latest board state&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> RenderRaceBoard&lt;/span>&lt;span>(&lt;/span>&lt;span>board&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> &amp;amp;&lt;/span>&lt;span>winner&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span> fmt&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Println&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">Race finished!&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> fmt&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Printf&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"># Winner: &lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">%s&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">\n&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>,&lt;/span>&lt;span> winner&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="generating-the-board">Generating the board
&lt;a class="heading-anchor" href="#generating-the-board" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>The race board is a bidimensional matrix of pointers to Horses. Each line “contains” only one Horse; aka only one pointer will point to an actual Horse, the rest will be pointers to &lt;code>nil&lt;/code>. During the generation of the Board, we will create one Horse at the first position of each line.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="go">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> NewRaceBoard&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);">lines&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);"> lineLength&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> int&lt;/span>&lt;span>)&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">*&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> board&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> make&lt;/span>&lt;span>(&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">*&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>,&lt;/span>&lt;span> lines&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> for&lt;/span>&lt;span> line&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> range&lt;/span>&lt;span> board&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> make&lt;/span>&lt;span>(&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">*&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>,&lt;/span>&lt;span> lineLength&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">0&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> &amp;amp;&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> Name&lt;/span>&lt;span>:&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> generateHorseName&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> Line&lt;/span>&lt;span>:&lt;/span>&lt;span> line&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> return&lt;/span>&lt;span> board&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>The names are randomly generated using &lt;code>HorseNames&lt;/code>.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="go">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">var&lt;/span>&lt;span> HorseNames&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">2&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">string&lt;/span>&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">Alloping&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">Giggles&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>}&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">A-lot&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">Gallop&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>}&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">BoJack&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">Jack&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>}&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">Baroness&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">Belle&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>}&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ...&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> generateHorseName&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> string&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> name&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span> HorseNames&lt;/span>&lt;span>[&lt;/span>&lt;span>rand&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Intn&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">len&lt;/span>&lt;span>(&lt;/span>&lt;span>HorseNames&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">0&lt;/span>&lt;span>]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> surname&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span> HorseNames&lt;/span>&lt;span>[&lt;/span>&lt;span>rand&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Intn&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">len&lt;/span>&lt;span>(&lt;/span>&lt;span>HorseNames&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> return&lt;/span>&lt;span> name&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> +&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;quot;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> +&lt;/span>&lt;span> surname&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="rendering-the-game">Rendering the game
&lt;a class="heading-anchor" href="#rendering-the-game" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Then &lt;code>RenderGame()&lt;/code>, &lt;code>renderRaceBoard()&lt;/code>, &lt;code>renderRaceLine()&lt;/code> and &lt;code>renderRacePosition()&lt;/code> are separated to help focus on each method’s responsibility, identifying what is the subject to be rendered.&lt;/p>
&lt;blockquote>
&lt;p>&lt;code>RenderGame()&lt;/code> is being executed in another process using &lt;code>go&lt;/code>.&lt;/p>
&lt;/blockquote>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="go">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> RenderGame&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);">board&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">*&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> for&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> time&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Sleep&lt;/span>&lt;span>(&lt;/span>&lt;span>renderDelay&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> *&lt;/span>&lt;span> time&lt;/span>&lt;span>.&lt;/span>&lt;span>Millisecond&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> RenderRaceBoard&lt;/span>&lt;span>(&lt;/span>&lt;span>board&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> nil&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> RenderRaceBoard&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);">board&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">*&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);"> winner&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> *&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> use a &amp;quot;string buffer&amp;quot; to save the whole board state&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> so we can later use one IO call to render it&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> var&lt;/span>&lt;span> buffer&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> bytes&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Buffer&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> buffer&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">WriteString&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">\n&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> for&lt;/span>&lt;span> line&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> range&lt;/span>&lt;span> board&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> renderRaceLine&lt;/span>&lt;span>(&lt;/span>&lt;span>board&lt;/span>&lt;span>,&lt;/span>&lt;span> line&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> &amp;amp;&lt;/span>&lt;span>buffer&lt;/span>&lt;span>,&lt;/span>&lt;span> winner&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> clearScreen&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> fmt&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Println&lt;/span>&lt;span>(&lt;/span>&lt;span>buffer&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">String&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> clearScreen&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> cmd&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span> exec&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Command&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">clear&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> cmd&lt;/span>&lt;span>.&lt;/span>&lt;span>Stdout&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> os&lt;/span>&lt;span>.&lt;/span>&lt;span>Stdout&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> cmd&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Run&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> renderRaceLine&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#E36209, #FFAB70);"> board&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">*&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#E36209, #FFAB70);"> line&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> int&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#E36209, #FFAB70);"> buffer&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> *&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">bytes&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Buffer&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#E36209, #FFAB70);"> winner&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> *&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> buffer&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">WriteString&lt;/span>&lt;span>(&lt;/span>&lt;span>fmt&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Sprintf&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> %.2d&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> | &lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>,&lt;/span>&lt;span> line&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> var&lt;/span>&lt;span> current&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> Horse&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> for&lt;/span>&lt;span> col&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> range&lt;/span>&lt;span> board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> h&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> renderRacePosition&lt;/span>&lt;span>(&lt;/span>&lt;span>board&lt;/span>&lt;span>,&lt;/span>&lt;span> line&lt;/span>&lt;span>,&lt;/span>&lt;span> col&lt;/span>&lt;span>,&lt;/span>&lt;span> buffer&lt;/span>&lt;span>,&lt;/span>&lt;span> winner&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> if&lt;/span>&lt;span> h&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> !=&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> nil&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> current&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> *&lt;/span>&lt;span>h&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> buffer&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">WriteString&lt;/span>&lt;span>(&lt;/span>&lt;span>fmt&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Sprintf&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">| &lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">%s&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>,&lt;/span>&lt;span> current&lt;/span>&lt;span>.&lt;/span>&lt;span>Name&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> if&lt;/span>&lt;span> current&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Equals&lt;/span>&lt;span>(&lt;/span>&lt;span>winner&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> buffer&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">WriteString&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> [Won!]&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> buffer&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">WriteString&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">\n&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> renderRacePosition&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#E36209, #FFAB70);"> board&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">*&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#E36209, #FFAB70);"> line&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);"> col&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> int&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#E36209, #FFAB70);"> buffer&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> *&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">bytes&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Buffer&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#E36209, #FFAB70);"> winner&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> *&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> *&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> if&lt;/span>&lt;span> board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>col&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> ==&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> nil&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> buffer&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">WriteString&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;quot;&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> return&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> nil&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span> current&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span> board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>col&lt;/span>&lt;span>]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> if&lt;/span>&lt;span> current&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Equals&lt;/span>&lt;span>(&lt;/span>&lt;span>winner&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> removeChars&lt;/span>&lt;span>(&lt;/span>&lt;span>buffer&lt;/span>&lt;span>,&lt;/span>&lt;span> col&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">+&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> for&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> range&lt;/span>&lt;span> board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> buffer&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">WriteString&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">-&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span> buffer&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">WriteString&lt;/span>&lt;span>(&lt;/span>&lt;span>current&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Letter&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> return&lt;/span>&lt;span> current&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="moving-the-horses">Moving the horses
&lt;a class="heading-anchor" href="#moving-the-horses" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>In &lt;code>main(...)&lt;/code>, the &lt;code>winnerChan&lt;/code> is a shared channel that will be used by the first Horse reaching the last position in their line.&lt;/p>
&lt;p>Each Horse will run a loop until reaching the end of the line OR receiving (via the shared channel &lt;code>winnerChan&lt;/code>) the message that another Horse already won the race. Until then, each horse will move independently by randomly sleeping milliseconds before moving to the next position in their line.&lt;/p>
&lt;blockquote>
&lt;p>&lt;code>startRuningHorseInLine()&lt;/code> runs in another process using &lt;code>go&lt;/code>.&lt;/p>
&lt;/blockquote>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="go">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> main&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">...&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> winnerChan&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> make&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">chan&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> Horse&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> for&lt;/span>&lt;span> line&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> range&lt;/span>&lt;span> board&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> each horse will be moved in different processes&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> go&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> startHorseRunning&lt;/span>&lt;span>(&lt;/span>&lt;span>board&lt;/span>&lt;span>,&lt;/span>&lt;span> line&lt;/span>&lt;span>,&lt;/span>&lt;span> winnerChan&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> wait until one horse reaches the end&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> winner&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> &amp;lt;-&lt;/span>&lt;span>winnerChan&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">...&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> startRunningHorseInLine&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);">board&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">*&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);"> line&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> int&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);"> winnerChan&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> chan&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> Horse&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> for&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> select&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> case&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> &amp;lt;-&lt;/span>&lt;span>winnerChan&lt;/span>&lt;span>:&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> check if another horse finished&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> return&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> in such a case, then stop the for loop&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> default&lt;/span>&lt;span>:&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> time&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Sleep&lt;/span>&lt;span>(&lt;/span>&lt;span>time&lt;/span>&lt;span>.&lt;/span>&lt;span>Millisecond&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> *&lt;/span>&lt;span> time&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Duration&lt;/span>&lt;span>(&lt;/span>&lt;span>rand&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Intn&lt;/span>&lt;span>(&lt;/span>&lt;span>maxSleepDelay&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> moveHorseOnePos&lt;/span>&lt;span>(&lt;/span>&lt;span>board&lt;/span>&lt;span>,&lt;/span>&lt;span> line&lt;/span>&lt;span>,&lt;/span>&lt;span> winnerChan&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> moveHorseOnePos&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);">board&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">*&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);"> line&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> int&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);"> winnerChan&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> chan&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> Horse&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> cols&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> len&lt;/span>&lt;span>(&lt;/span>&lt;span>board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> for&lt;/span>&lt;span> col&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span> cols&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> -&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 1&lt;/span>&lt;span>;&lt;/span>&lt;span> col&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> &amp;gt;&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 0&lt;/span>&lt;span>;&lt;/span>&lt;span> col&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">--&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> if&lt;/span>&lt;span> board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>col&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">-&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> ==&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> nil&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> continue&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> here we identify that there is a horse in&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> the following column, so we move it to the&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> current column, and we set `nil` the other one&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>col&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>col&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">-&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>col&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">-&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> nil&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> if&lt;/span>&lt;span> col&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">+&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> ==&lt;/span>&lt;span> cols&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> winnerChan&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> &amp;lt;-&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> *&lt;/span>&lt;span>board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>col&lt;/span>&lt;span>]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> break&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="source-code">Source code
&lt;a class="heading-anchor" href="#source-code" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>The code displayed in this post is a simplified version, so if you would like to check the working source, you can do it here: &lt;a rel="external" href="https://github.com/Chemaclass/go-horse-racing">Chemaclass/go-horse-racing&lt;/a>.&lt;/p>
&lt;aside class="kudos">
&lt;span class="kudos__icon" aria-hidden="true">🧠&lt;/span>
&lt;div class="kudos__content">
&lt;p>Thanks to my former Team Lead, Andrei Boar, who helped me review my first original solution and provided an &lt;a rel="external" href="https://gist.github.com/zuzuleinen/79413aa7933d7d6c6d84ec6ba8c3910a">alternative solution&lt;/a> (simpler and better!), which I applied to my original code. The main learning was using a &lt;code>chan Horse&lt;/code> to pass the winner Horse from &lt;code>main()&lt;/code>, instead of using a &lt;code>chan bool&lt;/code> and a &lt;code>sync.WaitGroup&lt;/code> between all threads.&lt;/p>
&lt;/div>
&lt;/aside></content></entry><entry xml:lang="en"><title>Effective Pair Programming</title><subtitle>Embracing quality practices in your engineering culture</subtitle><category term="pair-programming" scheme="https://chemaclass.com/tags/pair-programming/" label="Pair Programming"/><category term="xp" scheme="https://chemaclass.com/tags/xp/" label="Xp"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><category term="communication" scheme="https://chemaclass.com/tags/communication/" label="Communication"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><published>2024-03-28T00:00:00+00:00</published><updated>2024-03-28T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/effective-pair-programming/"/><id>https://chemaclass.com/blog/effective-pair-programming/</id><summary type="html">A practical guide to pair programming that works: roles, rotation, when to pair, common pitfalls, and how to make sessions productive.</summary><content type="html">&lt;p>What is pair programming? Two people working together on the same problem, at the same time.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>It is not about one person showing off their skills in front of another, nor one person afraid of making mistakes due to an impostor syndrome.&lt;/p>
&lt;p>Each person will have a role:&lt;/p>
&lt;ul>
&lt;li>Navigator: he will pay attention to the bigger picture; eg: architecture, relation between collaborators, object design, etc.&lt;/li>
&lt;li>Driver: she will pay attention to the small details; eg: naming, code conventions, writing syntax, object design, etc.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>The pair could, and should, switch roles occasionally; eg: every X commits pushed, every 10 mins, … up to them.&lt;/p>
&lt;/blockquote>
&lt;p>Pair programming should not be considered a practice only for “seniors” to juniors, but regardless of the team members’ experience level.&lt;/p>
&lt;p>It is about the &lt;strong>collaboration flow&lt;/strong>, the quality communication, the absence of feeling judged, and the idea of welcoming vulnerability with your peers, knowing they will support and help you.&lt;/p>
&lt;p>It is about constantly challenging each other, seeking the most pragmatic solution while keeping it simple. Always looking for &lt;strong>quick feedback&lt;/strong> when speaking to each other, but also on the solution you agreed to implement and its direction.&lt;/p>
&lt;p>It is about the short, quick, and immediate feedback loop while talking to your partner, who &lt;strong>reviews your code on the fly&lt;/strong>. You can guide as a navigator or help the driver validate their ideas in a broader picture.&lt;/p>
&lt;p>It is about the constant &lt;strong>sharing&lt;/strong> of &lt;strong>knowledge&lt;/strong> atmosphere by default, reducing bus-factors and silo-knowledge areas to the maximum. Increasing the focus by having two minds working on the same task simultaneously.&lt;/p>
&lt;p>It is about &lt;strong>team cohesion&lt;/strong> and sharpening the feeling that we belong. When we understand each other’s strengths and weaknesses, we will realize how much we can help each other grow.&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-03-28/footer.webp" alt="blog-img" />&lt;/p>
&lt;h2 id="how-can-you-practice-pair-programming">How can you practice pair programming?
&lt;a class="heading-anchor" href="#how-can-you-practice-pair-programming" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Pair programming can be done in different ways:&lt;/p>
&lt;ul>
&lt;li>You can start and finish a task with pairing. You can time-box it to 30, 60, 90 minutes. Either way, it is recommended to have pauses in the middle - Pomodoro.&lt;/li>
&lt;li>You can start the task together and stop when one of your peers feels confident enough to continue alone.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>It is up to the team, and the task in context, to decide when and how to apply pairing to get the best out of it.&lt;/p>
&lt;/blockquote>
&lt;p>This does not mean you must constantly work “no matter what” in pair. This is not about creating rules; on the contrary, it is about embracing this practice to the point you feel confident to choose when and how to use it to get the best out of it.&lt;/p>
&lt;p>Pair programming might become one of the best tools in your team toolbox for daily interactions. Not because you read it somewhere but because of the benefits you and your team will find.&lt;/p>
&lt;h3 id="common-patterns">Common Patterns
&lt;a class="heading-anchor" href="#common-patterns" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;h4 id="different-strategies-for-effective-pairing">Different strategies for effective pairing
&lt;a class="heading-anchor" href="#different-strategies-for-effective-pairing" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>&lt;strong>Driver-Navigator&lt;/strong>: One person is driving the code (with the keyboard), focusing on the detail aspect of the task itself. The other is a navigator (no keyboard), having a more abstract picture of the task in mind.&lt;/li>
&lt;li>&lt;strong>Ping-Pong&lt;/strong>: Frequent switching driver-navigator roles in small interactions, e.g., every N minutes, every N commits, etc.&lt;/li>
&lt;li>&lt;strong>Backseat driver&lt;/strong>: The navigator engages actively with the driver.&lt;/li>
&lt;li>&lt;strong>Tourist guide&lt;/strong>: The navigator passively learns with the driver.&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="/images/blog/2024-03-28/good-pair-prog.jpg" alt="effective pair programming patterns" />&lt;/p>
&lt;h4 id="anti-patterns-while-pairing">Anti-patterns while pairing
&lt;a class="heading-anchor" href="#anti-patterns-while-pairing" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>&lt;strong>The silent partner&lt;/strong>: The navigator is not participating, and they are being silent.&lt;/li>
&lt;li>&lt;strong>The solo act&lt;/strong>: The driver ignores all inputs from the navigator.&lt;/li>
&lt;li>&lt;strong>Distracted pair&lt;/strong>: The pair does not focus on the problem to solve.&lt;/li>
&lt;li>&lt;strong>The Dictator&lt;/strong>: One person is telling what to do, ignoring the input from the other.&lt;/li>
&lt;li>&lt;strong>Philosophical pair&lt;/strong>: The pair is &lt;a href="/blog/bikeshedding/">bikeshedding&lt;/a> into irrelevant topics.&lt;/li>
&lt;li>&lt;strong>The code war&lt;/strong>: The pair does not reach an agreement and starts an unnecessary war, which wastes time and effort.&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="/images/blog/2024-03-28/anti-pair-prog.jpg" alt="pair programming anti-patterns" />&lt;/p>
&lt;p>&lt;strong>Want more?&lt;/strong> Check this out: &lt;a rel="external" href="https://www.figma.com/file/FCmGwRPIO8cLowDRraJhgr/Learning-TDD">Learning Through KATAS&lt;/a>&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-03-28/learning-through-katas.jpg" alt="learning through katas" />&lt;/p>
&lt;h2 id="the-takeaway">The takeaway
&lt;a class="heading-anchor" href="#the-takeaway" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Pairing is not a rule to enforce, it is a tool to reach for. Use it when the task is complex, the knowledge is siloed,
or the stakes are high. Skip it when the work is trivial. The goal is never “always pair”, it is &lt;strong>better software and a
stronger team&lt;/strong>. Pick one real task this week, pair on it, and switch roles often. The benefits show up faster than you
expect.&lt;/p>
&lt;aside class="kudos">
&lt;span class="kudos__icon" aria-hidden="true">🧠&lt;/span>
&lt;div class="kudos__content">
&lt;p>Thanks to my friend &lt;a rel="external" href="https://x.com/evrtrabajo">Manu&lt;/a>, who helped me with this post. We even share a &lt;a rel="external" href="https://phpconference.com/agile-culture/practical-tdd-workshop/">workshop&lt;/a> on this topic.&lt;/p>
&lt;/div>
&lt;/aside></content></entry><entry xml:lang="en"><title>Great Engineering</title><subtitle>A great engineer is not just a great coder</subtitle><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="career" scheme="https://chemaclass.com/tags/career/" label="Career"/><category term="communication" scheme="https://chemaclass.com/tags/communication/" label="Communication"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><published>2023-12-30T00:00:00+00:00</published><updated>2023-12-30T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/great-engineering/"/><id>https://chemaclass.com/blog/great-engineering/</id><summary type="html">Coding is not just another job. In the right environment, writing software can be really fun and, even more, it can be your personal hobby as well! So... you might be focused on coding, coding and more coding to level up your own career skills.</summary><content type="html">&lt;p>Coding is not just another job. Writing software can be really fun and, even more, it can be your personal hobby as well! You might be focused on coding, coding and more coding to level up your own career skills.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>That itself is not bad at all! Practice makes the master, so a lot of coding will inevitably help you improve your coding skills… but there are &lt;a href="/blog/the-path-to-seniority-in-software/">other aspects&lt;/a> that you need to keep in mind in order to help you grow into a great engineer.&lt;/p>
&lt;p>As a software engineer, your job is not “just to write software” for its own sake, but to &lt;strong>use software to solve actual business problems&lt;/strong>. To make that happen there are plenty of different methodologies out there, for sure. However, we must agree that you need to identify and understand your customer’s needs in order to know what to actually build.&lt;/p>
&lt;p>You need to know your product, at least until certain level, so you can design your software using a similar language closer to the business, which will help its evolution and overall quality. This will be beneficial for the future (and present) maintenance of the product.&lt;/p>
&lt;p>IT, Software, Product and People topics are highly interconnected, and having at least a common ground of understanding the relation between these can help the overall goal of every single individual.&lt;/p>
&lt;p>The result of a great team work is not equal as the sum of the individual parts, as it’s multiplying the created value among their peers. To that, great communication skills are a key part of it in order to create as much clarity as possible from any different abstraction level.&lt;/p>
&lt;p>That’s why a great engineer is a knowledgeable person about business, customer, product, and coding. Understanding these points have a strong impact on your daily work as it creates a difference between the average and the great engineer.&lt;/p>
&lt;hr />
&lt;p>Image original by &lt;a rel="external" href="https://hybridhacker.email">Nicola Ballotta&lt;/a>.&lt;/p></content></entry><entry xml:lang="en"><title>How to Test Private Methods?</title><subtitle>Testing private methods. When and how?</subtitle><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><published>2023-10-20T00:00:00+00:00</published><updated>2023-10-20T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/how-to-test-private-methods/"/><id>https://chemaclass.com/blog/how-to-test-private-methods/</id><summary type="html">From time to time I have had to face this question: how to test private methods? I have put together in an article the techniques that I usually use.</summary><content type="html">&lt;p>This is a question that I have encountered with some frequency for a long time. So I thought I would put together my thoughts on the subject here.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="short-answer">Short answer
&lt;a class="heading-anchor" href="#short-answer" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Never.&lt;/p>
&lt;h2 id="long-answer">Long answer
&lt;a class="heading-anchor" href="#long-answer" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Never ever.&lt;/p>
&lt;hr />
&lt;h2 id="what-if">What if…?
&lt;a class="heading-anchor" href="#what-if" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>If you really want to test a private method, consider extracting that private method logic into a separate class, and write a unit test for that class’ behavior.&lt;/p>
&lt;blockquote>
&lt;p>For this one, I was inspired by Fran Iglesias’ &lt;a rel="external" href="https://franiglesias.github.io/test-private-methods/">original post&lt;/a>.&lt;/p>
&lt;/blockquote></content></entry><entry xml:lang="en"><title>Dedicated QA Teams in Software?</title><subtitle>How does it fit a dedicated QA person in your agile team?</subtitle><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><category term="agile" scheme="https://chemaclass.com/tags/agile/" label="Agile"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><published>2023-05-17T00:00:00+00:00</published><updated>2023-05-17T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/dedicated-qa-teams/"/><id>https://chemaclass.com/blog/dedicated-qa-teams/</id><summary type="html">This will be controversial, but let's talk about the QA position. The hidden truth behind the lack of software quality and why this should concern you if you write software.</summary><content type="html">&lt;p>This will be controversial, but let’s talk about the QA position. The hidden truth behind the lack of software quality and why this should concern you if you write software.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="qa-is-a-role-not-a-position">QA is a role, not a position
&lt;a class="heading-anchor" href="#qa-is-a-role-not-a-position" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>As a software developer, when you write software, you are responsible for the quality of whatever you’re writing. A third person acting like QA could find that your solution doesn’t work like expected, but how come? You might argue they might catch edge cases, but how could that be possible if the software was already tested previously?&lt;/p>
&lt;p>A software team’s final goal is to make the QA position useless because they should find nothing but well-working software. But how do you get to that point? How can we ensure that the software we write is working as expected and there is no need for a QA person in our team?&lt;/p>
&lt;h2 id="the-hidden-truth-behind-the-lack-of-software-quality">The hidden truth behind the lack of software quality
&lt;a class="heading-anchor" href="#the-hidden-truth-behind-the-lack-of-software-quality" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Unfortunately, in our software industry, the demand for “fast, quick and dirty” projects ended up in poorly developed MVPs by simply applying patches and code over code with just manual testing checking happy paths, sometimes even ignoring edge cases.&lt;/p>
&lt;blockquote>
&lt;p>“The deadline is in one week, so you better finish it on time!”&lt;/p>
&lt;/blockquote>
&lt;p>We don’t learn the importance of what automated testing can bring to our daily job, so we don’t take it seriously, and therefore, we don’t practice it enough. And, for that exact reason, because we don’t practice it, we don’t know how to perform it properly. Yes, I am talking about writing automated tests that prove the behavior of your software!&lt;/p>
&lt;p>Our inability to write testable code results in software that is hard to test, and thus we delegate testing to other third parties shifting the responsibility for the overall end quality of the product or service we write.&lt;/p>
&lt;h2 id="practice-makes-the-master">Practice makes the master
&lt;a class="heading-anchor" href="#practice-makes-the-master" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>You must learn and apply proper testing techniques when they make sense. How and when effectively use test doubles, prepare solitary or sociable tests, which compromises and reasons backup your mind when choosing one or other paths toward your testing strategies?&lt;/p>
&lt;p>You are the latest and main responsible person in charge of your knowledge, so you better invest in yourself because no one else will do it for you.&lt;/p>
&lt;p>Look at everything you do as an opportunity for learning. Practice and get better by default at everything you do.&lt;/p>
&lt;p>If you don’t know how to start, here is my favourite tip: you can always practice and improve your testing skills using code-katas. Read more about this topic &lt;a href="/blog/test-driven-development/">here&lt;/a>.&lt;/p>
&lt;h2 id="nice-theory-but-why-bother">Nice theory, but… why bother?
&lt;a class="heading-anchor" href="#nice-theory-but-why-bother" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Manual testing is, of course, necessary. It is another testing strategy that I am not blaming or attacking. We might still need a dedicated person in charge of discovering what new features we want to build to satisfy our clients. But this blog-post is not about that position.&lt;/p>
&lt;p>It is all about shortening the feedback loop. If you can write software to work in specific ways, can’t you write automated tests to prove that the software you wrote behaves the way you expect?&lt;/p>
&lt;p>If you have covered with automated tests the behavior of your software at any level that makes sense, what’s left for a dedicated QA person?&lt;/p>
&lt;p>Next time you think about “We need a QA person to test this,” try the exercise of thinking instead, “How can I write an automated test that verifies what I would expect if a QA person were checking this?”&lt;/p>
&lt;p>And that’s how you change the “full-time QA position” into a “role mentality for everyone that writes software.”&lt;/p>
&lt;p>Code never lies and never forgets; once it’s written and automated in your pipeline, you can run it anytime at zero cost.&lt;/p>
&lt;p>&lt;img src="/images/blog/2023-05-17/footer.webp" alt="blog-footer" />&lt;/p></content></entry><entry xml:lang="en"><title>Recipes for Decoupling</title><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="architecture" scheme="https://chemaclass.com/tags/architecture/" label="Architecture"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><published>2022-11-28T00:00:00+00:00</published><updated>2022-11-28T00:00:00+00:00</updated><author><name>
Matthias Noback</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/readings/recipes-for-decoupling/"/><id>https://chemaclass.com/readings/recipes-for-decoupling/</id><summary type="html">What is coupling, and why is it bad? What is decoupling, and how to do it efficiently? This book is a compilation of strategies to decouple your domain code from those infrastructure details, so you can enjoy a healthier system in the long run.</summary><content type="html">&lt;span id="continue-reading">&lt;/span>
&lt;p>What is coupling, and why is it bad? What is decoupling, and how to do it efficiently? This book is a compilation of
strategies to decouple your domain code from those infrastructure details, so you can enjoy a healthier system in the
long run.&lt;/p>
&lt;p>This book will teach you how to create &lt;a rel="external" href="https://phpstan.org/">&lt;strong>PHPStan&lt;/strong>&lt;/a> rules from no knowledge, and then it will
guide you across many decoupling opportunities like, for example:&lt;/p>
&lt;ul>
&lt;li>web framework&lt;/li>
&lt;li>cli frameworks&lt;/li>
&lt;li>form validation&lt;/li>
&lt;li>orm and database&lt;/li>
&lt;li>test framework&lt;/li>
&lt;/ul>
&lt;p>Read more about the book: &lt;a rel="external" href="https://matthiasnoback.nl/book/recipes-for-decoupling/">matthiasnoback.nl/book/recipes-for-decoupling/&lt;/a>&lt;/p>
&lt;blockquote>
&lt;p>Buy it here: &lt;a rel="external" href="https://leanpub.com/recipes-for-decoupling">leanpub.com/recipes-for-decoupling&lt;/a>&lt;/p>
&lt;/blockquote></content></entry><entry xml:lang="en"><title>Different Beliefs About Software Quality</title><subtitle>Some thoughts about software quality among your team</subtitle><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="agile" scheme="https://chemaclass.com/tags/agile/" label="Agile"/><category term="xp" scheme="https://chemaclass.com/tags/xp/" label="Xp"/><category term="communication" scheme="https://chemaclass.com/tags/communication/" label="Communication"/><category term="career" scheme="https://chemaclass.com/tags/career/" label="Career"/><published>2022-10-08T00:00:00+00:00</published><updated>2022-10-08T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/different-beliefs-about-software-quality/"/><id>https://chemaclass.com/blog/different-beliefs-about-software-quality/</id><summary type="html">What to do when working on "bad software" and you can't improve it because it is against the beliefs of your peers? Should you change the company?</summary><content type="html">&lt;p>I recently got a great question on Twitter which got me thinking for a while and I decided to share my thoughts about it.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;hr />
&lt;h2 id="the-tweet-that-started-this">The tweet that started this
&lt;a class="heading-anchor" href="#the-tweet-that-started-this" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>But first, some context: I am feeling great because the codebase where I work is getting better and better, so I am tweeting this:&lt;/p>
&lt;blockquote>
&lt;p>“As software improves with time, you can feel you’re doing right.”&lt;/p>
&lt;/blockquote>
&lt;p>And then I got a question asking for suggestions:&lt;/p>
&lt;p>&lt;img src="/images/blog/2022-10-08/tweet.jpg" alt="blog-tweet" />&lt;/p>
&lt;p>So there we go…&lt;/p>
&lt;hr />
&lt;h2 id="my-answer">My answer
&lt;a class="heading-anchor" href="#my-answer" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;h3 id="create-agreements">Create agreements
&lt;a class="heading-anchor" href="#create-agreements" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>The first thing is to create agreements about what quality software means for your team and yourself. This helps clarify
what software culture you want to establish and work towards that direction. Leaving your company should be the &lt;em>last
resort&lt;/em> once you have no other option.&lt;/p>
&lt;p>Before thinking about leaving your company, I would ask you:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Why do you think&lt;/strong> you cannot improve the working codebase of your company?&lt;/li>
&lt;li>&lt;strong>What can you do&lt;/strong> to reduce the friction between your different beliefs regarding what quality means for software?&lt;/li>
&lt;/ul>
&lt;p>There is no perfect codebase to work on because software is a living entity and constantly changes. So, at least for me,
quality software is the one that can cope with change smoothly.&lt;/p>
&lt;p>Once you have agreed on that goal, and while there are multiple ways to achieve that result, my favorite way of working
is keeping an &lt;strong>agile mindset&lt;/strong> with doses of &lt;strong>extreme programming&lt;/strong> values, principles, and practices in mind.&lt;/p>
&lt;h3 id="software-is-about-people">Software is about people
&lt;a class="heading-anchor" href="#software-is-about-people" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Software is not just about writing &lt;em>clean and solid code&lt;/em>. This is indeed desired, and we should aim for that, but we must
first understand why we want that. The “&lt;em>why&lt;/em>” is based on the &lt;strong>values&lt;/strong> that you have as a team.&lt;/p>
&lt;p>If you don’t share the same purpose, the same “why,” then you won’t &lt;em>enjoy&lt;/em> working together, and in such a case, I would
advise looking for another company that shares your values. But, before that, I would strongly suggest fixing the deeper
issue and helping your team improve.&lt;/p>
&lt;h3 id="understanding-your-why">Understanding your why
&lt;a class="heading-anchor" href="#understanding-your-why" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>You first need to deeply understand your “&lt;em>why&lt;/em>” so you can transmit this to your peers and the people around you. Have
you tried all you can to create awareness about your “&lt;em>why&lt;/em>”?&lt;/p>
&lt;p>Some ideas include encouraging collaborative programming (pair/mob), presenting some internal tech talks, creating a
culture of sharing knowledge on a regular daily basis, creating awareness about the current status quo, and looking for
opportunities to improve everywhere.&lt;/p>
&lt;h3 id="your-career-path">Your career path
&lt;a class="heading-anchor" href="#your-career-path" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>If, after several months of (really) trying these ideas, none of them work, look for a new company that shares your
beliefs. After all, you’re the first and primary responsible person for taking care of your career path.&lt;/p>
&lt;blockquote>
&lt;p>Original &lt;a rel="external" href="https://x.com/Chemaclass/status/1578425454562021376">twitter thread&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;hr />
&lt;p>&lt;img src="/images/blog/2022-10-08/footer.webp" alt="blog-footer" />&lt;/p>
&lt;h2 id="extra-thoughts">Extra thoughts
&lt;a class="heading-anchor" href="#extra-thoughts" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>If &lt;strong>you want something to be different&lt;/strong>, don’t wait till it’s changed automatically. Try to &lt;strong>change it&lt;/strong>; if it’s not
working, leave it. Maybe you don’t belong in that place.&lt;/p>
&lt;p>On the other hand, it’s crucial to reflect if you see that pattern often repeating (changing companies too quickly). In
such a case, maybe the problem isn’t the companies but yourself.&lt;/p>
&lt;p>Software development is not just about code but &lt;strong>business&lt;/strong>. It’s essential to be aware of finding a fair &lt;em>trade-off&lt;/em>
between speed, costs, and quality, depending on the situation. You might want to use some &lt;em>tech debt&lt;/em> to conquer the
market as soon as possible.&lt;/p>
&lt;p>It doesn’t make sense to have “low quality” as part of the identity of any team. Every team has certain quality
expectations. Therefore, the &lt;strong>key&lt;/strong> here is to &lt;strong>agree on what good quality is&lt;/strong>.&lt;/p>
&lt;aside class="kudos">
&lt;span class="kudos__icon" aria-hidden="true">🧠&lt;/span>
&lt;div class="kudos__content">
&lt;p>Thanks to my former Engineer Manager, Evgenii Sokolov, who inspired me to write these extra lines after sharing the original post.&lt;/p>
&lt;/div>
&lt;/aside></content></entry><entry xml:lang="en"><title>Clean Craftsmanship</title><subtitle>Disciplines, Standards, and Ethics</subtitle><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="xp" scheme="https://chemaclass.com/tags/xp/" label="Xp"/><published>2022-07-11T00:00:00+00:00</published><updated>2022-07-11T00:00:00+00:00</updated><author><name>
Robert C. Martin</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/readings/clean-craftsmanship/"/><id>https://chemaclass.com/readings/clean-craftsmanship/</id><summary type="html">Robert C. Martin covers the three pillars of software craftsmanship: TDD disciplines with practical examples, professional standards for teams, and the ethical responsibilities of programmers.</summary><content type="html">&lt;span id="continue-reading">&lt;/span>
&lt;p>The book is divided into three parts: the disciplines, the standards, and the ethics.&lt;/p>
&lt;p>The 1st part is the most technical one. It guides you with TDD examples, showing how testing can help you to design your code.&lt;/p>
&lt;p>The 2nd part is about productivity, quality, and courage.&lt;/p>
&lt;p>The 3rd part is about how did we get here in terms of people who develop software, and our responsibility within
our ethics about do no harm, integrity, and teamwork.&lt;/p>
&lt;hr />
&lt;p>One of my favourite parts from the book:&lt;/p>
&lt;blockquote>
&lt;p>Our software industry is wildly dynamic and changing; therefore, we must all be continuously aggressive learners.&lt;/p>
&lt;p>How and when do you do this learning? If your employer provides you the time and space to do this kind of learning, then
take as much advantage of it as you can. If your employer is not helpful, then you’ll have to learn on your own time.&lt;/p>
&lt;p>Be prepared to spend several hours per month on it. Make sure you have the personal time set aside for it.&lt;/p>
&lt;p>Yes, I know you have family obligations, bills to pay, planes to catch, and you’ve got a life. Okay, but you also have a
profession. And professions need care and maintenance. I expect us all to be continuous aggressive learners.&lt;/p>
&lt;p>&lt;code>Chapter 11. Courage - Continuous Aggressive Learning&lt;/code>&lt;/p>
&lt;/blockquote>
&lt;hr />
&lt;h2 id="index">Index
&lt;a class="heading-anchor" href="#index" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;h3 id="part-i-the-disciplines">Part I: The Disciplines
&lt;a class="heading-anchor" href="#part-i-the-disciplines" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;h4 id="chapter-1-craftsmanship">Chapter 1. Craftsmanship
&lt;a class="heading-anchor" href="#chapter-1-craftsmanship" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Extreme Programming&lt;/li>
&lt;li>Test-Driven Development&lt;/li>
&lt;li>Refactoring&lt;/li>
&lt;li>Simple Design&lt;/li>
&lt;li>Collaborative Programming&lt;/li>
&lt;li>Acceptance Tests&lt;/li>
&lt;/ul>
&lt;h4 id="chapter-2-test-driven-development">Chapter 2. Test-Driven Development
&lt;a class="heading-anchor" href="#chapter-2-test-driven-development" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Overview&lt;/li>
&lt;li>The Basics&lt;/li>
&lt;/ul>
&lt;h4 id="chapter-3-advanced-tdd">Chapter 3. Advanced TDD
&lt;a class="heading-anchor" href="#chapter-3-advanced-tdd" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Getting Stuck&lt;/li>
&lt;li>Arrange, Act, Assert&lt;/li>
&lt;li>Test Doubles&lt;/li>
&lt;li>Architecture&lt;/li>
&lt;/ul>
&lt;h4 id="chapter-4-test-design">Chapter 4. Test Design
&lt;a class="heading-anchor" href="#chapter-4-test-design" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Testing Databases&lt;/li>
&lt;li>Testing GUIs&lt;/li>
&lt;li>Test Patterns&lt;/li>
&lt;li>Test-Specific Subclass&lt;/li>
&lt;li>Humble Object&lt;/li>
&lt;li>Test Design&lt;/li>
&lt;li>Breaking the Correspondence&lt;/li>
&lt;/ul>
&lt;h4 id="chapter-5-refactoring">Chapter 5. Refactoring
&lt;a class="heading-anchor" href="#chapter-5-refactoring" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>What Is Refactoring?&lt;/li>
&lt;li>The Basic Toolkit&lt;/li>
&lt;li>Extract Method&lt;/li>
&lt;li>The Disciplines&lt;/li>
&lt;/ul>
&lt;h4 id="chapter-6-simple-design">Chapter 6. Simple Design
&lt;a class="heading-anchor" href="#chapter-6-simple-design" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>YAGNI&lt;/li>
&lt;li>Covered by Tests&lt;/li>
&lt;li>Coverage&lt;/li>
&lt;li>Design?&lt;/li>
&lt;li>Maximize Expression&lt;/li>
&lt;li>The Underlying Abstraction&lt;/li>
&lt;li>Minimize Duplication&lt;/li>
&lt;li>Minimize Size&lt;/li>
&lt;/ul>
&lt;h4 id="chapter-7-collaborative-programming">Chapter 7. Collaborative Programming
&lt;a class="heading-anchor" href="#chapter-7-collaborative-programming" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;h4 id="chapter-8-acceptance-tests">Chapter 8. Acceptance Tests
&lt;a class="heading-anchor" href="#chapter-8-acceptance-tests" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>The Discipline&lt;/li>
&lt;li>The Continuous Build&lt;/li>
&lt;/ul>
&lt;h3 id="part-ii-the-standards">Part II: The Standards
&lt;a class="heading-anchor" href="#part-ii-the-standards" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;h4 id="chapter-9-productivity">Chapter 9. Productivity
&lt;a class="heading-anchor" href="#chapter-9-productivity" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>We Will Never Ship S**T&lt;/li>
&lt;li>Inexpensive Adaptability&lt;/li>
&lt;li>We Will Always Be Ready&lt;/li>
&lt;li>Stable Productivity&lt;/li>
&lt;/ul>
&lt;h4 id="chapter-10-quality">Chapter 10. Quality
&lt;a class="heading-anchor" href="#chapter-10-quality" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Continuous Improvement&lt;/li>
&lt;li>Fearless Competence&lt;/li>
&lt;li>Extreme Quality&lt;/li>
&lt;li>We Will Not Dump on QA&lt;/li>
&lt;li>QA Will Find Nothing&lt;/li>
&lt;li>Test Automation&lt;/li>
&lt;li>Automated Testing and User Interfaces&lt;/li>
&lt;li>Testing the User Interface&lt;/li>
&lt;/ul>
&lt;h4 id="chapter-11-courage">Chapter 11. Courage
&lt;a class="heading-anchor" href="#chapter-11-courage" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>We Cover for Each Other&lt;/li>
&lt;li>Honest Estimates&lt;/li>
&lt;li>You Must Say NO&lt;/li>
&lt;li>Continuous Aggressive Learning&lt;/li>
&lt;li>Mentoring&lt;/li>
&lt;/ul>
&lt;h3 id="part-iii-the-ethics">Part III: The Ethics
&lt;a class="heading-anchor" href="#part-iii-the-ethics" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>The First Programmer&lt;/li>
&lt;li>Seventy-Five Years&lt;/li>
&lt;li>Nerds and Saviors&lt;/li>
&lt;li>Role Models and Villains&lt;/li>
&lt;li>We Rule the World&lt;/li>
&lt;li>Catastrophes&lt;/li>
&lt;li>The Oath&lt;/li>
&lt;/ul>
&lt;h4 id="chapter-12-harm">Chapter 12. Harm
&lt;a class="heading-anchor" href="#chapter-12-harm" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>First, Do No Harm&lt;/li>
&lt;li>Best Work&lt;/li>
&lt;li>Repeatable Proof&lt;/li>
&lt;/ul>
&lt;h4 id="chapter-13-integrity">Chapter 13. Integrity
&lt;a class="heading-anchor" href="#chapter-13-integrity" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Small Cycles&lt;/li>
&lt;li>Relentless Improvement&lt;/li>
&lt;li>Maintain High Productivity&lt;/li>
&lt;/ul>
&lt;h4 id="chapter-14-teamwork">Chapter 14. Teamwork
&lt;a class="heading-anchor" href="#chapter-14-teamwork" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Work as a Team&lt;/li>
&lt;li>Estimate Honestly and Fairly&lt;/li>
&lt;li>Respect&lt;/li>
&lt;li>Never Stop Learning&lt;/li>
&lt;/ul>
&lt;hr />
&lt;p>I found this chat in YouTube where Uncle Bob talks about most of the topics form his book &lt;strong>Clean Craftsmanship&lt;/strong>.&lt;/p>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/sPXk11hrWTM"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="plain">&lt;span class="giallo-l">&lt;span>Listen out for:&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Quote &amp;amp; Intro - [00:00:00]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Career Journey - [00:07:29]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Clean Craftsmanship - [00:10:53]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Programmer as a Profession - [00:15:31]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Craftsmanship - [00:18:45]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Disciplines - [00:22:45]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Disciplines: Test-Driven Development - [00:28:49]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Disciplines: Refactoring - [00:34:31]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Code Coverage - [00:39:02]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Standard: Never Ship S**t - [00:42:35]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Standard: Always Be Ready - [00:47:15]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Ethics: Do No Harm - [00:50:00]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Ethics: Estimate Honestly - [00:53:56]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* 2 Tech Lead Wisdom - [00:57:50]&lt;/span>&lt;/span>&lt;/code>&lt;/pre></content></entry><entry xml:lang="en"><title>The Path to Seniority in Software</title><subtitle>How to become a Senior Software Developer?</subtitle><category term="career" scheme="https://chemaclass.com/tags/career/" label="Career"/><category term="mentoring" scheme="https://chemaclass.com/tags/mentoring/" label="Mentoring"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><category term="communication" scheme="https://chemaclass.com/tags/communication/" label="Communication"/><published>2022-06-08T00:00:00+00:00</published><updated>2022-06-08T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/the-path-to-seniority-in-software/"/><id>https://chemaclass.com/blog/the-path-to-seniority-in-software/</id><summary type="html">Real seniority goes beyond job titles. It's about impact, mentoring others, owning outcomes, and raising the bar for your entire team.</summary><content type="html">&lt;p>We all have been junior developers at some point. This is easy to know because it sits at the very beginning of your
career. Your responsibilities were narrowed down by other peers who were looking after you.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>At some point, after months or years, you got your promotion or another job, where you weren’t a junior
anymore, but an intermediate.&lt;/p>
&lt;p>An intermediate (also known as middle) is something between junior and senior. You know now that you are not a junior
anymore, you know how to deliver value but yet you also have mixed feelings about seniority. You want to be a senior,
but you don’t know how. There is no clear path to achieving this goal.&lt;/p>
&lt;p>Wait for a second… there are actually two easy ways to get the senior title! You can get promoted as such in your
company, or you can start a new position as a “senior” in another company, easy right?&lt;/p>
&lt;h2 id="marketing-and-politics">Marketing and politics
&lt;a class="heading-anchor" href="#marketing-and-politics" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Unfortunately, the “seniority” level is very much polluted by marketing and politics. First, what
does it mean “senior” in this context? In all the companies where I have been working (if not all) I have always been
surrounded by people who claimed to be “seniors” when in reality only a few I would consider such.&lt;/p>
&lt;p>Our senior label is inflated by companies needing experts on paper more than in reality, and this is a
problem we need to deal with and speak about.&lt;/p>
&lt;p>Seniority generally means more experience, but how do you calculate this? It is easy from a company’s point of view:
more years in the industry. But, is the number of years you have been working really relevant in an industry that is
constantly changing and evolving? Actually, this wouldn’t be a big issue if you have the software fundamentals
well interiorized, but funny enough, I have seen these fundamentals in only ~10% of the seniors I have met across many
years and several companies.&lt;/p>
&lt;p>The fact that you have been working for 10 or more years doesn’t necessarily mean you are a “senior” with software.
What else can we measure in order to identify if you deserve indeed this title?&lt;/p>
&lt;h3 id="it-is-not-all-about-the-money">It is not all about the money
&lt;a class="heading-anchor" href="#it-is-not-all-about-the-money" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Let us be honest, senior titles are better paid than junior or middle positions. If you have the chance to get a higher
salary because you got the “senior” in your job title, well, it wouldn’t be clever to reject it. But, independently of
politics and marketing, we must address some seniority fundamentals to understand better what the word “senior” means in
this context.&lt;/p>
&lt;blockquote>
&lt;p>It is not all about the money, but also about the responsibilities that come with seniority.&lt;/p>
&lt;/blockquote>
&lt;h2 id="seniority-fundamentals">Seniority fundamentals
&lt;a class="heading-anchor" href="#seniority-fundamentals" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Being senior in our software industry is not about “the number of years of experience” but:&lt;/p>
&lt;ul>
&lt;li>How well do you &lt;strong>transmit your knowledge&lt;/strong> to others? Sharing what you know is a core task for a senior person.&lt;/li>
&lt;li>How well do you &lt;strong>collaborate&lt;/strong> with other people, including the PM/PO and other teams? Collaboration is crucial
to creating a constant feedback loop.&lt;/li>
&lt;li>How well do you &lt;strong>work together&lt;/strong> with your peers? Pair-programming builds team cohesion and helps everyone become
better.&lt;/li>
&lt;li>How strong are your &lt;strong>testing&lt;/strong> skills? Testing is tied to the quality of your work, and a senior should aim
for an incremental design.&lt;/li>
&lt;li>How well do you understand &lt;strong>delivering value constantly&lt;/strong> in small chunks? The sooner you deliver value, the
sooner you get feedback about it.&lt;/li>
&lt;li>How deep is your &lt;strong>technical knowledge&lt;/strong> of quality software and the trade-offs to get there?
SOLID principles, clean code, TDD, refactoring as part of your daily job, low coupling, high cohesion, appropriate
data structures, and choosing the right solution (KISS, YAGNI…).&lt;/li>
&lt;li>How well do you adapt and &lt;strong>cope with change&lt;/strong>? Change is inevitable, so we must learn to
deal with it, especially the parts we cannot control.&lt;/li>
&lt;li>How developed is your &lt;strong>entrepreneurial thinking&lt;/strong>? Always keeping the organization’s goals in mind.&lt;/li>
&lt;/ul>
&lt;p>As you can see, there is no mention of concrete technology or years of experience. Why? Because technology is just an
“implementation detail”, and experience comes by practicing and attitude, not by letting the time pass by.&lt;/p>
&lt;h3 id="attitude-is-important">Attitude is important
&lt;a class="heading-anchor" href="#attitude-is-important" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>We’ve got two persons:&lt;/p>
&lt;p>A) a person who is working for 15 years, doing relatively the same every day, and without caring about his own skills.
He just does what others tell him to do.&lt;/p>
&lt;p>B) a person who is working for 5 years, challenging herself every week, trying different approaches when dealing with
problems, and sharpening her own skills constantly.&lt;/p>
&lt;p>Can you see the main difference? No, it’s not the 10 years difference of “experience” between them, but their &lt;strong>attitude&lt;/strong>.&lt;/p>
&lt;p>We wrongly understand that &lt;em>a year of experience must come with learning and knowledge&lt;/em>, so we tend to use time as a
measurement of seniority. But I argue that the “attitude factor” is equal or even more important. I have been surrounded
by many people who call themselves seniors with 3, 6, 10, and more years of “experience” but lacking attitude, and you
could clearly see this problem on a daily basis.&lt;/p>
&lt;blockquote>
&lt;p>You need this combination to build yourself as a truly senior developer; time, experience, and most importantly:
attitude towards &lt;strong>improving your own skills and the ones that surround you&lt;/strong>.&lt;/p>
&lt;/blockquote>
&lt;h2 id="where-to-start">Where to start
&lt;a class="heading-anchor" href="#where-to-start" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Seniority is not granted, it is practiced. You don’t wait for the title, you build the behavior until the title catches
up. Start small, and start now:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Teach what you know.&lt;/strong> Pick one thing you understand and explain it to someone this week. If you can’t explain it,
you don’t own it yet.&lt;/li>
&lt;li>&lt;strong>Seek the uncomfortable.&lt;/strong> Volunteer for the task slightly beyond you. Growth lives at the edge of what you can
already do.&lt;/li>
&lt;li>&lt;strong>Reflect on purpose.&lt;/strong> After each project, ask what you would do differently. Experience without reflection is just
repetition.&lt;/li>
&lt;/ul>
&lt;p>The path is not a promotion. It is the daily decision to improve yourself and the people around you. Do that long
enough, and the title becomes a formality.&lt;/p></content></entry><entry xml:lang="en"><title>To Mock or Not to Mock</title><subtitle>How to escape the mocking hell</subtitle><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><published>2021-01-11T00:00:00+00:00</published><updated>2021-01-11T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/to-mock-or-not-to-mock/"/><id>https://chemaclass.com/blog/to-mock-or-not-to-mock/</id><summary type="html">Mocking is useful, but 'what to mock' usually turns out to be a more complicated than expected if you don't treat this carefully.</summary><content type="html">&lt;p>Mocking is useful, but “what to mock” usually turns out to be more complicated than expected if you don’t treat
this carefully.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h4 id="how-to-escape-the-mocking-hell">How to escape the mocking hell
&lt;a class="heading-anchor" href="#how-to-escape-the-mocking-hell" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;p>What is actually happening when we create a mock? Which types of mocks are there? Is mocking good or bad? Well, as
always, everything depends on the context. And here we will consider some of the main situations about when to mock and
when not to mock, but especially why.&lt;/p>
&lt;h2 id="what-happens-when-you-mock-something">What happens when you mock something?
&lt;a class="heading-anchor" href="#what-happens-when-you-mock-something" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>First, we should define what is a mock:&lt;/p>
&lt;blockquote>
&lt;p>In a unit test, mock objects can simulate the behavior of complex, real objects and are therefore useful when it is impractical or impossible to incorporate a real object into a unit test.&lt;/p>
&lt;/blockquote>
&lt;p>Mocking makes sense in a &lt;em>unit testing&lt;/em> context. An integration test should go through the real implementation checking
the integration between multiple units, which are even allowed to talk to the DB or File IO: infrastructure code.
Therefore we should agree that &lt;em>a unit test is a fast and deterministic test that doesn’t rely on external dependencies
and doesn’t require any special context to run&lt;/em>.&lt;/p>
&lt;p>Mock objects meet the &lt;em>interface&lt;/em> requirements. In consequence, they allow us to write and unit-test functionality
without calling complex underlying or collaborating classes.&lt;/p>
&lt;p>A mock is a test double that stands in for real implementation code during the unit testing process. It is also capable
of producing assertions about how it was manipulated by the test subject during the test run.&lt;/p>
&lt;blockquote>
&lt;p>I strongly recommend you to read this post if you want to get into the details of why &lt;a rel="external" href="https://medium.com/javascript-scene/mocking-is-a-code-smell-944a70c90a6a">Mocking is a code smell&lt;/a> (Topics like these: What is a mock? What is a unit test? What is test coverage? What is tight coupling? What causes tight coupling? What does composition have to do with mocking? How do we remove coupling? and more!)&lt;/p>
&lt;/blockquote>
&lt;h2 id="the-problem-with-mocking">The problem with mocking
&lt;a class="heading-anchor" href="#the-problem-with-mocking" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>When you mock you are overriding the logic of the mocked class. The real logic is getting hidden behind the scenes and
there is actually where bugs love to live. Consider that:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>The mock may have attributes, methods, or arguments that the real object doesn’t.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The mock’s &lt;em>return values may differ from the real objects’ return values&lt;/em>. For example, it may return a different
type of object that has different attributes.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The mock’s &lt;em>side effects and behavior may differ from the real objects’ ones&lt;/em>. For example, maybe the mock fails to
raise an exception when the real object would raise it.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="alternatives-to-mocking">Alternatives to mocking
&lt;a class="heading-anchor" href="#alternatives-to-mocking" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>“Are you saying that mocking is bad and we shouldn’t mock?!” No.&lt;/p>
&lt;p>It depends on what you are “overriding”.&lt;/p>
&lt;ul>
&lt;li>Is your business domain logic what you are mocking? Then it’s wrong.&lt;/li>
&lt;li>Is the connection to the DB what you are mocking? Then it’s right.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>It depends on the context of the logic and where that logic belongs.&lt;/p>
&lt;/blockquote>
&lt;p>Is it part of your business domain logic? Then you shouldn’t mock it but instantiate it.&lt;/p>
&lt;p>Is it part of any infrastructure dependency like DB connection, IO file system, Network, or any external service that
has nothing to do directly with your business domain? Then &lt;em>mock it using abstractions/interfaces&lt;/em>.&lt;/p>
&lt;p>The interface should be the &lt;em>contract between your business domain logic and its external infrastructure dependencies&lt;/em>.
Imagine how easy it would be to unit test your domain logic by instantiating it and calling their methods with different
arguments expecting different inputs under your entire control.&lt;/p>
&lt;h2 id="some-tricks">Some tricks
&lt;a class="heading-anchor" href="#some-tricks" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>When you are writing a unit test:&lt;/p>
&lt;ul>
&lt;li>Try to instantiate your classes first.&lt;/li>
&lt;li>Avoid mocking concrete classes. I wrote an article exclusively about this:
encouraging &lt;a rel="external" href="https://medium.com/swlh/final-classes-in-php-9174e3e2747e">final classes&lt;/a> and interfaces.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>Mock interfaces. Instantiate concrete classes.&lt;/p>
&lt;/blockquote>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/RbSqXFUfRMU"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div>
&lt;p>“Excessive use of mocks leads to legacy code.” - Philippe Boargau&lt;/p>
&lt;h3 id="how-can-we-avoid-excessive-mocking">How can we avoid excessive mocking?
&lt;a class="heading-anchor" href="#how-can-we-avoid-excessive-mocking" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Favor immutable state over a mutable state.&lt;/li>
&lt;li>Make dependencies explicit.&lt;/li>
&lt;li>Program to an interface, not to an implementation.&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="/images/blog/2021-01-11/footer.webp" alt="mock interfaces, instantiate concrete classes" />&lt;/p>
&lt;hr />
&lt;h4 id="references">References
&lt;a class="heading-anchor" href="#references" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>&lt;a rel="external" href="https://medium.com/javascript-scene/mocking-is-a-code-smell-944a70c90a6a">Mocking is a code smell&lt;/a> - Eric Elliott&lt;/li>
&lt;li>&lt;a rel="external" href="https://blog.cleancoder.com/uncle-bob/2014/05/10/WhenToMock.html">When to mock&lt;/a> &amp;amp; &lt;a rel="external" href="https://blog.cleancoder.com/uncle-bob/2017/05/05/TestDefinitions.html">Test Definitions&lt;/a> - Uncle Bob&lt;/li>
&lt;li>&lt;a rel="external" href="https://matthiasnoback.nl/2018/09/final-classes-by-default-why/">Final classes by default&lt;/a> - Matthias Noback&lt;/li>
&lt;li>&lt;a rel="external" href="https://www.seanh.cc/2017/03/17/the-problem-with-mocks/">The problem with mocks&lt;/a> - Sean Hammond&lt;/li>
&lt;li>&lt;a rel="external" href="https://www.artima.com/weblogs/viewpost.jsp?thread=126923">A Set of Unit Testing Rules&lt;/a> - Michael Feathers&lt;/li>
&lt;/ul></content></entry><entry xml:lang="en"><title>Principles of package design</title><subtitle>Creating Reusable Software Components</subtitle><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="architecture" scheme="https://chemaclass.com/tags/architecture/" label="Architecture"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><published>2020-11-12T00:00:00+00:00</published><updated>2020-11-12T00:00:00+00:00</updated><author><name>
Matthias Noback</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/readings/packaging-design/"/><id>https://chemaclass.com/readings/packaging-design/</id><summary type="html">Apply design principles to your classes, preparing them for reuse. You will use package design principles to create packages that are just right in terms of cohesion and coupling, and are user- and maintainer-friendly at the same time.</summary><content type="html">&lt;span id="continue-reading">&lt;/span>
&lt;p>Apply design principles to your classes, preparing them for reuse. You will use package design principles to create
packages that are just right in terms of cohesion and coupling, and are user- and maintainer-friendly at the same time.&lt;/p>
&lt;p>The first part of this book walks you through the five SOLID principles that will help you improve the design of your
classes. The second part introduces you to the best practices of package design, and covers both package cohesion
principles and package coupling principles. Cohesion principles show you which classes should be put together in a
package, when to split packages, and if a combination of classes may be considered a “package” in the first place.
Package coupling principles help you choose the right dependencies and prevent wrong directions in the dependency graph
of your packages.&lt;/p>
&lt;h3 id="what-you-ll-learn">What You’ll Learn
&lt;a class="heading-anchor" href="#what-you-ll-learn" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Apply the SOLID principles of class design&lt;/li>
&lt;li>Determine if classes belong in the same package&lt;/li>
&lt;li>Know whether it is safe for packages to depend on each other&lt;/li>
&lt;/ul></content></entry><entry xml:lang="en"><title>Never Use array_merge in a Loop</title><subtitle>The spread operator to the rescue</subtitle><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><published>2020-11-10T00:00:00+00:00</published><updated>2020-11-10T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/array-merge-in-loop/"/><id>https://chemaclass.com/blog/array-merge-in-loop/</id><summary type="html">Using array_merge inside a loop is a performance killer. The spread operator will help you to improve this by flatting the array.</summary><content type="html">&lt;p>Using array_merge inside a loop is a performance killer.
The spread operator will help you to improve this by flatting the array.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="flattening-a-one-level-array">Flattening a one-level array
&lt;a class="heading-anchor" href="#flattening-a-one-level-array" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>I have seen people using the array_merge function in a loop like:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 2&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">3&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 4&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">5&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 6&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>merged&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">foreach&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> as&lt;/span>&lt;span> $&lt;/span>&lt;span>list&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> $&lt;/span>&lt;span>merged&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> array_merge&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>merged&lt;/span>&lt;span>,&lt;/span>&lt;span> $&lt;/span>&lt;span>list&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">//&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> $merged === [1, 2, 3, 4, 5, 6];&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>This is a very bad practice because it’s a (memory) performance killer!
Instead, you should use the spread operator (in PHP since 5.6!):&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 2&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">3&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 4&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">5&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 6&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>merged&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> array_merge&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">...&lt;/span>&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">//&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> === [1, 2, 3, 4, 5, 6];&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h2 id="unpacking-an-assoc-array">Unpacking an assoc-array
&lt;a class="heading-anchor" href="#unpacking-an-assoc-array" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>What if you had an assoc-array instead like this one?&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-1&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 2&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-2&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">3&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 4&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-3&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">5&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 6&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>In that case, you will need to unpack its values:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>merged&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> array_merge&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">...&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">array_values&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">//&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> === [1, 2, 3, 4, 5, 6];&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>In Functional Programming, this is known as flatting a list.
No loops &amp;amp; no more performance problem.&lt;/p>
&lt;h2 id="flatting-a-multilevel-array">Flatting a multilevel array
&lt;a class="heading-anchor" href="#flatting-a-multilevel-array" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>What if you wanted to flat a multilevel array like this one?&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 2&lt;/span>&lt;span>,&lt;/span>&lt;span> [&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">3&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 4&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 5&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;span> [&lt;/span>&lt;span>[&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span>]&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;span> [&lt;/span>&lt;span>[&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">6&lt;/span>&lt;span>]&lt;/span>&lt;span>]&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 7&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 8&lt;/span>&lt;span>,&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Or like this one, even with key-values?&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-1&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 1&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">2&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-2&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 3&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-3&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">4&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 5&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> ]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> ]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> ]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 6&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-4&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">7&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 8&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>In these cases, you might want to use the internal standard library:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>merged&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> iterator_to_array&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> RecursiveIteratorIterator&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> RecursiveArrayIterator&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> $&lt;/span>&lt;span>use_keys&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> false&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">//&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> $merged === [1, 2, 3, 4, 5, 6, 7, 8];&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h2 id="which-flattening-approach-to-reach-for">Which flattening approach to reach for
&lt;a class="heading-anchor" href="#which-flattening-approach-to-reach-for" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Usually, being aware of how to flat a “2 level” array might be sufficient:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>flattenList&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> array_merge&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">...&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">array_values&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Otherwise, the internal standard library will help you deal with it.&lt;/p>
&lt;hr />
&lt;h3 id="references">References
&lt;a class="heading-anchor" href="#references" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;a rel="external" href="https://wiki.php.net/rfc/spread_operator_for_array">Spread_operator_for_array - Wikipedia&lt;/a>&lt;/li>
&lt;li>&lt;a rel="external" href="https://rosettacode.org/wiki/Flatten_a_list">Flatten_a_list - Rosettacode&lt;/a>&lt;/li>
&lt;/ul></content></entry><entry xml:lang="en"><title>Typed Arrays in PHP</title><subtitle>An alternative to the missing feature in PHP: Generics</subtitle><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><published>2020-10-13T00:00:00+00:00</published><updated>2020-10-13T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/typed-arrays-php/"/><id>https://chemaclass.com/blog/typed-arrays-php/</id><summary type="html">Argument unpacking, function variable argument list, and variadics function.</summary><content type="html">&lt;p>Argument unpacking, function variable argument list, and variadics function.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h3 id="the-perfect-combination">The perfect combination
&lt;a class="heading-anchor" href="#the-perfect-combination" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Argument unpacking: Instead of passing the argument itself to the function, the elements it contains will be passed (as individual arguments).&lt;/li>
&lt;li>Function variable argument list: The arguments will be passed into the given variable as an array.&lt;/li>
&lt;li>Variadics function: Types can be checked with a type-hint.&lt;/li>
&lt;/ul>
&lt;p>We will use this snippet for our examples.
Having a class, &lt;code>Customer&lt;/code>:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">/**&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> &lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> * @psalm-immutable &lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> */&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">final&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> class&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> Customer&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> Using PHP 8 constructor property promotion&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> https://wiki.php.net/rfc/constructor_promotion&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> __construct&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> string&lt;/span>&lt;span> $&lt;/span>&lt;span>name&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span> {&lt;/span>&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">//&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> We create a list of 6 customers&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>customers&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> array_map&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> fn&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">int&lt;/span>&lt;span> $&lt;/span>&lt;span>i&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Customer&lt;/span>&lt;span> =&amp;gt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Customer&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">name-&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">{&lt;/span>&lt;span>$&lt;/span>&lt;span>i&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">}&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> range&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 6&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Whenever we want to manipulate a list of Customers, we can pass as an argument: &lt;code>…$customers&lt;/code>.&lt;/p>
&lt;h2 id="how-we-used-to-do-it">How we used to do it
&lt;a class="heading-anchor" href="#how-we-used-to-do-it" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>We define the array type using the PHPDoc param comment block above. But we cannot define the real type of the item. The code will still run without any problem passing any type on that argument &lt;code>array $customers&lt;/code>:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">/**&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> &lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> * &lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">@param&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Customer&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">[]&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> &lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> */&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">array&lt;/span>&lt;span> $&lt;/span>&lt;span>customers&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> void&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> foreach&lt;/span>&lt;span> (&lt;/span>&lt;span>$&lt;/span>&lt;span>customers&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> as&lt;/span>&lt;span> $&lt;/span>&lt;span>customer&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... some irrelevant logic for this example&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>The code below would work at “compile-time”. But it might fail at “runtime”.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>customers&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Customer&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">any name&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>)&lt;/span>&lt;span>]&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> AnyOtherType&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>]&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>An alternative (recommended!) might be to extract that logic and ask for the particular type in order to “check it” at runtime in that particular moment, failing if one of the items wasn’t really a Customer:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">/**&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> &lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> * &lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">@param&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Customer&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">[]&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> &lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> */&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">array&lt;/span>&lt;span> $&lt;/span>&lt;span>customers&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> void&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> foreach&lt;/span>&lt;span> (&lt;/span>&lt;span>$&lt;/span>&lt;span>customers&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> as&lt;/span>&lt;span> $&lt;/span>&lt;span>customer&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> createInvoice&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>customer&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> createInvoice&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">Customer&lt;/span>&lt;span> $&lt;/span>&lt;span>customer&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> void&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... some irrelevant logic for this example&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Everything here below would work at “compile-time”. It will for sure break during “runtime” if the &lt;code>createInvoice(Customer $customer)&lt;/code> receives something different than a Customer.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>customers&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Customer&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">any name&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>)&lt;/span>&lt;span>]&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> AnyOtherType&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>]&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> won&amp;#39;t work&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>By doing that &lt;code>createInvoice(Customer $customer)&lt;/code> we are ensuring the type of the argument, which is good! But, what about going one step further. Could we check the types of the elements when calling the function &lt;code>createInvoiceForCustomers(array $customers)&lt;/code>, even making the IDE complain when the types are not right?&lt;/p>
&lt;p>Well, that’s actually what Generics are for, but sadly, they are not yet in PHP. Not even in the upcoming PHP 8. Hopefully in a near future, but we cannot predict that for now.
Luckily, we have currently an alternative nowadays, but it’s not that popular. It has its own “pros” and “cons”, so let’s take a look at an example first:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">Customer&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> ...&lt;/span>&lt;span>$&lt;/span>&lt;span>customers&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> void&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> foreach&lt;/span>&lt;span> (&lt;/span>&lt;span>$&lt;/span>&lt;span>customers&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> as&lt;/span>&lt;span> $&lt;/span>&lt;span>customer&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> createInvoice&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>customer&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Everything here below would work at “compile-time”. It will for sure break during “runtime” if the &lt;code>createInvoice()&lt;/code> receives something different than a Customer.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">...&lt;/span>&lt;span>$&lt;/span>&lt;span>customers&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> OK&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Customer&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">any name&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;span> &lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Customer&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">any name&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> OK&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">//&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> This is not even possible to write. The IDE will yell at you. &lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">//&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> It&amp;#39;s expecting a `Customer`, but `AnyOtherType` is given:&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> AnyOtherType&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="pros">PROS
&lt;a class="heading-anchor" href="#pros" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>We can easily type a list of any concrete type.&lt;/li>
&lt;/ul>
&lt;h3 id="cons">CONS
&lt;a class="heading-anchor" href="#cons" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>We better define our functions with one or two arguments max. Otherwise, it would be too complicated to read.&lt;/li>
&lt;/ul>
&lt;h3 id="important-remarks">Important remarks
&lt;a class="heading-anchor" href="#important-remarks" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>It needs to be the last taken argument of a function.&lt;/li>
&lt;li>It helps to minimize the number of arguments that we use in a function.&lt;/li>
&lt;/ul>
&lt;h2 id="variadics-simulate-typed-arrays-use-them-wisely">Variadics simulate typed arrays, use them wisely
&lt;a class="heading-anchor" href="#variadics-simulate-typed-arrays-use-them-wisely" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Argument unpacking is a great feature that, in combination with variadic functions, can help us to simulate typed arrays. With great power comes great responsibility, and this is no exception.
We need to learn about our toolbox in order to use it wisely.&lt;/p>
&lt;p>&lt;img src="/images/blog/2020-10-13/footer.webp" alt="typed arrays with variadics in php" />&lt;/p>
&lt;hr />
&lt;h3 id="references">References
&lt;a class="heading-anchor" href="#references" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;a rel="external" href="https://wiki.php.net/rfc/argument_unpacking">Argument unpacking&lt;/a>&lt;/li>
&lt;li>&lt;a rel="external" href="https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list">Function variable argument list&lt;/a>&lt;/li>
&lt;li>&lt;a rel="external" href="https://wiki.php.net/rfc/variadics">Variadics function&lt;/a>&lt;/li>
&lt;/ul></content></entry><entry xml:lang="en"><title>Object design style guide</title><subtitle>Powerful Techniques for Creating Flexible, Readable, and Maintainable Object-Oriented Code in Any OO Language</subtitle><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><published>2020-10-10T00:00:00+00:00</published><updated>2020-10-10T00:00:00+00:00</updated><author><name>
Matthias Noback</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/readings/object-design-style-guide/"/><id>https://chemaclass.com/readings/object-design-style-guide/</id><summary type="html">Matthias Noback's practical guide to writing flexible, readable, and maintainable object-oriented code, with techniques applicable to any OO language from Python to PHP.</summary><content type="html">&lt;p>Objects are the central concept of languages like Java, Python, C#. Applying best practices for object design means that
your code will be easy to read, write, and maintain.&lt;/p>
&lt;p>This book captures dozens of techniques for creating pro-quality OO code that can stand the
test of time.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>Examples are in an instantly-familiar pseudocode, teaching techniques you can apply to any OO language, from C++ to PHP.&lt;/p></content></entry><entry xml:lang="en"><title>Testing Effectively Legacy Code</title><subtitle>How to write proper tests to already written code</subtitle><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><published>2020-08-17T00:00:00+00:00</published><updated>2020-08-17T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/testing-effectively-legacy-code/"/><id>https://chemaclass.com/blog/testing-effectively-legacy-code/</id><summary type="html">How to write characterization tests for legacy code to safely refactor without breaking existing behavior.</summary><content type="html">&lt;p>These tests are also known as Characterization tests.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;blockquote>
&lt;p>A characterization test describes the actual behavior of an existing piece of software, and therefore protects existing
behavior of legacy code against unintended changes via automated testing. This term was coined by &lt;a href="/readings/working-effectively-with-legacy-code/">Michael Feathers&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;p>They enable and provide a safety net for extending and refactoring code that does not have adequate tests. A test can be
written that asserts that the output of the legacy code matches the observed result for the given inputs.&lt;/p>
&lt;h2 id="how-to-start">How to start?
&lt;a class="heading-anchor" href="#how-to-start" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>These are my learnings one year after
reading &lt;a href="/readings/working-effectively-with-legacy-code/">Working Effectively with Legacy Code&lt;/a> and applying it to the
different projects I’ve been working on since then.&lt;/p>
&lt;h3 id="1-what-do-you-want-to-test">1. What do you want to test?
&lt;a class="heading-anchor" href="#1-what-do-you-want-to-test" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Find out the assertions. Create a test file for your class, and a testing method for the function that you want to test.
Hint:&lt;/p>
&lt;ul>
&lt;li>If you have the following method &lt;code>applySomeLogic(): ReturnType&lt;/code>,&lt;/li>
&lt;li>the test you could write is &lt;code>test_apply_some_logic(): void&lt;/code>.&lt;/li>
&lt;/ul>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">final&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> class&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> MyBusinessLogic&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> private&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> DependencyInterface&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> dependencyInterface&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> private&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> ConcreteDependency&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> concrete&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> __construct&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> DependencyInterface dependencyInterface&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> ConcreteDependency concrete&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> this&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">dependencyInterface&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> dependencyInterface&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> this&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">concrete&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> concrete&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> applySomeLogic&lt;/span>&lt;span>(&lt;/span>&lt;span>Input input&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> ReturnType&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> black box responsible to create a ReturnType&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> based on the given Input&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> return&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> returnType&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">final&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> class&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> MyBusinessLogicTest&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> extends&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> TestCase&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> test_apply_some_logic&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> void&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> I want to assert that &amp;quot;applying some logic&amp;quot;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> from MyBusinessLogic with the given Input&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> I will receive a concrete ReturnType with a &lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> certain value as its property. Something like:&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> &lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> returnType&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">applySomeLogic&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">input&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> assertEquals&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">expected&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> returnType&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">getProperty&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="2-instantiate-the-concrete-final-class-that-you-want-to-test">2. Instantiate the concrete/final class that you want to test.
&lt;a class="heading-anchor" href="#2-instantiate-the-concrete-final-class-that-you-want-to-test" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Do not mock your concrete classes. Especially your business domain. Mock only interfaces. Otherwise, you can be hiding
bugs unintentionally (with green/passing tests!). Treat your &lt;a href="/blog/final-classes">business domain classes as final&lt;/a>.&lt;/p>
&lt;p>Either mock the interface or instantiate an anonymous class if you want to create a Stub:&lt;/p>
&lt;blockquote>
&lt;p>Stubs provide answers to calls made during the test, usually not responding to anything outside what’s programmed in for the test.&lt;/p>
&lt;/blockquote>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">final&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> class&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> MyBusinessLogicTest&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> extends&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> TestCase&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> test_apply_some_logic&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> void&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> MyBusinessLogic&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> this&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">createMock&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">DependencyInterface&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">class&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> ConcreteDependency&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">/*&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> OR&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> MyBusinessLogic&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> FakeDependency&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> ConcreteDependency&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">/*&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ...&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;blockquote>
&lt;p>Where &lt;code>FakeDependency&lt;/code> is a concrete implementation of &lt;code>DependencyInterface&lt;/code> with already “fake data/implementation” that it’s useful only for testing purposes.&lt;/p>
&lt;/blockquote>
&lt;h3 id="3-call-the-method-from-that-class-providing-the-desired-input">3. Call the method from that class providing the desired input.
&lt;a class="heading-anchor" href="#3-call-the-method-from-that-class-providing-the-desired-input" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>The output will be determined by the initial state of the business logic class that we want to test PLUS the input
arguments that we are using.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);">input&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Input&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">/*&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);">returnType&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">applySomeLogic&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">input&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="4-assert-the-output-with-the-expected-value">4. Assert the output with the expected value.
&lt;a class="heading-anchor" href="#4-assert-the-output-with-the-expected-value" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>From step-1 you need to know what you want. Apply the assertion(s) now.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">final&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> class&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> MyBusinessLogicTest&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> extends&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> TestCase&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> test_apply_some_logic&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> void&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> MyBusinessLogic&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> this&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">createMock&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">DependencyInterface&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">::&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">class&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> ConcreteDependency&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">/*&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> input&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Input&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">/*&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> returnType&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">applySomeLogic&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">input&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> assertEquals&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">expected&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> returnType&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">getProperty&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="5-you-might-want-to-assert-different-expected-values">5. You might want to assert different expected values.
&lt;a class="heading-anchor" href="#5-you-might-want-to-assert-different-expected-values" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>You can easily provide different arguments to your business logic either via the logic construction or different given
arguments. To do so, use the @dataProvider annotation. The “dataProvider” method must be public and return any iterable.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">final&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> class&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> MyBusinessLogicTest&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> extends&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> TestCase&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> /**&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> @dataProvider providerApplySomeLogic &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> test_apply_some_logic&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> array concreteMapping&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> string argInput&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> string expectedValue&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> void&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> MyBusinessLogic&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> this&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">createMock&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">DependencyInterface&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">class&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> ConcreteDependency&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">concreteMapping&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> /*&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> input&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Input&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">argInput&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> /*&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> actual&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">applySomeLogic&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">input&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> assertEquals&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>expectedValue&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> actual&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">getProperty&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> providerApplySomeLogic&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Generator&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> yield&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">concreteMapping&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">value&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">argInput&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">something&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">expectedValue&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">expected-value-A&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> ]&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> yield&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">concreteMapping&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key2&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">value2&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">argInput&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">something-else&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">expectedValue&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">expected-value-B&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> ]&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="lastly-clean-what-you-did">Lastly: clean what you did.
&lt;a class="heading-anchor" href="#lastly-clean-what-you-did" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Yes, clean the tests. They deserve to be as clean as your production code. Otherwise, they will rot as time passes by and
remain dirty for your colleagues and your future self!&lt;/p>
&lt;p>For example, you can apply extract method refactoring to move out the implementation details (of the creation of the
different objects) and keep the same abstraction level while reading the test code.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);">myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> this&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">createBusinessLogic&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">concreteMapping&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);">input&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> this&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">createInput&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">argInput&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);">actual&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">applySomeLogic&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">input&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">assertEquals&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">expectedValue&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> actual&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">getProperty&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Of course, everything depends on the context. Does it really make sense to extract into a private method the
createBusinessLogic() or even createInput()? Well, that’s up to you. It depends on the number of lines and, most
importantly, the abstraction level that belongs to that context.&lt;/p>
&lt;blockquote>
&lt;p>Just remember: keep your methods small.&lt;/p>
&lt;/blockquote>
&lt;p>Now you can refactor the production code that you covered with tests without that fear of breaking it.&lt;/p>
&lt;hr />
&lt;h3 id="all-together">All together
&lt;a class="heading-anchor" href="#all-together" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;script src="https://gist.github.com/Chemaclass&amp;#x2F;07704606fcb337dbb0881c94197c329e.js">&lt;/script>
&lt;script src="https://gist.github.com/Chemaclass&amp;#x2F;9f7f96242153b696b3f8da5c7fa80461.js">&lt;/script>
&lt;hr />
&lt;h2 id="legacy-code-is-code-without-tests">Legacy Code is code without tests
&lt;a class="heading-anchor" href="#legacy-code-is-code-without-tests" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>&lt;img src="/images/blog/2020-08-17/footer.jpg" alt="legacy code is code without tests" />&lt;/p>
&lt;p>Of course, there is way more to learn
about &lt;a href="/readings/working-effectively-with-legacy-code/">testing and working with legacy code&lt;/a>. In fact, especially when
dealing with legacy code, you will encounter situations where the code is coupled somehow that you might want to mock
your concrete classes because there is no interface (yet) for it.&lt;/p>
&lt;p>This book presents to you a lot of techniques about when, why, where, and how you can apply these changes.&lt;/p>
&lt;blockquote>
&lt;p>When working with code you need &lt;strong>feedback&lt;/strong>. Automated feedback is the best. Thus, this is the first thing you need to do: write the tests.&lt;/p>
&lt;/blockquote>
&lt;h3 id="first-add-tests-then-do-your-changes">First, add tests, then do your changes.
&lt;a class="heading-anchor" href="#first-add-tests-then-do-your-changes" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;h4 id="change-as-little-code-as-possible-to-get-tests-in-place-with-the-recipe">Change as little code as possible to get tests in place with the recipe:
&lt;a class="heading-anchor" href="#change-as-little-code-as-possible-to-get-tests-in-place-with-the-recipe" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ol>
&lt;li>Identify “change points” to break your code dependencies.&lt;/li>
&lt;li>Break dependencies.&lt;/li>
&lt;li>Write the tests.&lt;/li>
&lt;li>Make your changes.&lt;/li>
&lt;li>Refactor.&lt;/li>
&lt;/ol>
&lt;hr />
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/wRtJRkRIa2s"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div></content></entry><entry xml:lang="en"><title>Strict Types in PHP</title><subtitle>declare(strict_types=1);</subtitle><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><published>2020-08-09T00:00:00+00:00</published><updated>2020-08-09T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/strict-types/"/><id>https://chemaclass.com/blog/strict-types/</id><summary type="html">Why declaring strict_types in PHP improves code readability and prevents silent type coercion bugs.</summary><content type="html">&lt;p>In December 2015, PHP 7 introduced scalar type declarations and with it the strict types flag. What is this new feature?&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>The good thing about declaring a PHP file as strict is that it actually applies to &lt;strong>ONLY the current file&lt;/strong>. It ensures that this file has strict types, but it doesn’t apply to any other file in the whole project. It allows you to do, step by step, this migration from non-strict code to strict code, especially for new files or projects.&lt;/p>
&lt;blockquote>
&lt;p>To enable the strict mode, a single declare directive must be placed at the top of the file. This means that the strictness of typing for scalars is configured on a per-file basis. This directive not only affects the type declarations of parameters, but also a function’s return type.&lt;/p>
&lt;/blockquote>
&lt;h2 id="strict-types-affect-coercion-types">Strict types affect coercion types
&lt;a class="heading-anchor" href="#strict-types-affect-coercion-types" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Using a type hint without &lt;code>strict_types&lt;/code> may lead to subtle bugs.&lt;/p>
&lt;p>Without this, &lt;code>int $x&lt;/code> meant &lt;code>$x must have a value coercible to an int&lt;/code>. Any value that could be coerced to an int would pass the hint type, including:&lt;/p>
&lt;ul>
&lt;li>a proper &lt;code>int&lt;/code> (example: 42 -&amp;gt; 42)&lt;/li>
&lt;li>a &lt;code>float&lt;/code> (example: 13.1459 -&amp;gt; 13)&lt;/li>
&lt;li>a &lt;code>bool&lt;/code> (example: true -&amp;gt; 1)&lt;/li>
&lt;li>a &lt;code>null&lt;/code> (example: null -&amp;gt; 0)&lt;/li>
&lt;li>a &lt;code>string&lt;/code> with leading digits (example: “15 Trees” -&amp;gt; 15)&lt;/li>
&lt;/ul>
&lt;p>By setting &lt;code>strict_types=1&lt;/code>, you tell the engine that int $x means $x must only be an int proper, no type coercion allowed. You have the great assurance you’re getting exactly and only what was given, without any conversion or potential loss.&lt;/p>
&lt;h2 id="who-should-care-about-this-strict-type-line">Who should care about this “strict type” line?
&lt;a class="heading-anchor" href="#who-should-care-about-this-strict-type-line" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Actually, declare(strict_types=1); is more for the reader than for the writer. Why? Because it will explicitly tell the reader:&lt;/p>
&lt;ul>
&lt;li>The types in this current scope (file/class) are treated strictly.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>‘strict_types=1’ is more for the reader than for the writer&lt;/p>
&lt;/blockquote>
&lt;p>The writer just needs to maintain such strictness while writing the expected behavior. That said, as a writer, you should care about your readers, which also includes your future self. Because you are going to be one of them.&lt;/p>
&lt;p>&lt;img src="/images/blog/2020-08-09/footer.webp" alt="strict_types declaration in php" />&lt;/p>
&lt;hr />
&lt;h2 id="references">References
&lt;a class="heading-anchor" href="#references" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;ul>
&lt;li>&lt;a rel="external" href="https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.scalar-type-declarations">Scalar type declarations&lt;/a>&lt;/li>
&lt;li>&lt;a rel="external" href="https://stackoverflow.com/questions/48723637/what-do-strict-types-do-in-php/48723830#48723830">What do strict types do in PHP&lt;/a>&lt;/li>
&lt;/ul></content></entry><entry xml:lang="en"><title>The Art of Refactoring</title><subtitle>When, how, and why</subtitle><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><published>2020-06-28T00:00:00+00:00</published><updated>2020-06-28T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/the-art-of-refactoring/"/><id>https://chemaclass.com/blog/the-art-of-refactoring/</id><summary type="html">If you see something, in the scope of your current task, that can be easily improved, improve it. And if you have any questions about it, ask.</summary><content type="html">&lt;p>If you see something, in the scope of your current task, that can be easily improved, improve it. And if you have any questions about it, ask.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="what-is-refactoring">What is refactoring?
&lt;a class="heading-anchor" href="#what-is-refactoring" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Refactoring means improving your code. It can go from making a variable name more readable, extract some lines of code into a private method, or separate the responsibilities of a class into subclasses, for example.&lt;/p>
&lt;p>Refactoring is the action of showing that you care about what you do as a professional. It can be a controversial topic; it is indeed one of the major controversial topics since a long time ago. But we shouldn’t stop trying our best in order to improve the quality of the system just because of that controversiality.&lt;/p>
&lt;h2 id="when-and-how-should-we-refactor">When and how should we refactor?
&lt;a class="heading-anchor" href="#when-and-how-should-we-refactor" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Always. In the scope of your current task unless it is an already planned task, something like “architecture refactoring” or similar, where the scope of the task is actually to do refactoring.&lt;/p>
&lt;blockquote>
&lt;p>Refactoring should be part of our daily job, not a separate task by default.&lt;/p>
&lt;/blockquote>
&lt;p>We do not need to ask permission to refactor. Or do we ask our managers for permission to do our best job?&lt;/p>
&lt;p>In order to do proper refactoring, the intention of such refactoring needs to be clear. What is intended to achieve and how? Pair programming (or even pair thinking!) certainly helps in this topic because it syncs two brains on the same topic and that encourages team building and a better understanding of them.&lt;/p>
&lt;p>Applying refactoring in a collaborative way, in a “bidirectional channel”, is fundamental when working within a team. Refactoring shouldn’t be a taboo topic, on the contrary: it will be helpful in order to unify the goals and the direction of the team code quality.&lt;/p>
&lt;h3 id="some-personal-advice-about-the-how">Some personal advice about the “how”
&lt;a class="heading-anchor" href="#some-personal-advice-about-the-how" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Continuous improvement is what we’re looking for within this topic, but…&lt;/p>
&lt;ul>
&lt;li>If you realize your changes are generating more noise than help, stop immediately and think again if your changes are worth it in the current system status.&lt;/li>
&lt;/ul>
&lt;p>Maybe it’s not the right moment for that refactoring.&lt;/p>
&lt;p>Maybe you are polluting your current diff with out-scoped changes.&lt;/p>
&lt;p>Or, maybe, your refactoring idea is too big to be applied in your current task. In such a case, a follow-up task (in order to apply the refactoring) would be a better idea.&lt;/p>
&lt;ul>
&lt;li>If you see that refactoring is perhaps needed even before starting your current task, do the refactoring first.&lt;/li>
&lt;/ul>
&lt;p>We usually refactor in order to increase our productivity, making the code more readable and therefore easier to understand.&lt;/p>
&lt;h3 id="testing">Testing
&lt;a class="heading-anchor" href="#testing" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Be aware that you should have a pretty good suite of tests covering the logic that you might have changed. Without tests, refactoring can be really risky. Usually, the easier something is to be tested, the easier it is to be replaced or removed.&lt;/p>
&lt;p>You can read more about how testing is related to quality here.&lt;/p>
&lt;h2 id="why-should-we-do-it">Why should we do it?
&lt;a class="heading-anchor" href="#why-should-we-do-it" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Wouldn’t you want to have a better system as time goes by?&lt;/p>
&lt;p>Software isn’t like wine: it doesn’t get better as time passes by. Therefore, if you want to have a better system you must work for it.&lt;/p>
&lt;p>&lt;img src="/images/blog/2020-06-28/footer.webp" alt="refactoring as continuous improvement" />&lt;/p></content></entry><entry xml:lang="en"><title>Final Classes in PHP | Java | Any</title><subtitle>Final, or not final, that's the question</subtitle><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><published>2020-06-06T00:00:00+00:00</published><updated>2020-06-06T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/final-classes/"/><id>https://chemaclass.com/blog/final-classes/</id><summary type="html">Clear contracts, isolated side effects, testability, low complexity and cognitive load, code fluidity, and confidence in yourself.</summary><content type="html">&lt;p>Clear contracts, isolated side effects, testability, low complexity and cognitive load, code fluidity, and confidence in yourself.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="motivation">Motivation
&lt;a class="heading-anchor" href="#motivation" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;h3 id="reduce-the-scope-visibility-to-the-minimum">Reduce the scope visibility to the minimum
&lt;a class="heading-anchor" href="#reduce-the-scope-visibility-to-the-minimum" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>When you see a class prefixed with final you will prevent a particular class to be extended by any other, which not only makes it more readable but also makes you be sure that the scope of the logic where you are is limited to that particular class.&lt;/p>
&lt;h3 id="encourage-composition-over-inheritance-mentality">Encourage “composition over inheritance” mentality
&lt;a class="heading-anchor" href="#encourage-composition-over-inheritance-mentality" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>The Open-Close Principle states: open for extension but closed for modification.&lt;/p>
&lt;p>If for any reason, a good one you should be completely aware of, you decide to create an inheritance there, well, then just drop the final keyword and you are good to go.&lt;/p>
&lt;p>When you “by default” can’t extend from a class (because it’s final), you will help yourself by thinking about using composition instead of inheritance.&lt;/p>
&lt;h2 id="why-isn-t-this-class-final">Why isn’t this class final?
&lt;a class="heading-anchor" href="#why-isn-t-this-class-final" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>If we aim for composition over inheritance, then we should try to avoid inheritance as much as possible, and use it only when it’s really necessary. Inheritance is often misused in OOP.&lt;/p>
&lt;h3 id="misconception">Misconception
&lt;a class="heading-anchor" href="#misconception" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>When we first taught OOP, we usually introduced the classic inheritance example.&lt;/p>
&lt;p>Nonetheless, when Alan Kay created Smalltalk, the inheritance was never the main concept of it. The main concept was messaging, which is that you can send messages to objects and they encapsulate the data and logic in it, and you can change their behavior by using different objects, which is actually composition. But the concept of inheritance is so popular that it eventually overshadows composition.&lt;/p>
&lt;h3 id="benefits">Benefits
&lt;a class="heading-anchor" href="#benefits" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Clear contracts. Using interfaces will force you to think in terms of communication between objects.&lt;/li>
&lt;li>Isolated, side effect free code units. Injecting interfaces only as dependencies will remove every nasty side effect around the code you are working on.&lt;/li>
&lt;li>Testability. Mocking dependencies is extremely easy when they are interfaces.&lt;/li>
&lt;li>Low, manageable complexity. Since everything is isolated, you won’t need to worry about rippling changes. This dramatically decreases the complexity of your code.&lt;/li>
&lt;li>Low cognitive load. With decreased complexity, your brain will be free to focus on what matters.&lt;/li>
&lt;li>Code fluidity. By removing any unnecessary coupling, you will be able to move things around way more easily than before.&lt;/li>
&lt;li>Confidence in yourself. Being able to test your code in isolation so well will give you a wonderful sense of confidence in changing it.&lt;/li>
&lt;/ul>
&lt;h2 id="composition-over-inheritance">Composition over inheritance
&lt;a class="heading-anchor" href="#composition-over-inheritance" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>If you feel the need to reconfigure an object, to change parts of an algorithm, or to rewrite part of the implementation, consider creating a new class instead of overriding an existing class.
If you need to represent a hierarchy of classes, where subclasses are proper substitutes for their parent classes. This would be the classic situation where you may still consider inheritance. However, the result may even be better if you don’t inherit from concrete parent classes but from abstract interfaces.&lt;/p>
&lt;h3 id="what-you-should-start-doing-instead">What you should start doing instead
&lt;a class="heading-anchor" href="#what-you-should-start-doing-instead" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Use interfaces to define the contracts between your classes.&lt;/li>
&lt;li>Use final classes to implement behavior for those interfaces.&lt;/li>
&lt;li>Use composition (using dependency injection through constructor) to put things together and prevent complexity.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>Interfaces -&amp;gt; Final classes -&amp;gt; Composition&lt;/p>
&lt;/blockquote>
&lt;p>&lt;img src="/images/blog/2020-06-06/footer.webp" alt="interfaces, final classes and composition" />&lt;/p></content></entry><entry xml:lang="en"><title>The Art of Testing: Where Design Meets Quality</title><subtitle>From a software developer's point of view</subtitle><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><published>2020-04-07T00:00:00+00:00</published><updated>2020-04-07T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/the-art-of-testing/"/><id>https://chemaclass.com/blog/the-art-of-testing/</id><summary type="html">Why you should consider testing as part of your daily development habit and how it's directly linked to the software quality.</summary><content type="html">&lt;p>Why you should consider testing as part of your daily development habit and how it’s directly linked to the software
quality.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>This post intends not to explain the different testing techniques that we can use. I’m not going to tell you the differences between unit, integration, feature, or end-to-end testing.&lt;/p>
&lt;p>I’m still amazed by the lack of experience with testing in software in general. Common ignorance in this world about
best testing practices for us as developers. Inexperience that you can easily see if you have already worked on
different projects and teams.&lt;/p>
&lt;h3 id="software-testing">Software testing
&lt;a class="heading-anchor" href="#software-testing" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Some horrible patterns I’ve seen (and done):&lt;/p>
&lt;ul>
&lt;li>Testing for the sake of testing: testing every single file, sometimes wrongly considered a unit.&lt;/li>
&lt;li>Mocking every class we intend to test, overriding the actual implementation, and creating a fake behavior,
providing a false coverage perception.&lt;/li>
&lt;li>Coupling production code with tests everywhere, so it’s impossible to change anything without breaking some tests,
even if the feature itself it’s working as intended.&lt;/li>
&lt;li>Not testing at all because “why should we even test anything if the feature is done, and it works? Why should we
spend more time on this if it’s done?.”&lt;/li>
&lt;/ul>
&lt;p>One of the main reasons for software testing is actually verifying a suite of proofs for the expected behavior of the
final software piece. However, testing can (and should) be more than that.&lt;/p>
&lt;h3 id="software-design">Software design
&lt;a class="heading-anchor" href="#software-design" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Software design goes from algorithm to architecture design. Even when I believe these two levels of components have
different needs and requirements, they still share some common patterns. For example, testing, and this is what we are
going to talk about right now:&lt;/p>
&lt;blockquote>
&lt;p>If it’s easy to test, it will likely be because of good design.&lt;/p>
&lt;/blockquote>
&lt;h3 id="software-quality">Software quality
&lt;a class="heading-anchor" href="#software-quality" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Is quality hard to measure out? Indeed. There are different measurement keys that we should take while considering
quality for any piece of software. Still, I’m sure we could agree on this:&lt;/p>
&lt;blockquote>
&lt;p>If you aim for quality in your software, you better seek a good design.&lt;/p>
&lt;/blockquote>
&lt;p>Testing by itself means “proving,” as we all know. That said… how difficult it sometimes turns to prove some logic
that we finally give up because of its complexity itself?&lt;/p>
&lt;p>The art of testing is about using testing itself to help and contribute to the final result. To encourage good design,
suppose we’re able to use testing (of any kind) in our favor, depending on the context of what we want to prove. In that
case, it will undoubtedly help us increase the product’s end quality.&lt;/p>
&lt;p>Therefore, testing should be used not only to prove the behavior of our software but also to guide our software to a better design.&lt;/p>
&lt;p>Should we test everything? Well, that’s the million-dollar question. In my opinion, everything depends on the context. We
might encounter situations where tests might not be beneficial. Even in those situations, we should write our code as if
it could be tested anyway.&lt;/p>
&lt;p>&lt;img src="/images/blog/2020-04-07/footer.webp" alt="testable code and good design" />&lt;/p>
&lt;blockquote>
&lt;p>Testable code tends to better design and, therefore, better quality.&lt;/p>
&lt;/blockquote></content></entry><entry xml:lang="en"><title>Clean Architecture</title><subtitle>A Craftsman's Guide to Software Structure and Design</subtitle><category term="architecture" scheme="https://chemaclass.com/tags/architecture/" label="Architecture"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="ddd" scheme="https://chemaclass.com/tags/ddd/" label="Ddd"/><published>2018-06-04T00:00:00+00:00</published><updated>2018-06-04T00:00:00+00:00</updated><author><name>
Robert C. Martin</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/readings/clean-architecture/"/><id>https://chemaclass.com/readings/clean-architecture/</id><summary type="html">Robert C. Martin's guide to SOLID principles, component design, and architectural boundaries that keep software systems flexible, testable, and maintainable over time.</summary><content type="html">&lt;span id="continue-reading">&lt;/span>&lt;h3 id="code-design-principles-solid">Code design principles (SOLID)
&lt;a class="heading-anchor" href="#code-design-principles-solid" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Single Responsibility&lt;/strong>: a class should have one, and only one, reason to change. Or the new version: a module
should be responsible to one, and only one, actor.&lt;/li>
&lt;li>&lt;strong>Open-closed&lt;/strong>: a class should be open for extension but closed for modification.&lt;/li>
&lt;li>&lt;strong>Liskov’s Substitution&lt;/strong>: objects in a program should be replaceable with instances of their subtypes without
altering the correctness of that program.&lt;/li>
&lt;li>&lt;strong>Interface Segregation&lt;/strong>: many client-specific interfaces are better than one general-purpose interface.&lt;/li>
&lt;li>&lt;strong>Dependency Inversion&lt;/strong> : one should depend upon abstractions, not concretions.&lt;/li>
&lt;/ul>
&lt;h3 id="component-principles">Component principles
&lt;a class="heading-anchor" href="#component-principles" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;h4 id="component-cohesion">Component cohesion
&lt;a class="heading-anchor" href="#component-cohesion" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>&lt;strong>Reuse/Release Equivalence&lt;/strong> Principle: classes and modules (i.e. a component) reused together should be released
together. They should have the same version number and there should be proper documentation such as changelogs.&lt;/li>
&lt;li>&lt;strong>Common Closure&lt;/strong> Principle: classes that change together should be grouped together, and vice versa. The single
responsibility principle at component-level.&lt;/li>
&lt;li>&lt;strong>Common Reuse&lt;/strong> Principle: don’t force users of a component to depend on things they don’t need. The Interface
Segregation Principle at component-level.&lt;/li>
&lt;/ul>
&lt;h4 id="component-coupling">Component coupling
&lt;a class="heading-anchor" href="#component-coupling" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>&lt;strong>Acyclic Dependencies&lt;/strong> Principle: no cycle in the dependency graph. Cycles couple components and, among other
things, force them to be to released together. Use the dependency inversion principle to break cycles.&lt;/li>
&lt;li>&lt;strong>The Stable Dependency&lt;/strong> Principle: less stable components should depend on more stable components. Depend on the
direction of stability.&lt;/li>
&lt;li>&lt;strong>Stable Abstractions&lt;/strong> Principle: stable components should be abstract, and vice versa. An example of an abstract
stable component is a high-level policy which is changed by extension following the open-closed principle.&lt;/li>
&lt;/ul>
&lt;h3 id="architecture-principles">Architecture principles
&lt;a class="heading-anchor" href="#architecture-principles" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;h4 id="setting-boundaries">Setting boundaries
&lt;a class="heading-anchor" href="#setting-boundaries" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;p>Boundaries are lines that separate software elements. They separate things that matter from things that don’t, i.e.
high-level components from low-level components. If a high-level component depends on a low-level component at the
source level, changes in the low-level components will spread to the high-level component. Therefore, we place a
boundary between the two, using polymorphism to invert the logic flow. This is the Dependency Inversion Principle in the
SOLID principles.&lt;/p>
&lt;h4 id="separating-layers">Separating layers
&lt;a class="heading-anchor" href="#separating-layers" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;p>We can identify four main layers, although the number may vary:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Entities&lt;/strong>: objects containing critical business logic. For example, a bank could establish that no loans are
granted to customers not satisfying some credit score requirements. Entities may be shared across apps in the same
enterprise.&lt;/li>
&lt;li>&lt;strong>Use-cases&lt;/strong>: app-specific business rules. For example, the sequence of screens to execute a bank transfer.&lt;/li>
&lt;li>&lt;strong>Interface adapters&lt;/strong>: Gateways, presenters and controllers. For example, this layer will contain the MVC
architecture of the GUI and also objects that transform data between the format of the database and the use-cases.&lt;/li>
&lt;li>&lt;strong>Frameworks and drivers&lt;/strong>: web frameworks, database, the view of MVC.&lt;/li>
&lt;/ul></content></entry><entry xml:lang="en"><title>The Pragmatic Programmer</title><subtitle>The journey to mastery</subtitle><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><category term="career" scheme="https://chemaclass.com/tags/career/" label="Career"/><published>2016-10-01T00:00:00+00:00</published><updated>2016-10-01T00:00:00+00:00</updated><author><name>
Andrew Hunt</name></author><author><name>
David Thomas</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/readings/the-pragmatic-programmer/"/><id>https://chemaclass.com/readings/the-pragmatic-programmer/</id><summary type="html">Key takeaways from Hunt and Thomas's classic on pragmatic software development, including DRY principles, the right mindset, and how to choose and master your tools.</summary><content type="html">&lt;span id="continue-reading">&lt;/span>&lt;h3 id="takeaways">Takeaways
&lt;a class="heading-anchor" href="#takeaways" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Don’t Repeat Yourself.&lt;/li>
&lt;li>Mindset is as important as knowledge.&lt;/li>
&lt;li>Good code is easier to change than bad design.&lt;/li>
&lt;li>Choose great tools and become fluent with them.&lt;/li>
&lt;/ul>
&lt;hr />
&lt;h4 id="don-t-repeat-yourself-dry">Don’t Repeat Yourself (DRY)
&lt;a class="heading-anchor" href="#don-t-repeat-yourself-dry" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.&lt;/li>
&lt;li>DRY is about the duplication of knowledge, of intent. It’s about expressing the same thing in two different places,
possibly in two totally different ways.&lt;/li>
&lt;/ul>
&lt;h4 id="mindset-is-as-important-as-knowledge">Mindset is as important as knowledge
&lt;a class="heading-anchor" href="#mindset-is-as-important-as-knowledge" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;p>Some important aspects of this mindset include:&lt;/p>
&lt;ul>
&lt;li>Taking responsibility for your work by not making excuses or passing blame when things go wrong.&lt;/li>
&lt;li>Writing software that’s good enough. This means not wasting time on things that are better than they need to be to
make the product successful.&lt;/li>
&lt;li>Not ignoring technical debt. The authors use the analogy of broken windows:&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>Don’t leave “broken windows” (bad designs, wrong decisions, or poor code) unrepaired.
Fix each one as soon as it is discovered. If there is insufficient time to fix it properly, then board it up.
Perhaps you can comment out the offending code, or display a “Not Implemented” message, or substitute dummy data instead.&lt;/p>
&lt;/blockquote></content></entry><entry xml:lang="en"><title>The Clean Coder</title><subtitle>A Code of Conduct for Professional Programmers</subtitle><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="career" scheme="https://chemaclass.com/tags/career/" label="Career"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><category term="communication" scheme="https://chemaclass.com/tags/communication/" label="Communication"/><published>2016-08-01T00:00:00+00:00</published><updated>2016-08-01T00:00:00+00:00</updated><author><name>
Robert C. Martin</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/readings/the-clean-coder/"/><id>https://chemaclass.com/readings/the-clean-coder/</id><summary type="html">Robert C. Martin's guide to professional behavior in software development, covering time management, pressure handling, TDD practices, and what it truly means to be a software craftsman.</summary><content type="html">&lt;p>Programmers who endure and succeed amidst swirling uncertainty and nonstop pressure share a common attribute: They care
deeply about the practice of creating software. They treat it as a craft. They are professionals.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h3 id="readers-will-learn">Readers will learn
&lt;a class="heading-anchor" href="#readers-will-learn" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>What it means to behave as a true software craftsman&lt;/li>
&lt;li>How to deal with conflict, tight schedules, and unreasonable managers&lt;/li>
&lt;li>How to get into the flow of coding, and get past writer’s block&lt;/li>
&lt;li>How to handle unrelenting pressure and avoid burnout&lt;/li>
&lt;li>How to combine enduring attitudes with new development paradigms&lt;/li>
&lt;li>How to manage your time, and avoid blind alleys, marshes, bogs, and swamps&lt;/li>
&lt;li>How to foster environments where programmers and teams can thrive&lt;/li>
&lt;li>When to say &lt;strong>No&lt;/strong> and how to say it&lt;/li>
&lt;li>When to say &lt;strong>Yes&lt;/strong> and what yes really means&lt;/li>
&lt;/ul>
&lt;hr />
&lt;h2 id="summary">Summary
&lt;a class="heading-anchor" href="#summary" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;h3 id="chapter-1-professionalism">Chapter 1: Professionalism
&lt;a class="heading-anchor" href="#chapter-1-professionalism" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Being a professional means taking full responsibility for one’s actions.&lt;/li>
&lt;li>First rule is not doing harm to the function nor the structure of the software.&lt;/li>
&lt;li>You will always make occasional mistakes, but you must learn from each.&lt;/li>
&lt;li>You should be certain about all code you release and firmly expect QA to find nothing wrong with it.
&lt;ul>
&lt;li>Test it and test it again.&lt;/li>
&lt;li>Automate your tests.&lt;/li>
&lt;li>Design your code to be easy to test.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>You should follow the Boy Scout rule and always leave a module a little cleaner than you found it so that it becomes
easier to change over time, not harder.&lt;/li>
&lt;li>Your career is &lt;strong>your responsibility&lt;/strong>, not your boss nor your employers.
&lt;ul>
&lt;li>Spending 20 hours a week beyond your normal work to improve your knowledge and skills.&lt;/li>
&lt;li>Read, experiment, practice (kata), talk to other, collaborate, look over the fence, mentor.&lt;/li>
&lt;li>It should be fun.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Also, know your domain, identify with your customer (no “us vs. them”, ever).&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-2-saying-no">Chapter 2: Saying No
&lt;a class="heading-anchor" href="#chapter-2-saying-no" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Professionals have the courage to say no to their managers.&lt;/li>
&lt;li>Managers and developers have roles that are often adversarial, because on the short term, their goals tend to
conflict.&lt;/li>
&lt;li>The higher the stakes, the more valuable a “no” becomes, and the harder to say.&lt;/li>
&lt;li>Good teams will successfully work towards a yes, but only a right yes, that will later work out in practice.&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-3-saying-yes">Chapter 3: Saying Yes
&lt;a class="heading-anchor" href="#chapter-3-saying-yes" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>There are three parts to making a commitment:
&lt;ul>
&lt;li>You say you will do it&lt;/li>
&lt;li>You mean it&lt;/li>
&lt;li>You actually do it&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Your commitment must respect the limits of what you expect (based on your experience) you can and cannot do.
&lt;ul>
&lt;li>If you recognize you will probably not be able to meet a commitment, you need to raise a red flag immediately.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-4-coding">Chapter 4: Coding
&lt;a class="heading-anchor" href="#chapter-4-coding" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Programming requires a level of focus that few other disciplines require.&lt;/li>
&lt;li>“The zone” (or “flow”) is not as good as people think: you will be locally productive, but will often lose the bigger
picture and possibly product not-so-good designs.&lt;/li>
&lt;li>Interruptions are bad distractions.
&lt;ul>
&lt;li>Pair programming is helpful to cope with them.&lt;/li>
&lt;li>TDD helps to make the pre-interruption context reproducible.
&lt;ul>
&lt;li>Minimize time spent debugging&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Coding is a &lt;strong>marathon&lt;/strong>, not a sprint, so conserve the energy and creativity.&lt;/li>
&lt;li>Leave when it’s time, even in the middle of something important.&lt;/li>
&lt;li>Continuously re-estimate your best/likely/worst completion time and speak up as soon as you recognize you will likely
be late.
&lt;ul>
&lt;li>Do not allow anyone to rush you.&lt;/li>
&lt;li>Use a proper definition of “done”, with sufficiently high quality requirements.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Programming is too hard for anyone, so get help and provide help to others, in particular (but not only) in mentoring
style.
&lt;ul>
&lt;li>Don’t be shy from asking.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-5-test-driven-development">Chapter 5: Test-Driven Development
&lt;a class="heading-anchor" href="#chapter-5-test-driven-development" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;a rel="external" href="https://en.wikipedia.org/wiki/Test-driven_development">TDD&lt;/a> is not a cure-all and is impractical or inappropriate in
some (rare) cases.&lt;/li>
&lt;li>TDD Cycle:
&lt;ol>
&lt;li>Add a test&lt;/li>
&lt;li>Run all tests. The new test should fail for expected reasons&lt;/li>
&lt;li>Write the simplest code that passes the new test&lt;/li>
&lt;li>All tests should now pass&lt;/li>
&lt;li>Refactor as needed&lt;/li>
&lt;li>Repeat&lt;/li>
&lt;/ol>
&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-6-practicing">Chapter 6: Practicing
&lt;a class="heading-anchor" href="#chapter-6-practicing" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>A programming Kata is a precise set of choreographed keystrokes and mouse movements that simulates the solving of some
programming problem.
&lt;ul>
&lt;li>A Kata is about the process, not the solution.&lt;/li>
&lt;li>You aren’t solving the problem because you already know the solution.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-7-acceptance-testings">Chapter 7: Acceptance Testings
&lt;a class="heading-anchor" href="#chapter-7-acceptance-testings" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Avoid garbage in, garbage out. Make sure you understand the requirements.
&lt;ul>
&lt;li>Creating this understanding means removing ambiguity.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>The best way to do this is defining acceptance tests:
&lt;ul>
&lt;li>All customer’s conditions need to be fulfilled by automated tests to prove the expected software behavior.&lt;/li>
&lt;li>Success of those tests constitutes the definition of “Done”.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Code implementation should start only when the tests are complete.&lt;/li>
&lt;li>Unlike unit tests (which are only for programmers), the audience of acceptance tests are both: business and
developers.&lt;/li>
&lt;li>Run all tests in a continuous integration and immediately fix any failures.&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-8-test-strategies">Chapter 8: Test Strategies
&lt;a class="heading-anchor" href="#chapter-8-test-strategies" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Consider QA part of the team. They act as specifiers: writing acceptance tests, including the failure cases and corner
cases, and perform exploratory testing.&lt;/li>
&lt;li>Testing pyramid:
&lt;ul>
&lt;li>Most tests are unit tests. By developer and for developers.&lt;/li>
&lt;li>Many tests are component or integration tests. By QA or Business assisted by Developers. For Business and
Developers.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-9-time-management">Chapter 9: Time management
&lt;a class="heading-anchor" href="#chapter-9-time-management" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Management roles in software development requires good time management.&lt;/li>
&lt;li>Meeting are necessary but are also often huge time wasters, so avoid meeting that have no clear benefit &amp;lt;- this is a
professional obligation.&lt;/li>
&lt;li>Meeting must have an agenda and a clear goal.
&lt;ul>
&lt;li>Agile stand up meetings can be an efficient format.&lt;/li>
&lt;li>Iteration planning should take 5% of the iteration.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Concentration (focus) is a scarce resource.
&lt;ul>
&lt;li>Use it well when present and recharge with simpler tasks (meetings) and breaks in between.&lt;/li>
&lt;li>How to improve?
&lt;ul>
&lt;li>Sport.&lt;/li>
&lt;li>Creative input.&lt;/li>
&lt;li>Short breaks every 45 minutes.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-10-estimation">Chapter 10: Estimation
&lt;a class="heading-anchor" href="#chapter-10-estimation" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Estimation is the source of most distrust between business people and developers because the latter provide estimate
which the former treats like commitments.
&lt;ul>
&lt;li>Both are insufficiently aware that the estimate really is a probability distribution, not a fixed number.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-11-pressure">Chapter 11: Pressure
&lt;a class="heading-anchor" href="#chapter-11-pressure" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>The professional developer is calm and decisive under pressure, adhering to his training and disciplines, knowing that
they are the best way to meet pressing deadlines and commitments.&lt;/li>
&lt;li>Avoid situations that cause pressure via:
&lt;ul>
&lt;li>make only commitments you can fulfill&lt;/li>
&lt;li>keep your code clean&lt;/li>
&lt;li>work in such a way that you need not change it when in crisis&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Don’t panic. Talk with your team. Don’t rush. Trust your disciplines.&lt;/li>
&lt;li>Offer to pair to others in crisis.&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-12-collaboration">Chapter 12: Collaboration
&lt;a class="heading-anchor" href="#chapter-12-collaboration" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Not all but most programmers like working alone. But we need to understand the goals of the surrounding people,
including business folks.
&lt;ul>
&lt;li>This requires &lt;strong>communication&lt;/strong>.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Likewise, within the development team: only collective code ownership and pairing produce a good level of
communication.
&lt;ul>
&lt;li>Programming is all about &lt;strong>communication&lt;/strong>.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-13-teams-and-projects">Chapter 13: Teams and Projects
&lt;a class="heading-anchor" href="#chapter-13-teams-and-projects" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Teams need time (months) to gel, to really get to know each other and learn to truly work together.
&lt;ul>
&lt;li>Assigning fractional people to different projects is a bad idea, as is breaking up a good team at the end of a
project.&lt;/li>
&lt;li>Instead, assigning several projects to one team can work well.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-14-mentoring-apprenticeship-and-craftsmanship">Chapter 14: Mentoring, Apprenticeship and Craftsmanship
&lt;a class="heading-anchor" href="#chapter-14-mentoring-apprenticeship-and-craftsmanship" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Young programmers need mentoring.
&lt;ul>
&lt;li>Mentoring can be implicit or explicit.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Given that we entrust software with all aspects of our lives, a reasonable period of training and supervised practice
would be appropriate.&lt;/li>
&lt;/ul>
&lt;hr />
&lt;p>In this lesson, Uncle Bob demonstrates the need to write a clean code and establishes the bases to achieve it,
being these bases of a social and scientific nature. Making it clear that the future of programming is based on an
ethical and polite code.&lt;/p>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/7EmboKQH8lM"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div>
&lt;hr />
&lt;p>In this second lesson, Uncle Bob teaches us the purpose of comments in the code, breaking the paradigm that commenting
is something “I have to do” for the simple fact that we mistakenly consider that commenting is a good practice. For
Uncle Bob, writing a comment is a sign of failure, since a good code must be able explain by itself: Fewer Comments =
Better Code.&lt;/p>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/2a_ytyt9sf8"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div>
&lt;hr />
&lt;p>In this third lesson, Uncle Bob focuses on raising awareness, given the need to increase the level of criteria in code
production. Pointing to the lack of preparation in most programmers, as one of the main reasons for the inefficiency in
software development today.&lt;/p>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/Qjywrq2gM8o"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div>
&lt;hr />
&lt;p>In this fourth lesson, Uncle Bob introduces us to a software development methodology oriented through testing. This is
the Test-Driven Development (TDD), a practice with a long learning curve, but with significant results to generate a
more robust, safer, more maintainable code and with greater development efficiency.&lt;/p>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/58jGpV2Cg50"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div></content></entry><entry xml:lang="en"><title>97 Things Every Programmer Should Know</title><subtitle>Collective whisdom from the experts</subtitle><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="career" scheme="https://chemaclass.com/tags/career/" label="Career"/><category term="productivity" scheme="https://chemaclass.com/tags/productivity/" label="Productivity"/><published>2016-07-15T00:00:00+00:00</published><updated>2016-07-15T00:00:00+00:00</updated><author><name>
Kevlin Henney</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/readings/97-things-every-programmer-should-know/"/><id>https://chemaclass.com/readings/97-things-every-programmer-should-know/</id><summary type="html">Tap into the wisdom of experts to learn what every programmer should know, no matter what language you use. With the 97 short and extremely useful tips for programmers in this book, you'll expand your skills by adopting new approaches to old problems, learning appropriate best practices, and honing your craft through sound advice.</summary><content type="html">&lt;p>Tap into the wisdom of experts to learn what every programmer should know, no matter what language you use. With the 97
short and extremely useful tips for programmers in this book, you’ll expand your skills by adopting new approaches to
old problems, learning appropriate best practices, and honing your craft through sound advice.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h3 id="my-main-key-takeaways">My main key takeaways
&lt;a class="heading-anchor" href="#my-main-key-takeaways" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>01.- Pay off technical debt as soon as possible.&lt;/p>
&lt;p>02.- Learn and master &lt;strong>functional programming&lt;/strong>.&lt;/p>
&lt;ul>
&lt;li>It makes your code less prone to error and easier to debug.&lt;/li>
&lt;/ul>
&lt;p>03.- Don’t guess what a user would do; get users to do things and watch them.&lt;/p>
&lt;p>04.- &lt;strong>Automate&lt;/strong> coding standards.&lt;/p>
&lt;p>05.- Write &lt;strong>simple&lt;/strong> code, simple descriptive names, simple relationships.&lt;/p>
&lt;p>06.- Before you refactor: consider the existing tests and code.&lt;/p>
&lt;ul>
&lt;li>Work in increments, make sure the tests still pass after every change.&lt;/li>
&lt;/ul>
&lt;p>08.- Always leave code &lt;strong>cleaner&lt;/strong> than you found it, even if you didn’t write it.&lt;/p>
&lt;p>10.- Choose your libraries/frameworks carefully to avoid unnecessary complexity.&lt;/p>
&lt;p>11.- Make your code easy to understand using &lt;strong>domain&lt;/strong> terms.&lt;/p>
&lt;p>13.- The &lt;strong>layout&lt;/strong> of the code is also important.&lt;/p>
&lt;p>14.- Use code &lt;strong>reviews&lt;/strong> focusing on knowledge-sharing among team members.&lt;/p>
&lt;p>15.- Objects &lt;strong>immutable&lt;/strong> whenever relevant. Each variable should have the smallest possible scope. Never include more than four function arguments.&lt;/p>
&lt;p>18.- Take &lt;strong>responsibility&lt;/strong> for your own education and never stop learning.&lt;/p>
&lt;ul>
&lt;li>That can be done with just a bit of time each week and there are many ways to go about it (e.g. podcasts, lessons, books, etc.).&lt;/li>
&lt;/ul>
&lt;p>19.- When designing an API, aim to make it &lt;strong>easy to use&lt;/strong>, not convenient to code.&lt;/p>
&lt;p>20.- Deploy early and &lt;strong>often&lt;/strong>. Do not leave it until the end of the project.&lt;/p>
&lt;p>22.- Improving your skills should be on your daily basis.&lt;/p>
&lt;p>23.- Adapt the technical level of your domain-specific language to your audience.&lt;/p>
&lt;p>24.- &lt;strong>Don’t be afraid&lt;/strong> to break things if that’s what’s necessary to fix things.&lt;/p>
&lt;p>25.- Careful with your test data because that might go public accidentally.&lt;/p>
&lt;p>26.- Handle your errors as they appear, don’t leave it for later.&lt;/p>
&lt;p>27.- Learn &lt;strong>different&lt;/strong> programming languages.&lt;/p>
&lt;ul>
&lt;li>Learn their own “culture” or way of doing things.&lt;/li>
&lt;li>It’ll make you definitely a better programmer.&lt;/li>
&lt;/ul>
&lt;p>28.- Don’t just catch your errors, really handle them.&lt;/p>
&lt;p>29.- Understand at least some complexities of your business, not just programming.&lt;/p>
&lt;p>30.- &lt;strong>DRY&lt;/strong>: Don’t Repeat Yourself.&lt;/p>
&lt;p>32.- Encapsulate behavior, not just state.&lt;/p>
&lt;p>33.- Floating point numbers inevitably can create errors in calculations.&lt;/p>
&lt;p>34.- &lt;strong>Open source&lt;/strong> is a great opportunity to do interesting work and develop programming skills.&lt;/p>
&lt;p>36.- Give proper &lt;strong>context&lt;/strong> when asking for help, because people can’t just guess what’s going on.&lt;/p>
&lt;p>37.- It’s not about the long hours. Learn to &lt;strong>work effectively&lt;/strong>.&lt;/p>
&lt;ul>
&lt;li>Dedicate time to continuous learning and to think about what you’re doing.&lt;/li>
&lt;/ul>
&lt;p>38.- Write proper &lt;strong>bug reports&lt;/strong>:&lt;/p>
&lt;ul>
&lt;li>Precisely how to reproduce the bug,&lt;/li>
&lt;li>how often it appears,&lt;/li>
&lt;li>what should have happened,&lt;/li>
&lt;li>what actually happened.&lt;/li>
&lt;/ul>
&lt;p>39.- Don’t write unnecessary code.&lt;/p>
&lt;ul>
&lt;li>Only write code that adds value and is needed right now.&lt;/li>
&lt;li>&lt;strong>Remove dead code&lt;/strong>.&lt;/li>
&lt;/ul>
&lt;p>41.- The main cause of delays in application response time is a high number of remote &lt;strong>interprocess&lt;/strong> communications, not the algorithm.&lt;/p>
&lt;ul>
&lt;li>DB connections, for example.&lt;/li>
&lt;/ul>
&lt;p>42.- If a compiler warning shows up in your build, fix it.&lt;/p>
&lt;ul>
&lt;li>Don’t leave it for later. Even if it’s not going to be a problem in production.&lt;/li>
&lt;li>Compiler == any static code analysis for non compiled languages.&lt;/li>
&lt;/ul>
&lt;p>43.- Learning to use &lt;strong>command line&lt;/strong> tools is a valuable educational experience, and you might end up preferring them.&lt;/p>
&lt;p>44.- Learn (at least) two different languages and paradigms well.&lt;/p>
&lt;p>45.- Invest some time to &lt;strong>master&lt;/strong> the IDE you’re using.&lt;/p>
&lt;ul>
&lt;li>It’ll make your life easier and save you time in the long run.&lt;/li>
&lt;/ul>
&lt;p>46.- Know and work with your limitations: budget, resources, time, etc.&lt;/p>
&lt;p>47.- Work in &lt;strong>small tasks&lt;/strong>, don’t be afraid to throw away changes.&lt;/p>
&lt;ul>
&lt;li>You’ll still have the insight you gained from the experience.&lt;/li>
&lt;li>Know what you need to accomplish beforehand.&lt;/li>
&lt;/ul>
&lt;p>48.- Use a relational DB if your application is going to handle a large, persistent, interconnected set of data.&lt;/p>
&lt;p>49.- Learn to &lt;strong>communicate&lt;/strong> well in many “languages”: not just to your machine, but also to business partners, and maybe even pick up a foreign language too.&lt;/p>
&lt;ul>
&lt;li>It’s good for connections and for life.&lt;/li>
&lt;/ul>
&lt;p>54.- Think twice before implementing “temporary solutions”.&lt;/p>
&lt;p>55.- Make &lt;strong>GUI&lt;/strong> easy to use correctly and hard to use incorrectly.&lt;/p>
&lt;ul>
&lt;li>Anticipate errors and find ways to prevent them.&lt;/li>
&lt;li>It’s about the user’s experience, not your own.&lt;/li>
&lt;/ul>
&lt;p>56.- In projects, find ways to make &lt;strong>the invisible visible&lt;/strong>.&lt;/p>
&lt;p>57.- Message passing leads to better &lt;strong>scalability&lt;/strong> in parallel systems.&lt;/p>
&lt;p>58.- Write code that other people can easily &lt;strong>understand&lt;/strong>.&lt;/p>
&lt;p>59.- Using &lt;strong>polymorphism&lt;/strong> in your classes and objects reduces the need for if/else statements, which results in smaller, safer code.&lt;/p>
&lt;p>60.- QA is your friend, not your enemy.&lt;/p>
&lt;p>61.- Version your releases.&lt;/p>
&lt;p>62.- Make sure your source code clearly states what the program is doing.&lt;/p>
&lt;p>63.- Learn about the build process. It’s an important part of development.&lt;/p>
&lt;p>64.- Practice &lt;strong>pair programming&lt;/strong>.&lt;/p>
&lt;p>65.- Prefer &lt;strong>domain-specific types&lt;/strong> over primitive types.&lt;/p>
&lt;ul>
&lt;li>They make the code more readable and less prone to errors in development.&lt;/li>
&lt;/ul>
&lt;p>67.- A professional takes &lt;strong>personal responsibility&lt;/strong> for their career and their code.&lt;/p>
&lt;p>68.- Use version control.&lt;/p>
&lt;p>69.- Sometimes the best way to solve a problem is to step away from the computer and let the solution magically appear in your mind.&lt;/p>
&lt;p>70.- Reading code is a good way to &lt;strong>learn&lt;/strong>. Other people’s or your old code.&lt;/p>
&lt;p>72.- Reinventing the wheel is a great way to develop your skills.&lt;/p>
&lt;p>75.- If the code you wrote is truly horrifying, don’t try to fix. &lt;strong>Delete it&lt;/strong> and start again.&lt;/p>
&lt;p>76.- Apply the Single Responsibility Principle (&lt;strong>SRP&lt;/strong>).&lt;/p>
&lt;p>77.- If a client or team member requests a product change, don’t dismiss it outright even if you don’t agree. Ask why instead.&lt;/p>
&lt;ul>
&lt;li>That will lead to a more productive conversation and better results.&lt;/li>
&lt;/ul>
&lt;p>78.- If you’re doing the same thing over and over, try to find a way to &lt;strong>automate it&lt;/strong>.&lt;/p>
&lt;p>79.- Take advantage of code analysis tools.&lt;/p>
&lt;p>80.- Write tests based on the &lt;strong>desired functionality&lt;/strong> of your program, not incidental behavior.&lt;/p>
&lt;p>83.- Testing takes time, but it ensures the &lt;strong>quality&lt;/strong> of the end product. Do it.&lt;/p>
&lt;p>85.- There are many benefits to collaborative work and pair programming.&lt;/p>
&lt;p>86.- Sometimes fixing a mistake in the code leads to uncovering a hidden error.&lt;/p>
&lt;p>87.- Write code &lt;strong>with other programmers in mind&lt;/strong>.&lt;/p>
&lt;p>88.- Learn to use Unix tools. Learn how to use the &lt;strong>terminal&lt;/strong>.&lt;/p>
&lt;p>89.- Use the right algorithm and data structure for the job.&lt;/p>
&lt;ul>
&lt;li>To do that, you need to understand them well.&lt;/li>
&lt;/ul>
&lt;p>90.- Have a good logging policy.&lt;/p>
&lt;p>91.- Using the DRY principle helps you identify and repair performance bottlenecks.&lt;/p>
&lt;p>92.- Testers and programmers should &lt;strong>collaborate&lt;/strong>.&lt;/p>
&lt;p>93.- Write code as if you had to support it for the &lt;strong>rest of your life&lt;/strong>.&lt;/p>
&lt;p>94.- Try to write &lt;strong>“small” functions&lt;/strong>.&lt;/p>
&lt;ol start="95">
&lt;li>Good tests act as &lt;strong>documentation&lt;/strong> for the code they’re testing.&lt;/li>
&lt;/ol>
&lt;ul>
&lt;li>They describe how the code works.&lt;/li>
&lt;/ul>
&lt;ol start="96">
&lt;li>
&lt;p>To be a good programmer, you have to care about the &lt;strong>quality&lt;/strong> of the code.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Really, really &lt;strong>discuss things&lt;/strong> with your customers before assuming you understand what they want.&lt;/p>
&lt;/li>
&lt;/ol></content></entry><entry xml:lang="en"><title>Clean Code</title><subtitle>A Handbook of Agile Software Craftsmanship</subtitle><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><published>2016-05-01T00:00:00+00:00</published><updated>2016-05-01T00:00:00+00:00</updated><author><name>
Robert C. Martin</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/readings/clean-code/"/><id>https://chemaclass.com/readings/clean-code/</id><summary type="html">Even bad code can function. But if code isn't clean, it can bring a development organization to its knees. Every year, countless hours and significant resources are lost because of poorly written code. But it doesn't have to be that way.</summary><content type="html">&lt;p>Even bad code can function. But if code isn’t clean, it can bring a development organization to its knees. Every year,
countless hours and significant resources are lost because of poorly written code. But it doesn’t have to be that way.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;hr />
&lt;h2 id="summary">Summary
&lt;a class="heading-anchor" href="#summary" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;h3 id="chapter-1-what-is-clean-code">Chapter 1: What Is Clean Code?
&lt;a class="heading-anchor" href="#chapter-1-what-is-clean-code" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>The code can be measured with either “good” or “bad” in the code review or by how many minutes it takes you to talk
about it.&lt;/li>
&lt;li>A clean code should be elegant, efficient, readable, simple, without duplications, and well-written.&lt;/li>
&lt;li>You should add value to the business with your code.&lt;/li>
&lt;li>Clean code offers quality and understanding when we open the source file.&lt;/li>
&lt;li>It is necessary that your code is clean and readable for anyone to find and easily understand. Avoid wasting others’
time.&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-2-meaningful-names">Chapter 2: Meaningful Names
&lt;a class="heading-anchor" href="#chapter-2-meaningful-names" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Names of the classes, variables, and methods must be meaningful and clearly indicate what a method does or what an
attribute is.&lt;/li>
&lt;li>Create pronounceable names to facilitate communication.&lt;/li>
&lt;li>Avoid acronyms and avoid confusing names, which may bring anyone who reads the code to the wrong conclusions.&lt;/li>
&lt;li>Use names that reflect the system domain, the context, and the problems that must be solved.&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-3-functions">Chapter 3: Functions
&lt;a class="heading-anchor" href="#chapter-3-functions" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Methods should be easy to read and understand.&lt;/li>
&lt;li>Methods should convey its intention.&lt;/li>
&lt;li>Methods should be small.&lt;/li>
&lt;li>They must have up to 20 lines.&lt;/li>
&lt;li>Methods should only do one thing.&lt;/li>
&lt;li>You should use names with words that say what it really does.&lt;/li>
&lt;li>The optimal number of parameters of a method is zero, after one and two.&lt;/li>
&lt;li>Three should be avoided, but if you think it should be used, have a justification.&lt;/li>
&lt;li>&lt;code>Boolean&lt;/code> type as a parameter already states that it does more than one thing.&lt;/li>
&lt;li>Avoid duplication.&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-4-comments">Chapter 4: Comments
&lt;a class="heading-anchor" href="#chapter-4-comments" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>One of the common reasons for comments is because the code is bad.&lt;/li>
&lt;li>If you’re thinking about writing a comment, then the code should be refactored.&lt;/li>
&lt;li>Comments do not save a bad code.&lt;/li>
&lt;li>Try to explain what the code causes happening.&lt;/li>
&lt;li>Comments can be useful when placed in certain places.&lt;/li>
&lt;li>Don’t explain your code with comments. Use informative vars/method names.&lt;/li>
&lt;li>Comments can be used to express the importance of certain points.&lt;/li>
&lt;li>Do not write comments with redundant, useless, or false information.&lt;/li>
&lt;li>They shouldn’t be used to indicate who changed or why, use versioning.&lt;/li>
&lt;li>Don’t comment code that will not be used. Remove it instead.&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-5-formatting">Chapter 5: Formatting
&lt;a class="heading-anchor" href="#chapter-5-formatting" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Formatting should indicate things of importance since it is a developer of communication form.&lt;/li>
&lt;li>A messy code is hard to read.&lt;/li>
&lt;li>The readability of the code will take effect on all the changes that will be made.&lt;/li>
&lt;li>Smaller classes are easier to understand.&lt;/li>
&lt;li>Set a limit of characters per line of code. For example 120.&lt;/li>
&lt;li>Try to keep more next related concepts vertically to create a code stream.&lt;/li>
&lt;li>Use spaces between operators, parameters, and commas.&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-6-objects-and-data-structure">Chapter 6: Objects and Data Structure
&lt;a class="heading-anchor" href="#chapter-6-objects-and-data-structure" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Follow the &lt;a rel="external" href="https://en.wikipedia.org/wiki/Law_of_Demeter">Law of Demeter&lt;/a>:
&lt;ul>
&lt;li>Each unit should have only limited knowledge about other units: only units “closely” related to the current unit.&lt;/li>
&lt;li>Each unit should only talk to its friends; don’t talk to strangers.&lt;/li>
&lt;li>Only talk to your immediate friends.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Do not make dumb objects.&lt;/li>
&lt;li>Objects hide the data abstraction and expose methods that operate the data.&lt;/li>
&lt;li>Data structures expose your data and do not have significant methods.&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-7-error-handling">Chapter 7: Error Handling
&lt;a class="heading-anchor" href="#chapter-7-error-handling" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Error handling should be planned carefully by all programmers.&lt;/li>
&lt;li>When wrong things occur, we have to get it to do the right things.&lt;/li>
&lt;li>Give preference to launching an exception than treating it just to hide.&lt;/li>
&lt;li>Create messages with information about the error.&lt;/li>
&lt;li>Mention that it failed. Where was this failure? If possible, mention why it failed.&lt;/li>
&lt;li>Look at separate business rules for errors and error handling.&lt;/li>
&lt;li>Avoid returning a &lt;code>NULL&lt;/code> in methods, preferably to return an empty object.&lt;/li>
&lt;li>Avoid passing &lt;code>NULL&lt;/code> to the methods; this can generate &lt;code>NullPointerExceptions&lt;/code>.&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-8-boundary">Chapter 8: Boundary
&lt;a class="heading-anchor" href="#chapter-8-boundary" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>In third-party code, to avoid passing objects, APIs look forward in order to keep things in the same class.&lt;/li>
&lt;li>Perform tests on the API’s third party.&lt;/li>
&lt;li>Study the documentation and test the third API before you start using it.&lt;/li>
&lt;li>Check well the features you will use.&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-9-unit-tests">Chapter 9: Unit Tests
&lt;a class="heading-anchor" href="#chapter-9-unit-tests" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Make sure each piece of code is doing what you expect it to do.&lt;/li>
&lt;li>Follow the &lt;a rel="external" href="https://en.wikipedia.org/wiki/Test-driven_development">TDDs law&lt;/a>:
&lt;ul>
&lt;li>Don’t create code before you have a failing test.&lt;/li>
&lt;li>Don’t create more tests than necessary to fail.&lt;/li>
&lt;li>You cannot write more code than enough to pass the test that is failing.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Keep your test clean.&lt;/li>
&lt;li>The tests must undergo changes in the same way that the code.&lt;/li>
&lt;li>The dirtier the code, the more difficult test will be to maintain.&lt;/li>
&lt;li>Use the F.I.R.S.T rule for testing:
&lt;ul>
&lt;li>The test is fast-running.&lt;/li>
&lt;li>The tests are independent of others.&lt;/li>
&lt;li>The test is repeatable in various environments.&lt;/li>
&lt;li>The test is self-validating.&lt;/li>
&lt;li>The test is timely.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>The test is as important as the production code.&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-10-classes">Chapter 10: Classes
&lt;a class="heading-anchor" href="#chapter-10-classes" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>By default, classes should start with the variables:
&lt;ul>
&lt;li>Static and constants public.&lt;/li>
&lt;li>Static and variable private.&lt;/li>
&lt;li>Instances and variables privates.&lt;/li>
&lt;li>Soon after comes the functions.&lt;/li>
&lt;li>The class name should represent its responsibility.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>The class must have only &lt;a rel="external" href="https://en.wikipedia.org/wiki/Single-responsibility_principle">one responsibility&lt;/a>: one reason to change.&lt;/li>
&lt;li>You should try to make a brief description of the class.&lt;/li>
&lt;li>The methods should be small and one responsibility.&lt;/li>
&lt;/ul>
&lt;hr />
&lt;p>This interview is based on Uncle Bob’s book “Clean Code”. They cover some existing guides that can help you become a
better programmer and explore how books and current trends are shaping the software landscape.&lt;/p>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/QnmRpHFoYLk"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div></content></entry></feed>