<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title><![CDATA[ Philipp Giese - RSS Feed ]]></title>
    <link>https://www.philgiese.com</link>
    <description><![CDATA[ Personal page and blog of Philipp Giese. ]]></description>
    <lastBuildData>Sun, 15 Jun 2025 08:50:24 GMT</lastBuildData>
    <item>
      <title><![CDATA[ Hypothesis-Based Planning ]]></title>
      <description><![CDATA[ What are we going to do next? Lots of teams are asking this question every day. I've certainly been part of planning sessions of every shape and form. Be it… ]]></description>
      <link>https://www.philgiese.com/post/hypothesis-based-planning</link>
      <guid isPermaLink="false">https://www.philgiese.com/post/hypothesis-based-planning</guid>
      <dc:creator>Philipp Giese</dc:creator>
      <pubDate>Wed, 21 Dec 2022 00:00:00 GMT</pubDate>
      <category>process</category>
      <category>productivity</category>
      <content:encoded><![CDATA[
<p>
  What are we going to do next?
  Lots of teams are asking this question every day.
  I've certainly been part of planning sessions of every shape and form.
  Be it just a quick check-in or a planning WEEK.
  They all had one thing in common: the plan rarely worked out.
</p>
<h2 id="the-enemy-of-every-plan">The enemy of every plan<a aria-hidden="true" tabindex="-1" href="#the-enemy-of-every-plan"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>While planning something, we usually talk about <strong>what</strong> we want to achieve.</p>
<ul>
  <li>What problems have the most impact on our users?</li>
  <li>Which parts of our architecture are holding us back the most?</li>
</ul>
<p>
  This focus on <strong>what</strong> needs to happen is great.
  How come plans so often don't work out in the end?
  It is because we're unaware of the most crucial part of each plan: all the <strong>assumptions</strong> that go into it.
</p>
<p>Not only do we make many assumptions about the problems we want to solve.</p>
<ul>
  <li>The problem exists</li>
  <li>The problem needs a solution</li>
  <li>Our users want to use our product to solve the problem</li>
  <li>The solution fits into our product strategy</li>
  <li>(there are probably more)</li>
</ul>
<p>
  Add to that list all of your assumptions about how your code works and how you think it will work in the future.
  Most plans fail because we're treating our <strong>assumptions</strong> as if they were <strong>knowledge</strong>.
  When you treat an assumption as knowledge, it means you will never test it.
  And if we never test our assumptions or aren't even aware of them, they become the most significant risk to our plans.
  If one of the assumptions in the list above does not hold, then whatever you're doing will not matter.
  You might be working on the wrong thing, creating a solution your users don't want or adding bloat to your product because you make it do something it shouldn't.
</p>
<h2 id="treat-plans-as-a-set-of-hypotheses-and-test-them">Treat plans as a set of hypotheses and test them<a aria-hidden="true" tabindex="-1" href="#treat-plans-as-a-set-of-hypotheses-and-test-them"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  We need to accept the reality that we're going to make many guesses.
  That's fine.
  A good guess is 1000 times better than being stuck in analysis paralysis.
  The important part is that everyone <strong>knows</strong> that we're guessing and that we take measures to get feedback as early as possible on whether our guess is correct.
  <a href="/post/how-early-integration-creates-value-for-your-users">Working in small increments</a> and <a href="/post/when-is-the-time-to-converge">deferring decisions</a> can help with that.
</p>
<p>
  If we continuously check whether our assumptions are correct, we are much more likely to end up with something that works.
  Might your initial plan change?
  Absolutely!
  And that's a good thing because we're not trying to blindly follow a plan but create <strong>value</strong> for our customers.
</p>
<h2 id="what-and-when-to-validate">What and when to validate<a aria-hidden="true" tabindex="-1" href="#what-and-when-to-validate"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Similar to <a href="/post/when-is-the-time-to-converge">deferring decisions</a>, you don't want to constantly check every assumption.
  That's because not every assumption has the same impact.
  It would be best to focus on the assumptions that would derail you completely.
  How can you do this?
</p>
<h3 id="start-tracking-your-hypothesis">Start tracking your hypothesis<a aria-hidden="true" tabindex="-1" href="#start-tracking-your-hypothesis"><<span></span>></<span></span>></a></h3>
<p>The first thing you need to do is track your hypothesis.</p>
<pre class="language-md"><code class="language-md code-highlight"><span class="code-line"><span class="token title important"><span class="token punctuation">#</span> Title</span>
</span><span class="code-line">
</span><span class="code-line">What is the assumption we're making, and why is that important?
</span><span class="code-line">
</span><span class="code-line"><span class="token title important"><span class="token punctuation">##</span> Impact</span>
</span><span class="code-line">
</span><span class="code-line">What impact on the plan would it have when this assumption is wrong?
</span><span class="code-line">The impact of an assumption can be anything from "none" to "need to cancel."
</span><span class="code-line">
</span><span class="code-line"><span class="token title important"><span class="token punctuation">##</span> How to disprove</span>
</span><span class="code-line">
</span><span class="code-line">What can we observe that would show us that our assumption is wrong?
</span><span class="code-line">Is there a particular user behavior, KPIs we can track, or something else?
</span><span class="code-line">
</span><span class="code-line"><span class="token title important"><span class="token punctuation">##</span> Who can validate the hypothesis</span>
</span><span class="code-line">
</span><span class="code-line">Which people can validate this hypothesis?
</span><span class="code-line">When no one can validate a hypothesis, this is a sign that you should not be doing what you're about to do.
</span></code></pre>
<h3 id="link-hypothesis-to-your-work">Link hypothesis to your work<a aria-hidden="true" tabindex="-1" href="#link-hypothesis-to-your-work"><<span></span>></<span></span>></a></h3>
<p>
  You might be tracking work with issues, tickets, epics, or any other format you like.
  It doesn't matter which style you prefer.
  Once you've formulated your hypothesis, you should link them to your planning artifacts.
  The important part is to do this on every level.
  Items representing a broad road map will have many hypotheses linked to them, and individual tickets might end up with one or none.
  That's fine.
  By relating your work plan to your hypothesis, you've already created transparency for everyone who wants to know.
  This way, people you don't regularly interact with can comment on your hypothesis and contribute valuable feedback!
</p>
<h3 id="rank-hypothesis-based-on-impact">Rank hypothesis based on impact<a aria-hidden="true" tabindex="-1" href="#rank-hypothesis-based-on-impact"><<span></span>></<span></span>></a></h3>
<p>
  There are a ton of ways to define impact.
  I choose the (what I believe) easiest one.
  For each hypothesis, count how many work items it relates to, and then sort that list descending.
  The hypothesis at the top will have the highest <strong>impact</strong> because much work depends on it.
  Should this hypothesis not hold, then <strong>a lot</strong> needs to change.
  Make sure you'll have clarity around this one as soon as possible.
</p>
<p>
  By regularly testing your top hypothesis, you can decrease the risk of your overall development process.
  You'll spend more time on things that matter and less time on stuff that doesn't have an impact.
  That's great news!
</p>
<p>
  You can also use the list of hypotheses to make it clear to outside stakeholders that you're going down a precarious path because you're working on something that can't be validated and has a high risk of failure.
  Use that information to your advantage!
</p>
<hr>
<p>
  What do you think about this approach?
  While it is very similar to what engineering teams around the globe already do, it also adds more transparency in an area that is often overlooked.
  I'd like to hear about your experience, so tweet at <a href="https://www.twitter.com/philgiese">@philgiese</a> on Twitter (as long as it still exists).
</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[ Why Building Software is Hard ]]></title>
      <description><![CDATA[ Every day someone new decides that writing code will be the thing they'd like to do for a living. Or maybe just for fun. And thanks to incredible frameworks… ]]></description>
      <link>https://www.philgiese.com/post/why-building-software-is-hard</link>
      <guid isPermaLink="false">https://www.philgiese.com/post/why-building-software-is-hard</guid>
      <dc:creator>Philipp Giese</dc:creator>
      <pubDate>Mon, 22 Aug 2022 00:00:00 GMT</pubDate>
      <category>process</category>
      <category>leadership</category>
      <category>communication</category>
      <category>software-design</category>
      <content:encoded><![CDATA[
<p>
  Every day someone new decides that writing code will be the thing they'd like to do for a living.
  Or maybe just for fun.
  And thanks to incredible frameworks and <a href="https://stackoverflow.com/">Stack Overflow</a>, getting your first results has become somewhat easy.
  This is great but has misled some people into thinking that building software (i.e., larger apps that people pay for) is easy.
  I believe this is because some practices that lead to great software aren't prominent when you first encounter them.
  This post will be my ever-growing list of activities and misconceptions of the software world.
</p>
<h2 id="before-we-start">Before we start<a aria-hidden="true" tabindex="-1" href="#before-we-start"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  What I don't want this post to be is discouraging.
  As I said, you can start small and get results.
  You don't need to know or follow everything I'm describing from day one.
  Pick something, try it out, and see for yourself.
  Some points might work better for you (and your team) than others.
</p>
<hr>
<table>
  <thead>
    <tr>
      <th>What you <strong>think</strong> works</th>
      <th>What <strong>actually</strong> works</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Work on as many tasks as possible in parallel</td>
      <td><a href="#why-you-are-faster-the-fewer-tasks-are-open-in-parallel">Focus on one task at a time</a></td>
    </tr>
    <tr>
      <td>Code reviews</td>
      <td><a href="#why-code-reviews-arent-helping-you">Pair or swarm on tasks</a></td>
    </tr>
    <tr>
      <td>Design and QA as separate steps</td>
      <td><a href="#why-you-should-avoid-handoffs">Co-create and involve people at every stage</a></td>
    </tr>
    <tr>
      <td>Do rigorous planning up-front</td>
      <td><a href="#why-you-should-not-spend-too-much-time-planning">Experiment and work in small increments</a></td>
    </tr>
    <tr>
      <td>Few releases with extensive manual tests</td>
      <td><a href="#why-you-will-never-find-all-the-bugs">Automate releases and do them frequently</a></td>
    </tr>
    <tr>
      <td>Never change a running system</td>
      <td><a href="#why-you-should-refactor">Continuously adapt</a></td>
    </tr>
    <tr>
      <td>Build the big thing that handles everything</td>
      <td><a href="#why-that-huge-component-might-not-be-a-good-idea">Build many small blocks that do exactly one thing</a></td>
    </tr>
    <tr>
      <td>Have someone manage releases</td>
      <td><a href="#why-releasing-should-not-be-a-big-deal">Deliver continuously</a></td>
    </tr>
    <tr>
      <td>Keep people busy all the time</td>
      <td><a href="#why-people-should-not-work-all-the-time">Provide room for self-improvement</a></td>
    </tr>
    <tr>
      <td>Writing software is easy</td>
      <td><a href="#why-writing-software-is-hard">That sh*it ain't easy</a></td>
    </tr>
  </tbody>
</table>
<h2 id="why-you-are-faster-the-fewer-tasks-are-open-in-parallel">Why you are faster the fewer tasks are open in parallel<a aria-hidden="true" tabindex="-1" href="#why-you-are-faster-the-fewer-tasks-are-open-in-parallel"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  When five people work on five tasks simultaneously, you'll get five results faster, right?
  Wrong!
  Many people (want to) believe this is true because then every additional developer will make the team faster.
  Unfortunately, the opposite is true.
  How come?
  This sentiment assumes that you can define and work on five tasks in complete isolation.
  Maybe on separate <a href="https://martinfowler.com/bliki/FeatureBranch.html">feature branches</a> because this would be required to make the above somewhat true.
  In real life, the five people will probably need to talk to each other because their work is interdependent in one way or the other.
  They will also most likely change the code in ways that affect the work of the other developers.
  That means these developers will need to <strong>sync</strong> from time to time to check whether their work is still compatible.
  And with the word <strong>sync</strong> your parallel dream is over.
</p>
<p>
  It can get worse.
  When person A works on something that person B needs and person B relies on the fact that A finishes their task before B picks up the next task, there is much more risk involved.
  Any interruption of A (vacation, sickness, manager casually swinging by their desk) will become an issue for B.
  Imagine there is a person C who is also waiting for B.
  This style of working builds a massive house of cards that <strong>will</strong> come down, eventually.
</p>
<p>
  A system that optimizes for parallel work ultimately optimizes for <a href="/post/the-productivity-paradox">busyness over productivity</a>.
  People will always have something to do, but nothing will come out of it.
  <a href="https://en.wikipedia.org/wiki/Lean_product_development">Lean</a> and <a href="https://en.wikipedia.org/wiki/Kanban">Kanban</a> teach us that <a href="https://dzone.com/articles/pattern-of-the-month-single-piece-flow">single item flow</a> (i.e., working on one thing at a time) is desirable when you want to get things done.
  That <strong>does not</strong> mean that one <strong>person</strong> works on one thing at a time (even though that might already be an improvement in some companies).
  It means that the <strong>whole team</strong> works on only one thing at a time.
  This seems counter-intuitive at first, but this way of working has some key advantages:
</p>
<ul>
  <li>
    <p>
      <strong>No need for <a href="#why-code-reviews-arent-helping-you">reviews</a></strong> —
      When the whole team works on a task, the review happens continuously.
      With that in place, there is no need for another gateway step that speeds up the whole process.
    </p>
  </li>
  <li>
    <p>
      <strong>No handovers</strong> —
      When designers and QA folks work with everyone, you don't need a design <a href="#why-you-should-avoid-handoffs">handover</a> or a QA handover.
      The designers figure out the design with developers, and the QA folks help build the right thing.
      This removes a lot of back and forth, shortens feedback cycles, and speeds up the process.
    </p>
  </li>
  <li>
    <p>
      <strong>No knowledge silos</strong> —
      As everyone is working on the same thing at the same time, everyone also shares the same knowledge.
      With that, it is absolutely no problem when people get sick or go on vacation.
      Everyone else is still on board, and when someone comes back, they are immediately on-boarded into the changes.
    </p>
  </li>
</ul>
<p>
  The methods I just described optimize the time <strong>not spent</strong> on <a href="https://kanbanize.com/lean-management/value-waste/7-wastes-of-lean">wasteful activities</a>.
  Doing so automatically increases the time you spend on activities that create value.
</p>
<h2 id="why-code-reviews-arent-helping-you">Why code reviews aren't helping you<a aria-hidden="true" tabindex="-1" href="#why-code-reviews-arent-helping-you"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Code reviews are a low bandwidth form of communication with a high chance for misunderstandings (<a href="https://hilton.org.uk/">Peter Hilton</a>).
  When the reviewer does not share the same context as the person who wants the review, chances are high that the reviewer will miss or not fully understand the most significant bits.
</p>
<p>
  The quality of a review is indirectly proportional to how much the code change is in need of a proper review.
  This means that a 15-line change will get a lot of comments because it is easy to understand.
  But because it is easy to understand, the chance that the reviewer will find something groundbreaking is also low.
  A 1500-line change will likely get no comments because the change is just too hard to understand.
</p>
<p>
  Reviews are also an interruption to flow.
  What does the person who wants the review do now?
  Best case: nothing.
  Worst case: start the next task already (see <a href="#why-you-are-faster-the-fewer-tasks-are-open-in-parallel">why you are faster the fewer tasks are open in parallel</a>).
</p>
<p>
  You can make code reviews obsolete with <a href="https://www.agilealliance.org/glossary/mob-programming">mob programming</a> plus <a href="/post/the-religion-of-test-driven-development">test driven development</a>.
  A code review happens all the time when the whole team works together.
  TDD is a <a href="https://en.wikipedia.org/wiki/Behavior-shaping_constraint">forcing function</a> to have the most important discussions at the start because everyone needs to be on the same page about what the mob is currently trying to achieve (get the current test green).
  It also helps to ensure you're not accidentally breakings something as you move along.
</p>
<h2 id="why-you-should-avoid-handoffs">Why you should avoid handoffs<a aria-hidden="true" tabindex="-1" href="#why-you-should-avoid-handoffs"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Handoffs happen when people work <a href="#why-you-are-faster-the-fewer-tasks-are-open-in-parallel">in parallel</a>.
  This means that anytime the deliverable that got handed to you isn't perfect, you're going to interrupt the flow of someone else because they need to look at something again that they thought was finished.
  If you're lucky, they can do that right away.
  Otherwise, you'll need to wait until they finish their current task.
  You might be able to see how this quickly adds a lot of waste to your process.
  The more handoffs you have, the higher the chance for waste.
</p>
<p>
  Now you're in a situation where everything takes forever, and you can't progress because everyone is waiting for something from someone else.
  This means deadlines will approach, and you're unable to deliver.
  Since people know that fixing issues takes forever, they tend to just not do this anymore, which leads to crap products being released.
  Crap products lead to bad customer feedback, leading to more rigorous handoffs.
  A vicious cycle.
</p>
<p>
  Some people will claim that you can fix this situation with better planning.
  <a href="#why-you-should-not-spend-too-much-time-planning">That won't work</a>.
  Certain things are impossible to know up-front, and you'll only discover them when you start working on your task.
</p>
<p>
  Again, the solution is to work together.
  Eliminate handoffs by co-creating with designers, developers, QA folks, and customers.
  Then make sure you work <a href="/post/when-is-the-time-to-converge">in small increments</a>.
  When designers need to watch developers code for weeks on end, they're less likely to enjoy working with them.
  When you ship something every other day, and you can rapidly prototype and change the software as you get new insights, the process will motivate everyone involved.
</p>
<h2 id="why-you-should-not-spend-too-much-time-planning">Why you should not spend too much time planning<a aria-hidden="true" tabindex="-1" href="#why-you-should-not-spend-too-much-time-planning"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Some people think they are smarter than everybody else.
  The same people think you can plan a large software project in detail.
  A missed deadline?
  A better plan could have avoided that.
</p>
<p>
  These people forget that our job is not to execute plans perfectly.
  Our job is to build the right thing and build it right.
  Nothing is worse than perfectly executing the wrong plan.
</p>
<p>
  A big plan will ultimately lead to <a href="/post/how-early-integration-creates-value-for-your-users">large</a> <a href="#why-you-will-never-find-all-the-bugs">releases</a>.
  Why?
  Because frequent small releases will likely result in feedback, and that feedback may not match your plan.
  This might not sound bad to you, but for people who think their job is to come up with perfect plans, this is a threat.
  Mostly because it can expose that what they sold as <strong>knowledge</strong> was simply an <strong>assumption</strong>.
  Plans also fix many things in place because to create a plan, you need to <a href="/post/when-is-the-time-to-converge">make decisions</a>.
  When you decide on aspects that might only become important in a couple of months early on, it is easy to pigeonhole yourself into a fixed mindset.
  And fixed mindsets don't like change at all.
</p>
<p>
  Instead of planning too much, you should spend time experimenting.
  Thanks to concepts like <a href="/post/how-many-feature-toggles-are-enough">feature toggles</a>, you can test changes or new features with a subset of select users before you roll them out for everyone.
  This helps to mitigate the risk of releasing something that nobody wants.
</p>
<p>
  You should also be clear about what you <strong>think</strong> is true and what you <strong>know</strong> to be true.
  Tracking your hypothesis can help you determine which experiments to run first because they have the most significant impact.
  With that, you can avoid surprises late in the process, which would otherwise lead to delays.
</p>
<h2 id="why-you-will-never-find-all-the-bugs">Why you will never find all the bugs<a aria-hidden="true" tabindex="-1" href="#why-you-will-never-find-all-the-bugs"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  No one likes to introduce bugs.
  This is why some insist that rigorous testing must happen before each release.
  With that, they usually mean manual, exploratory testing.
  While this kind of testing definitively adds <em>some</em> value, I would argue that it shouldn't be done for <strong>every</strong> change.
</p>
<p>
  When you try to find every edge case, you'll never ship something because you're never done searching.
  But when you never ship to production, you'll never discover all edge cases.
  Testing <em>too much</em> can lead to situations where people think they should <a href="#why-you-should-not-spend-too-much-time-planning">plan more</a>, <a href="#why-you-should-avoid-handoffs">outsource testing</a>, <a href="#why-releasing-should-not-be-a-big-deal">release less often</a>, and <a href="#why-you-are-faster-the-fewer-tasks-are-open-in-parallel">parallelize more work</a>.
</p>
<p>
  What to do?
  Accept that bugs will exist no matter what you do.
  Then work on reducing the risk for <strong>high impact</strong> bugs.
</p>
<ul>
  <li>
    <strong>Work in small increments</strong> —
    This ensures that the code changes are small when a bug appears, making it easier to identify and fix.
    Also, <a href="/post/how-early-integration-creates-value-for-your-users">working in small increments</a> generally reduces the risk for bugs because small changes are easier to comprehend than large ones.
  </li>
  <li>
    <strong>Better <em>automated</em> tests</strong> —
    Write <a href="/post/tests-that-help-you-find-defects-faster">tests that help you find defects faster</a> so that even while developing, you can identify issues earlier and be more confident about your changes.
  </li>
  <li>
    <strong>Test Driven Development</strong> —
    Admittedly, that's my personal bias.
    <a href="/post/the-religion-of-test-driven-development">TDD</a> makes you think about your changes before you do them.
    This usually forces you to have the most important discussions first, leading to better code and fewer defects.
  </li>
  <li>
    <strong>Focus on MTTR</strong> —
    MTTR, or <em>Mean Time to Resolve</em> is my favorite metric.
    It measures how fast you are at fixing bugs.
    I think it is an excellent forcing function to help teams optimize their way of working to ensure that when a bug happens, it is fixed in the fasted way possible.
  </li>
  <li>
    <strong>Use a zero-bug policy</strong> —
    A zero-bug policy does not mean that there are no bugs but that all bugs must be resolved before regular work happens.
    That's great because it means you'll never (knowingly) build features on top of broken code.
    This further reduces the risk of future bugs.
  </li>
</ul>
<h2 id="why-you-should-refactor">Why you should refactor<a aria-hidden="true" tabindex="-1" href="#why-you-should-refactor"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  What habits did you change in the last year?
  Did you stop doing certain things and maybe start doing some others?
  Did you learn something new?
  Did the language you use get an update that makes it easier to achieve a certain task?
  All these things happen, so we need to refactor our code constantly.
</p>
<p>
  The moment you write code you put an <a href="/post/thoughts-on-technical-debt-and-continuous-improvement">expiry date</a> on it.
  Even if the code was crafted according to the current best practices and standards, the sheer fact of time would make it erode.
  Because your tooling gets better, and you'll learn new things.
</p>
<p>
  When you never refactor code, it will eventually expire.
  This means that the cost of a large-scale refactor will equal the cost of a <a href="/post/the-rewrite-trap">rewrite</a>.
  It is a bit like housekeeping.
  When you clean up a little every day, your house will be in an acceptable state all the time.
  However, when you neglect cleaning for too long, things go from dirty to broken.
</p>
<p>
  I always like to work according to the rule that you should always leave a place a little bit better than when you found it.
  Refactors don't have to be big.
  I'd even say they should never be big.
  Make small improvements every day, and they will amount to something big over time.
  When you get into this habit, tech debt related to outdated code won't be on your list of problems anymore.
</p>
<h2 id="why-that-huge-component-might-not-be-a-good-idea">Why that huge component might not be a good idea<a aria-hidden="true" tabindex="-1" href="#why-that-huge-component-might-not-be-a-good-idea"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  When people learn to code, they inevitably encounter certain design patterns.
  One pretty much everyone knows (maybe because it is so simple) is <a href="https://en.wikipedia.org/wiki/Don&#x27;t_repeat_yourself">"don't repeat yourself"</a> or DRY.
  Oh, boy, do I not like this pattern.
  For some reason, people think that any form of repetition is bad design.
  What this leads to are premature and very leaky abstractions.
  Because they are premature, these abstractions leak all over the place and lead to <a href="/post/what-is-cohesion-and-why-should-you-care">high coupling and low cohesion</a> in your code base.
</p>
<p>
  One symptom of that is either huge classes or long functions.
  For functions, you can easily spot this when people start passing around <a href="https://techterms.com/definition/flag">flags</a> that are used to control the flow.
  In most cases, you'd want two or more functions focusing on one thing.
  However, that would lead to some duplication, and when people think this is a bad design, they end up with huge functions that combine many use cases.
</p>
<p>
  The goal of DRY was to keep things re-usable.
  Instead of duplicating logic into multiple places, it should be well encapsulated and re-used.
  That's a great idea!
  So why doesn't it work?
</p>
<p>
  In a lot of cases, duplication is a coincidence and nothing more.
  If you mistake this coincidence for something more and create an abstraction out of it, then your abstraction also only works coincidentally.
  I always write the same code at least three times before I start thinking about extracting it.
  Only then will I have understood the use cases well enough to develop an abstraction that makes sense, is re-usable, and doesn't leak implementation details.
</p>
<p>
  Think of abstractions and methods as a toolbox.
  You don't have one screwdriver that fits all different screws in all different sizes.
  Such a tool would be utterly useless.
  But multiple full-blown screwdrivers are also over the top.
  They would take up way too much space.
  So we took the re-usable part - the handle - and created a set of different bits that all fit on it.
  All bits still have some duplication: the metal, the part needed to make them fit into the handle.
  However, this duplication helps, and no one would think about removing it because that would make using the different bits much harder.
</p>
<h2 id="why-releasing-should-not-be-a-big-deal">Why releasing should not be a big deal<a aria-hidden="true" tabindex="-1" href="#why-releasing-should-not-be-a-big-deal"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Have you ever heard of <a href="https://mende.io/blog/not-deploying-on-fridays-outdated-practice/"><em>No Release Fridays</em></a>?
  It's a saying that teams should not release on Fridays because the release might break, and someone needs to spend their weekend fixing it.
  This sounds reasonable until you ask yourself why releasing is scary in the first place.
  When you build software so that releasing it is scary, change how you build it!
</p>
<p>
  When something is hard, do it more often.
  That statement is true for working out and for almost anything else in life.
  <a href="#why-you-will-never-find-all-the-bugs">Don't be afraid of bugs</a> and release as soon as something hits your main branch.
</p>
<p>When you're building a library or framework tools like <a href="/post/automated-releases-with-semantic-release">semantic release</a> can help you not only release but also figure out the correct version bump and automatically create change logs.</p>
<p>If you're interested in a real-world example of how to change your release process, then have a look at <a href="https://mende.io/blog/not-deploying-on-fridays-outdated-practice/">this article</a> from my co-worker <a href="https://mende.io/">Tobias</a> where he describes how we pulled it off at <a href="https://bryter.io/">BRYTER</a>.</p>
<h2 id="why-people-should-not-work-all-the-time">Why people should not work all the time<a aria-hidden="true" tabindex="-1" href="#why-people-should-not-work-all-the-time"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  We've already talked about wasteful activities such as <a href="#why-you-are-faster-the-fewer-tasks-are-open-in-parallel">working in parallel</a>, <a href="#why-code-reviews-arent-helping-you">code reviews</a>, and <a href="#why-you-should-avoid-handoffs">handoffs</a>.
  If you avoid all these pitfalls and crank out code using TDD in a mob all the time, you should be good, right?
  Unfortunately, not.
  In fact, you shouldn't be working 100% of your time.
</p>
<p>
  That might be the point where you think I'm crazy.
  We're all knowledge workers, and if we're <a href="/post/the-productivity-paradox">busy all the time</a>, we're giving up a huge potential.
  The potential for <a href="/post/innovation-by-design">innovation</a>.
</p>
<p>
  Think about it.
  When you're working <em>head down</em> all the time, you'll never have time to reflect.
  You will not read that <a href="/reading">book</a> that gives you a great idea or watch that <a href="/talks">talk</a> with some crazy new insight.
  It also removes the possibility of trying out the refactoring you thought about but never got to.
  I would argue that people in our busyness should only spend up to 70% of their work week with planned activities and leave the last 30% for their minds to wander.
</p>
<h2 id="why-writing-software-is-hard">Why writing software is hard<a aria-hidden="true" tabindex="-1" href="#why-writing-software-is-hard"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  This has become the longest article I've written so far.
  I don't want to gate keep anyone from getting into the field of software development.
  But I also wanted to highlight that writing high-quality software and doing it in a way that produces good results in the fastest way possible <strong>is hard work</strong>.
</p>
<p>
  This article merely scratches the surface of what is required of software developers every day.
  Of course, you won't be able to follow all these rules daily, which is exactly why continuous improvement is part of the list.
  The goal isn't to be perfect but to do something good every day.
  Over time these small bits will amount to something big.
</p>
<p>
  I've mentioned TDD a couple of times.
  This practice alone takes so much time to get right.
  Now, not only do you have to get the code for the product right, but also the tests.
  Because tests should be written in a way so that they don't need to change every time a detail in your product changes but they need to make sure that you don't accidentally break stuff while you move along.
</p>
<p>
  The best advice is to work in baby steps and keep iterations as small as possible.
  Get early feedback and improve.
  If you want to read more on the topic, <a href="https://ronjeffries.com/articles/-z022/01121/extreme-thoughts">Ron Jeffries</a> has written a great article about it!
</p>
<hr>
<p>That's it for now. I'm happy to hear your feedback on <a href="https://twitter.com/philgiese">Twitter</a>.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[ The Rewrite Trap ]]></title>
      <description><![CDATA[ This would all be way easier if we would just throw everything away and build it ourselves. ]]></description>
      <link>https://www.philgiese.com/post/the-rewrite-trap</link>
      <guid isPermaLink="false">https://www.philgiese.com/post/the-rewrite-trap</guid>
      <dc:creator>Philipp Giese</dc:creator>
      <pubDate>Tue, 12 Jul 2022 00:00:00 GMT</pubDate>
      <category>process</category>
      <category>productivity</category>
      <category>architecture</category>
      <category>software-design</category>
      <content:encoded><![CDATA[
<blockquote>
  <p>This would all be <strong>way</strong> easier if we would just throw everything away and build it ourselves.</p>
</blockquote>
<p>
  When was the last time you've heard someone say this or even said it yourself?
  I definitively heard this at least a thousand times.
  What I observed, though, is that this sentiment usually comes from people who recently joined a new team or a new company.
  Do these people bring fresh ideas that make them see issues where others are already blinded?
  Or are they the ones who are missing something and, therefore, think that a rewrite will produce a better result?
</p>
<h2 id="tldr">TL;DR<a aria-hidden="true" tabindex="-1" href="#tldr"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  We'll learn why rewriting software will most likely not produce a better result.
  To not fall for this fallacy yourself, you need to understand how to:
</p>
<ul>
  <li><a href="#why-it-is-so-tempting-to-start-something-from-scratch">move out of your comfort zone</a>,</li>
  <li><a href="#you-dont-know-what-you-dont-know">acknowledge that you don't have all the answers</a>, and</li>
  <li><a href="#rebuild-the-parts-that-really-need-rebuilding">what you might want to do instead</a></li>
</ul>
<h2 id="why-it-is-so-tempting-to-start-something-from-scratch">Why it is so tempting to start something from scratch<a aria-hidden="true" tabindex="-1" href="#why-it-is-so-tempting-to-start-something-from-scratch"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  There are multiple reasons why starting from scratch seems like a promising approach.
  I will talk about the ones I have encountered most often and advise on what to do instead.
</p>
<h3 id="you-dont-need-to-wrap-your-head-around-new-concepts">You don't need to wrap your head around new concepts<a aria-hidden="true" tabindex="-1" href="#you-dont-need-to-wrap-your-head-around-new-concepts"><<span></span>></<span></span>></a></h3>
<p>
  One key reason is that people like to stick to what they already know.
  When you start all over, you can choose the conditions you want to work in (e.g., the programming language or a framework).
  No matter what was already there, you don't need to try to learn something new.
  The freedom to use the tools that you already know can feel like a huge productivity boost.
</p>
<h4 id="why-is-this-a-bad-thing">Why is this a bad thing<a aria-hidden="true" tabindex="-1" href="#why-is-this-a-bad-thing"><<span></span>></<span></span>></a></h4>
<p>
  Software is much more than a framework or a language.
  Most complexity is not found in the code that renders something on screen or accesses the database.
  You'll find the complexity inside the business logic of the software.
  I would argue that although some languages or frameworks will remove some boilerplate code, the gains you get from replacing one language with another are minimal in many software products.
  What you'll end up with is the same complex logic expressed in a slightly different way.
  Will that new way feel better to you?
  Maybe.
  However, it will only feel better because you could stick to what you already know.
</p>
<p>
  People also usually forget that the current implementation won't just disappear.
  While working on the rewrite, your users will still use the old product and find issues that need fixing.
  The fixes will now take much more time because next to the time it takes to produce the fix, you will also add the time it needs to context switch between the old and the new world.
  Even worse, when the rewrite is not done by the team that built the original version, this can mean that the rewrite will reintroduce the issues.
  A <a href="https://twitter.com/webri_">co-worker</a> told me about a situation where the old team saw the rewrite as a challenge to compete with the new team because they took pride in what had already been built.
</p>
<h4 id="what-you-can-do-instead">What you can do instead<a aria-hidden="true" tabindex="-1" href="#what-you-can-do-instead"><<span></span>></<span></span>></a></h4>
<p>
  Be aware of why you like specific frameworks, languages, or concepts and <a href="/post/working-with-people#talking-is-hard">talk to people</a> about it.
  There is a good chance that you can apply some of the same methodologies also in another language.
  Also, you might learn that what the team is currently using has some nice features you have never heard of before.
  See this as a learning opportunity for both the team and you.
</p>
<p>When you figure out that you want to refactor parts of the product, do it in <a href="/talk/embrace-legacy">the right way</a>.</p>
<hr>
<h3 id="follow-your-mental-model">Follow your mental model<a aria-hidden="true" tabindex="-1" href="#follow-your-mental-model"><<span></span>></<span></span>></a></h3>
<p>
  When we build software, we also create a mental model to guide the architecture.
  Getting into a mental model of someone else can be very hard.
  When you rewrite a product, you can build your mental model, meaning it is much easier to understand and follow architectural choices when encountering them.
  This lowers the cognitive load on your end and makes you feel more productive as you move along because the likelihood that you misunderstood a concept is lower (because you invented it).
</p>
<h4 id="why-is-this-a-bad-thing-1">Why is this a bad thing<a aria-hidden="true" tabindex="-1" href="#why-is-this-a-bad-thing-1"><<span></span>></<span></span>></a></h4>
<p>
  Models change and evolve.
  It is likely that even though the mental modal you find seems confusing, there is a good reason for it being this way.
  When you create a new mental model, it will likely miss certain parts.
  However, you won't know this yet.
  By building up a new mental model that disregards what is already there, you set yourself up for failure.
</p>
<h4 id="what-you-can-do-instead-1">What you can do instead<a aria-hidden="true" tabindex="-1" href="#what-you-can-do-instead-1"><<span></span>></<span></span>></a></h4>
<p>
  <a href="/post/working-with-people#talking-is-hard">Talk to people</a>.
  When something seems odd, this is a very good start for a meaningful conversation.
  Be clear about why something seems odd to you and suggest what you think would fit better.
  Even though there might be good reasons for the current model, this does not mean it is <em>perfect</em>.
  With your input, the team can iron out inconsistencies and improve.
</p>
<p>
  Don't do this only once.
  Make sure to adapt the terms you use to build the product as the product evolves.
  This will make it easier for the next person that joins the team to get going.
</p>
<hr>
<h3 id="work-the-way-you-want">Work the way you want<a aria-hidden="true" tabindex="-1" href="#work-the-way-you-want"><<span></span>></<span></span>></a></h3>
<p>
  With new tools and new architecture, likely, you'll also choose new processes for your work.
  You might want to start with continuous delivery right from the start.
  After all, the product is small again, so changes to the process are easier.
</p>
<h4 id="why-is-this-a-bad-thing-2">Why is this a bad thing<a aria-hidden="true" tabindex="-1" href="#why-is-this-a-bad-thing-2"><<span></span>></<span></span>></a></h4>
<p>
  <em>How</em> you work is only loosely coupled to <em>what</em> you build.
  If the system you're working in leads to 3-month release cycles, it will most likely lead to 3-month release cycles even when you start from scratch.
</p>
<h4 id="what-you-can-do-instead-2">What you can do instead<a aria-hidden="true" tabindex="-1" href="#what-you-can-do-instead-2"><<span></span>></<span></span>></a></h4>
<p>
  <a href="/post/working-with-people#talking-is-hard">Talk to people</a>.
  Figure out why things happen in a certain way.
  Maybe people aren't aware that <a href="/post/how-early-integration-creates-value-for-your-users">early integration creates value</a> or that there is a better way of doing things.
  Make sure to figure out why things are the way they are before you change them.
</p>
<h2 id="you-dont-know-what-you-dont-know">You don't know what you don't know<a aria-hidden="true" tabindex="-1" href="#you-dont-know-what-you-dont-know"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Maybe you have noticed already that <a href="/post/working-with-people#talking-is-hard">talking to people</a> is the best way to overcome the initial urge to rewrite everything.
  Unfortunately, communication is hard and takes a lot of time, and that's probably why we sometimes try to avoid it as much as possible.
  However, when something is hard, <a href="/post/working-with-people#when-something-is-hard-do-it-more-often">do it more often</a> to strengthen that muscle.
  Talking with people is no exception to this rule.
  It would be best if you built relationships to understand where people are coming from and their <a href="/post/non-violent-communication#say-what-you-need">needs</a>.
</p>
<p>
  Another thing is not to underestimate <strong>how much</strong> you don't know.
  When you're new to a project, it is easy to underestimate the problem's complexity.
  Many problems seem small from the outside but are huge on the inside.
  Acknowledge that there is a ton of stuff you don't know yet.
  People will usually react nicer to your questions when you start from this assumption.
  Because now you're not the person who wants to tell people how to do their jobs, but you're the novice who likes to understand how we got to where we are.
</p>
<p>
  Last but not least: <a href="/post/when-is-the-time-to-converge"><em>time</em></a>.
  We don't want to estimate how long it will take to develop a specific feature because we know our estimate will be incorrect.
  If we can't estimate how long it will take to build one <strong>feature</strong>, how can we be confident that a <strong>rewrite</strong> will be any good?
  We can't.
  We want to believe it is faster because of all the reasons I've outlined above.
  When we allow ourselves to believe in these lies, we're no better than any manager who <em>believes</em> that development estimates will align with reality.
  And we don't want to be this person.
  We need to acknowledge that even though we'd like something to be better once we've rewritten it, we don't have any proof that this will be the case.
  Even worse, we know that all things considered, it will probably take longer, and it won't be better but just different and come with a new set of problems.
</p>
<p>
  <img src="/posts/the-rewrite-trap/outcome-over-time.png" alt="Outcome over time">
</p>
<p>
  The graph above illustrates what causes us to choose rewrites nonetheless.
  Initially, we can move fast.
  This makes us feel productive and gives us lots of small dopamine rushes because we can ship the first features quickly.
  We must be on the right track!
  We're missing that we're not fast because we are incredible software engineers but because the new project is small.
  Over time the complexity increases, and we learn that some of the assumptions we made (explicitly or implicitly) were wrong.
  Even worse, we've probably made other mistakes along the way that we now need to <strong>also</strong> fix.
  That leads to a decline in productivity and maybe to someone new coming along who wants to rewrite the software <em>again</em>.
</p>
<h2 id="rebuild-the-parts-that-need-rebuilding">Rebuild the parts that need rebuilding<a aria-hidden="true" tabindex="-1" href="#rebuild-the-parts-that-need-rebuilding"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>Once you have overcome the initial urge to throw everything away and start over and have <a href="/post/working-with-people#talking-is-hard">talked to people</a> you can start to change the parts that matter.</p>
<p>
  Is there waste in your processes?
  Can you, for instance, replace a review step with pair programming?
  Do this!
</p>
<p>
  Are there parts in your software that are <a href="/post/what-is-cohesion-and-why-should-you-care#re-use-what-can-be-re-used-but-not-more">re-purposed instead of re-used</a>?
  Adapt their names, pull them apart, and improve the code step by step.
</p>
<p>
  There will be real shortcomings (i.e., <a href="/post/thoughts-on-technical-debt-and-continuous-improvement">technical debt</a>) that might be more obvious to you than to the existing team.
  Be vocal about these parts and look out not to make things worse when you add new features.
  Build appropriate extension points and maybe devise a plan to incrementally get the software into a better shape.
  A new pair of eyes with fresh ideas is usually appreciated.
  The one idea that is not: let's start from scratch.
</p>
<hr>
<p>Have you been part of a <em>big rewrite</em>? Did you cause it, or did you have to live through it? I'm interested in hearing about your experiences. Good and bad! Tell me on Twitter: <a href="https://twitter.com/philgiese">@philgiese</a>.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[ Working with People ]]></title>
      <description><![CDATA[ You might have overheard people saying or said some of the following phrases yourself. "I work better on my own," "Pair programming just doesn't work for me,"… ]]></description>
      <link>https://www.philgiese.com/post/working-with-people</link>
      <guid isPermaLink="false">https://www.philgiese.com/post/working-with-people</guid>
      <dc:creator>Philipp Giese</dc:creator>
      <pubDate>Mon, 17 Jan 2022 00:00:00 GMT</pubDate>
      <category>process</category>
      <category>productivity</category>
      <category>leadership</category>
      <category>communication</category>
      <content:encoded><![CDATA[
<p>
  You might have overheard people saying or said some of the following phrases yourself.
  "I work better on my own," "Pair programming just doesn't work for me," "Other people <em>just</em> don't think the same way I do."
  Usually, when I hear people say these things, we discuss whether we should spend more time working with each other.
  Sometimes this comes up during retros, sometimes during post-mortems.
  People think that these are good excuses not to do something.
</p>
<p>
  Let's change the subject of these statements from "working with others" to "testing."
  "I work better without tests," "Testing just doesn't work for me," "The test framework just doesn't work the way I want it to."
</p>
<p>
  I would bet that you wouldn't stop testing if the people on your team bring up these excuses.
  However, I've repeatedly seen that we're (without hesitation) willing to give up collaboration and make more room for solo work.
</p>
<h2 id="tldr">TL;DR<a aria-hidden="true" tabindex="-1" href="#tldr"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Working as a team or managing one is hard!
  Historically, many practices focus on <a href="#the-individual-contributor">individual contributors</a> instead of a team.
  However, teams and individuals are very different.
  It helps to understand particular <a href="#working-in-teams">dynamics that exist whether you like it or not</a>.
  Also, similar to software development, you can't afford to ignore issues but need to tackle them head-on.
  <a href="#talking-is-hard">Hard tasks</a> need to <a href="#when-something-is-hard-do-it-more-often">happen as often as possible</a> so that the team can learn how to cope with them and, eventually, turn them into easy tasks.
</p>
<h2 id="the-individual-contributor">The individual contributor<a aria-hidden="true" tabindex="-1" href="#the-individual-contributor"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  I believe the underlying problem is that even though we're forming teams within our organizations, most performance reviews still happen solely for individuals.
  When it comes to whether someone should get a promotion or not, we're only thinking about <a href="https://www.indeed.com/career-advice/finding-a-job/what-is-an-individual-contributor">individual contributions</a>.
  What have <strong>you</strong> specifically done to get the company further?
  It bothers me that how I work (tech stack, setup, location) has changed <em>dramatically</em> in the last decade but performance reviews, salary negotiations, and the likes still mostly happen the exact same way.
  When everything about your work changes, why doesn't the mechanism to figure out whether you're doing a good job or not change?
</p>
<p>
  Even more so, I genuinely believe that if we want to get the best out of our teams, we also need to change how we think about a team's performance.
  For instance, compensation is usually seen as something tied to a title.
  What would happen if we'd not tie salary to a title but instead to specific roles that an individual may or may not hold for a certain period?
  When a junior developer is excellent at writing documentation and finding bugs, why not pay them for that?
  What if the teams decide who has which roles?
  I don't know whether this would work or make sense, but I like the sound of it and the flexibility it brings with it.
</p>
<h2 id="working-in-teams">Working in teams<a aria-hidden="true" tabindex="-1" href="#working-in-teams"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  I've recently participated in a course called <a href="https://tam-akademie.de/ausbildungen-programme/weiterbildung-fuehrungskraefte/">modern leadership</a>.
  One module dealt with team dynamics.
  A key takeaway for me was that we're inclined to call every group of people a team.
  However, most groups of people are just that.
  A group.
  Not every group needs to be a team.
  But if we want to turn people that share a manager into a team, this takes effort.
</p>
<p>
  When you form a new team, or the team structure changes considerably, every team will go through five stages.
  <a href="#1-forming">Forming</a>, <a href="#2-storming">Storming</a>, <a href="#3-norming">Norming</a>, <a href="#4-performing">Performing</a>, and <a href="#5-adjourning">Adjourning</a>.
</p>
<p>
  This isn't some business talk but psychology.
  It will happen whether you like it or not.
  However, when you cater to each stage and support it in the right way, you're helping the team become the best version of itself.
  Let's have a quick look at each stage.
</p>
<h3 id="1-forming">1. Forming<a aria-hidden="true" tabindex="-1" href="#1-forming"><<span></span>></<span></span>></a></h3>
<p>
  We got either a completely new team or some people left or joined.
  In this stage, people get to know each other.
  People try to figure out whom they're working with.
  What do I want to achieve in this team?
  What do the others want to achieve?
  Can I imagine working with someone else?
  Do our values align?
</p>
<p>
  All the above (and possibly more) questions need to be answered because it helps people understand each other.
  This is essential in the future because it can help understand the actions of others when you know something about their intentions.
</p>
<h3 id="2-storming">2. Storming<a aria-hidden="true" tabindex="-1" href="#2-storming"><<span></span>></<span></span>></a></h3>
<p>
  After the team has formed, people will now try to assume the roles <strong>they</strong> think they are best suited for.
  Prepare yourself for some conflicts.
  You'll see different ideas of where the team should go and different ways of working.
  What is important is that you leave room for these conflicts.
  They need to happen, and they need to be discussed.
  Sometimes even in great detail.
  If you're shutting down these conflicts to "get going," you're setting the team up for much more trouble in the long run when it really should be performing.
</p>
<h3 id="3-norming">3. Norming<a aria-hidden="true" tabindex="-1" href="#3-norming"><<span></span>></<span></span>></a></h3>
<p>
  Conflicts have happened, and people have a much deeper understanding of how they work and their characters.
  Now is the time to draw up concrete rules.
  In software, this is where you'd define your <a href="https://www.agilealliance.org/glossary/definition-of-done/">definition of done</a> and the likes.
  You want to document these rules because they become the foundation of how your team works.
  You can discuss and change them at any point but only when everyone agrees.
  No single individual is allowed just to break these rules.
</p>
<p>
  Notice how making up rules is the <strong>third</strong> step and not the first.
  To me, this screams "individuals and interactions over processes and tools" from the <a href="http://agilemanifesto.org/">Manifesto for Agile Software Development</a>.
  Why would we think we can start with the rules if we don't yet understand the people who should follow the rules?
</p>
<h3 id="4-performing">4. Performing<a aria-hidden="true" tabindex="-1" href="#4-performing"><<span></span>></<span></span>></a></h3>
<p>
  Only now will the team be able to perform.
  People understand each other, and they've defined a set of rules to follow.
  With this setup, you got the necessary trust between people to do a great job.
</p>
<p>
  Again, you can't skip to this stage.
  The three stages before will happen if you like it or not.
  You can influence how good (or great) the team will perform when it reaches this stage.
  If you shut down any initial conflict and don't let people create their own set of rules, you'll miss out on a lot of energy.
</p>
<h3 id="5-adjourning">5. Adjourning<a aria-hidden="true" tabindex="-1" href="#5-adjourning"><<span></span>></<span></span>></a></h3>
<p>
  I have to admit I have never witnessed that the "adjourning" stage was properly supported.
  Let's say a team finished a project it was set up for, or someone leaves the team.
  Did you acknowledge what this <strong>meant</strong> for the team, the people?
</p>
<p>
  It is crucial to be aware when the current team setup changes considerably.
  Why?
  Because it will mean that the team forming process starts again.
  When most team members stay the same, it might not take as long, but it will happen.
  You'll need to make sure that new team members get the same chance to become a part of the team as current ones.
  You'll also need to look out for people who might want to fill a spot that is not taken by someone else anymore.
</p>
<hr>
<p>
  Do you think your current team went through all these stages in the best possible way?
  If yes - great!
  If not - you can still fix that.
  I've used a tool called <a href="https://www.theteamcanvas.com/">the team canvas</a> in the past, and I think it is excellent!
  It is similar to the <a href="https://www.strategyzer.com/canvas/business-model-canvas">business model canvas</a> but for teams.
  The whole team fills the canvas together.
  This exercise takes longer than you think (instead of hours think days) and will lead to <strong>a lot</strong> of discussions.
</p>
<p>
  What I like most about it is that I can correlate each category to either forming, storming, or norming.
  However, that's also why it might take you a while to finish it.
  A good strategy might be to start with "common goals, "values," "personal goals," and "needs &#x26; expectations" because I think these are closest to the forming stage.
  Let what you put in there sink in for a day (or a week) and only then move on to "purpose," "people &#x26; roles," "strengths &#x26; assets," "weaknesses &#x26; risks."
  These four categories all say "storming" for me.
  Consider what would happen if someone thinks they are good at something, but then this skill is listed under "weaknesses &#x26; risks."
  You'll have a lot to talk about.
  Again, let this sink in for a couple of days and then define "rules &#x26; activities," which I consider the only "norming" activity.
</p>
<h2 id="talking-is-hard">Talking is hard<a aria-hidden="true" tabindex="-1" href="#talking-is-hard"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Communication is hard.
  I wrote an article about <a href="/post/non-violent-communication">non-violent communication</a>, but I still struggle to apply that every day.
  Especially when you need to talk about issues, it becomes complicated.
  That's why we sometimes tend to avoid talking about something to fool us into believing the issues don't exist.
  But that makes the whole situation worse.
</p>
<p>
  So why do we do this?
  I claim that this has a lot do to with the value of the individual contributor.
  We trained people to think they're <a href="/post/the-productivity-paradox">not being productive</a> when they don't do the thing they're hired to do.
  Now, when a performance review focuses solely on you and your output in terms of code or features, resolving underlying issues inside the team seems not to be your job.
  Because who would spend time doing this when this will actively harm your career progression?
</p>
<p>
  I might have convinced you that we should strive for team performance instead of individual performance at this point.
  If we want the team to work better together, we need to reduce solo work as much as possible.
  Because when people don't talk with each other, they'll lose alignment, knowledge transfer, and colossal learning potential.
  All these things are crucial if you want a team that performs as best as possible.
</p>
<h2 id="when-something-is-hard-do-it-more-often">When something is hard, do it more often<a aria-hidden="true" tabindex="-1" href="#when-something-is-hard-do-it-more-often"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  The headline of this paragraph has become one of the things I often say.
  It applies to sports, software releases, bug fixing, and so much more.
  Most importantly, it also applies to team collaboration.
  If you believe that "other people just don't think like you," then this is not an excuse to collaborate less.
  It is a clear sign that you need to collaborate more!
  You have just discovered that you're missing alignment with others in your team.
  And maybe you're the one who needs alignment more than the others.
</p>
<h3 id="pairing-or-swarming">Pairing or Swarming<a aria-hidden="true" tabindex="-1" href="#pairing-or-swarming"><<span></span>></<span></span>></a></h3>
<p>
  <a href="https://en.wikipedia.org/wiki/Pair_programming">Pair programming</a> is a proven technique to get out of your bubble.
  By working with someone else, you're forced to explain yourself and bounce ideas back and forth.
  That's great.
  But it might also mean that you're "just" extending your bubble to one more person.
</p>
<p>
  Swarming takes the pairing approach even further.
  You pull together as many people as you need to get something done.
  This might feel slow, but it isn't because you're working towards <a href="https://scrumdictionary.com/term/single-item-flow/">single item flow</a>.
  Let me highlight just some of the advantages of a swarm.
</p>
<h4 id="made-for-distributed-teams">Made for distributed teams<a aria-hidden="true" tabindex="-1" href="#made-for-distributed-teams"><<span></span>></<span></span>></a></h4>
<p>
  One of the most incredible things about a swarm is that the people who participate in it don't need to be the same all the time.
  Sometimes it makes sense to pull in a designer or product manager, and sometimes it doesn't.
  If the people don't have to be in the swarm constantly, this also means that teams that operate over different time zones can better work together.
  When your whole team focuses on one topic, the people who get up early can start together.
  Working hours should overlap at least a little so that the people who start later can join the swarm when their workday begins.
  People are now having conversations about the given task which means there aren't any hard handoffs.
  Some people will continue to work while others stop.
</p>
<p>If you lean into this idea, it will significantly impact knowledge sharing inside your team.</p>
<h4 id="simplify-and-speed-up-your-process">Simplify and speed up your process<a aria-hidden="true" tabindex="-1" href="#simplify-and-speed-up-your-process"><<span></span>></<span></span>></a></h4>
<p>
  Have you ever chased down people from your team to review your code?
  This can be a cumbersome task.
  It gets even worse when you also have to spend a lot of time explaining to them what you did so that they can do a proper review of your code.
  Does this sound like fun?
  It doesn't sound like that to me.
</p>
<p>
  When you're working in a swarm, you have multiple people debating the pros and cons of a particular approach <strong>all the time</strong>.
  This effectively removes the need for any further review.
  You've already shared the knowledge, and multiple people have agreed that the solution you typed is the best one given the current circumstances.
</p>
<p>If you take this idea further, it even eliminates the necessity for branches 🤯.</p>
<h4 id="accelerate-learning">Accelerate learning<a aria-hidden="true" tabindex="-1" href="#accelerate-learning"><<span></span>></<span></span>></a></h4>
<p>
  For me, the worst part of the individual contributor model is that it slows down learning.
  When you have to make every mistake yourself and find a solution for it yourself, this takes considerable time.
  While this might be good from time to time to train your <a href="/post/how-to-solve-problems">problem-solving strategy</a> it can become very tiring.
</p>
<p>
  Swarming helps less experienced developers to learn more faster.
  Since the swarm only moves forward when everyone is on board with a solution, senior engineers must explain more.
  This ramps up junior engineers faster and also requires senior engineers to become better at explaining things.
  Again, I'll file this under if it is hard, do it more often.
</p>
<hr>
<p>
  Is your team as good as possible, and what are your thoughts on individual contributor strategies?
  Tell me on Twitter: <a href="https://twitter.com/philgiese">@philgiese</a>.
</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[ When is the time to converge? ]]></title>
      <description><![CDATA[ In the past months, I have learned something about myself. I learned that I value a good development process a lot. One thing, in particular, seems to spark… ]]></description>
      <link>https://www.philgiese.com/post/when-is-the-time-to-converge</link>
      <guid isPermaLink="false">https://www.philgiese.com/post/when-is-the-time-to-converge</guid>
      <dc:creator>Philipp Giese</dc:creator>
      <pubDate>Thu, 03 Jun 2021 00:00:00 GMT</pubDate>
      <category>process</category>
      <category>productivity</category>
      <category>leadership</category>
      <content:encoded><![CDATA[
<p>
  In the past months, I have learned something about myself.
  I learned that I value a good development process a lot.
  One thing, in particular, seems to spark the most discussions: when to make decisions.
  Some people also call this "When to converge".
  This topic needs some unpacking.
</p>
<h2 id="tldr">TL;DR<a aria-hidden="true" tabindex="-1" href="#tldr"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  When you make the wrong decisions too early on, you're setting yourself up for failure.
  Especially, when there was no need to make that decision this early.
  To understand the root cause of this kind of problem, you need to understand
</p>
<ul>
  <li><a href="#who-makes-the-decisions">Who</a> makes <a href="#which-decisions-are-there-to-make">which</a> decision <a href="#when-are-decisions-made">when</a>,</li>
  <li>what <a href="#decision-categories">kind of decision you are making</a>, and</li>
  <li><a href="#defer-decisions-if-possible">whether you need to converge just now</a></li>
</ul>
<h2 id="context-for-decisions">Context for decisions<a aria-hidden="true" tabindex="-1" href="#context-for-decisions"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  This section could probably be a post on its own.
  We need to clarify <strong>who</strong> makes <strong>which</strong> decision <strong>when</strong>.
</p>
<h3 id="who-makes-the-decisions">Who makes the decisions<a aria-hidden="true" tabindex="-1" href="#who-makes-the-decisions"><<span></span>></<span></span>></a></h3>
<p>
  I think the assumption that people in management positions or with the word "Manager" in their job title are the only ones capable of making decisions is wrong.
  At least they shouldn't be the ones who make <strong>all</strong> the decisions.
  Building software is a complex task.
  We hire different people to fulfill different roles, so the people who have the most profound knowledge can make the best decisions.
</p>
<p>
  What is important is that people need to be aware of their abilities.
  You can and should always reach out to other people to decide which decision is the best.
  Assuming that other people also do this helps as well.
  It prevents you from over-defining when to involve which people.
  When you create an environment where collaboration is valued, then you can trust people to involve whoever is necessary whenever they are necessary.
</p>
<p>
  This paragraph is for all product managers out there.
  I would bet a couple of bucks that people have told you that your job is "to make decisions."
  Don't fall into this trap!
  Your job is to ensure "that decisions are being made" which is a completely different and vastly more complicated task.
  It prevents the development process from stalling.
  You can do that by:
</p>
<ul>
  <li>connecting developers to customers,</li>
  <li>arranging sessions with other departments or stakeholders,</li>
  <li>asking, "what do you need to make this call?"</li>
</ul>
<p>
  And many more things.
  Don't let others pressure you into making decisions out of thin air.
</p>
<h3 id="which-decisions-are-there-to-make">Which decisions are there to make<a aria-hidden="true" tabindex="-1" href="#which-decisions-are-there-to-make"><<span></span>></<span></span>></a></h3>
<p>Let's start with what kind of decisions you usually have to make when you're building software.</p>
<ul>
  <li>Should we build the new feature at all?</li>
  <li>How big does the feature need to be to solve a given problem?</li>
  <li>Does everyone understand the problem?</li>
  <li>Who is going to build the feature?</li>
  <li>Do we need to solve the problem with code?</li>
  <li>Who decides whether a proposed solution solves the problem?</li>
</ul>
<p>
  These are just a couple of questions that ultimately lead to decisions being made.
  You can already be happy if the answers to these questions are accessible and all stakeholders are aware of them.
  I've seen that many people make assumptions and then base their actions on these assumptions without even clarifying them.
  That will ultimately lead to chaos because people do not share a common understanding of the desired outcome.
</p>
<p>
  What I would try to do is to be very clear about which decisions you want to take at which point in time.
  This can drive a discussion around the importance of different decisions.
  It can also calm other stakeholders who could otherwise confuse deferring a decision with not being aware of it.
</p>
<h3 id="when-are-decisions-made">When are decisions made<a aria-hidden="true" tabindex="-1" href="#when-are-decisions-made"><<span></span>></<span></span>></a></h3>
<p>The short answer is: When they become relevant.</p>
<p>
  For instance, you don't need to decide how to implement a feature when you don't even know whether you're going to build it.
  I would go even further and say you <strong>must not</strong> decide this too early on.
  When you <a href="https://anchor.fm/john-cutler/episodes/Premature-Convergence-e1hvt5">converge too early</a> on in the process, then bad things can happen:
</p>
<ul>
  <li>You might get tricked into making false promises based on the wrong assumption</li>
  <li>It becomes harder to incorporate new insights because you've already settled on a solution</li>
  <li>For the same reason, it can get harder to reduce scope later one because that could invalidate any of these decisions</li>
</ul>
<p>
  On the other hand, you don't want to find out that the feature you're building is useless after you spent six months developing it.
  So the "should we build this or not" decision should be made pretty early on, and it needs to be backed up with good research.
</p>
<h2 id="decision-categories">Decision categories<a aria-hidden="true" tabindex="-1" href="#decision-categories"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>When I think about a decision I mainly think about two aspects:</p>
<ol>
  <li><strong>Impact</strong>: How many people and products are affected, and how much does it cost?</li>
  <li><strong>Reversibility</strong>: How hard is it to undo the decision?</li>
</ol>
<h3 id="low-impact--high-reversibility">Low impact / High reversibility<a aria-hidden="true" tabindex="-1" href="#low-impact--high-reversibility"><<span></span>></<span></span>></a></h3>
<p>
  If the decision's impact is low and you can easily undo it, there is little harm to be done.
  You probably shouldn't get hung up on it for too long because discussions might take longer than trying something out.
  These decisions usually are good for experimenting.
  Run with something for a couple of weeks and see how it goes.
</p>
<h3 id="low-impact--low-reversibility">Low impact / Low reversibility<a aria-hidden="true" tabindex="-1" href="#low-impact--low-reversibility"><<span></span>></<span></span>></a></h3>
<p>
  When you make this kind of decision, it makes a part of your system harder to change.
  However, since the impact is so low, that might not matter this much.
  It might make sense to defer the decision until you have more context.
  You should probably at least have some discourse with people about it, but that should be time-boxed.
</p>
<h3 id="high-impact--high-reversibility">High impact / High reversibility<a aria-hidden="true" tabindex="-1" href="#high-impact--high-reversibility"><<span></span>></<span></span>></a></h3>
<p>
  Probably try to make this decision as soon as possible.
  Given that the impact is high, people might want to have some guidelines on how to proceed.
  It also helps to not work in opposite directions.
  Should anyone figure out that the decision wasn't optimal, the high reversibility is your friend, and you can easily course correct.
</p>
<h3 id="high-impact--low-reversibility">High impact / Low reversibility<a aria-hidden="true" tabindex="-1" href="#high-impact--low-reversibility"><<span></span>></<span></span>></a></h3>
<p>
  Be very careful with this kind of decision.
  People will probably want a decision, but given that you have a small margin for error, you need to make sure that you have everything you need to make the call.
  At this point, you might want to think about whether you can turn the big decision into smaller ones with better attributes for impact and reversibility.
</p>
<h2 id="defer-decisions-if-possible">Defer decisions if possible<a aria-hidden="true" tabindex="-1" href="#defer-decisions-if-possible"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  A thing I had to learn is that you can take your time with most decisions.
  There are not so many things that you need to decide on day one.
  What is more likely is that other stakeholders <strong>want</strong> you to make decisions early because it helps them.
  They will claim that early convergence helps you to plan better.
  However, I don't want to create a process designed to deliver the best plan to stakeholders but to provide the best value to customers.
</p>
<p>
  <a href="/post/how-early-integration-creates-value-for-your-users">Incremental development</a> is key.
  Because when we deliver software in small increments, the amount of decisions we need to make for each increment is also tiny.
  This approach makes it also easier to come up with more easily revertible decisions and fewer ones that need to stay forever.
</p>
<hr>
<p>
  How do you make decisions?
  Tell me on Twitter: <a href="https://twitter.com/philgiese">@philgiese</a>.
</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[ Set your project up for success ]]></title>
      <description><![CDATA[ This article is loaded with my personal opinion on how to do things. The baseline I'm going to describe is derived from my personal experience. If you have a… ]]></description>
      <link>https://www.philgiese.com/post/software-project-baseline</link>
      <guid isPermaLink="false">https://www.philgiese.com/post/software-project-baseline</guid>
      <dc:creator>Philipp Giese</dc:creator>
      <pubDate>Sun, 07 Feb 2021 00:00:00 GMT</pubDate>
      <category>process</category>
      <category>productivity</category>
      <category>tooling</category>
      <content:encoded><![CDATA[
<p>
  This article is loaded with my personal opinion on how to do things.
  The baseline I'm going to describe is derived from my personal experience.
  If you have a different view on some topics, please let me know.
  I'm not claiming that what I'm doing is perfect!
</p>
<p>
  When I'm talking about a project in this post, I'm thinking of a larger, commercial project.
  Not something you'd do on the weekend.
  When I try out stuff on my own, I also choose not to do some of these steps.
  However, once you're working with a team on something you want to sell to customers, I'd go with the list below.
</p>
<h2 id="tldr">TL;DR<a aria-hidden="true" tabindex="-1" href="#tldr"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  That's the first time the TL;DR section is straightforward.
  Have a look at the buzzwords and decide for yourself whether you want to read more or not.
</p>
<ul>
  <li><a href="#a-common-language">Define the terms you use</a>,</li>
  <li><a href="#a-tool-to-automate-your-tasks">Automate your tasks</a>,</li>
  <li><a href="#automated-code-formatting">Format your code automatically</a>,</li>
  <li><a href="#zero-lint-errors-or-warnings">Zero tolerance for lint errors and warnings</a>,</li>
  <li><a href="#a-check-for-cyclic-dependencies">Check for cyclic dependencies</a>,</li>
  <li><a href="#automated-tests">Tests!</a>, and</li>
  <li><a href="#automated-deploys">Automate deployments</a></li>
</ul>
<h2 id="a-common-language">A common language<a aria-hidden="true" tabindex="-1" href="#a-common-language"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  This step is often forgotten or declared not crucial because it isn't so much fun.
  You can't play around with technology, and you have to sit down and talk with your teammates.
  Probably for a couple of hours, even, and I still think it is precious.
</p>
<p>
  You should - as a team - come up with definitions for the words you use.
  Did you think "bug" means the same to everyone?
  I got news for you: It doesn't.
</p>
<p>
  That's why it is essential to come to a shared understanding of what these terms mean for your team.
  The good news is that you can then publicly share the definitions so that other people know them.
  Especially the fine line between a bug and an improvement is crucial.
</p>
<p>Here is a non-exhaustive list of things you might want to define.</p>
<ul>
  <li>Ready (how must a ticket look before you start to work on it)</li>
  <li>Done (what needs to happen so that you consider a task done)</li>
  <li>Bug</li>
  <li>Improvement</li>
  <li>Epic</li>
  <li>User Story</li>
  <li>Idea (e.g., what do we expect to gain from it)</li>
</ul>
<h2 id="a-tool-to-automate-your-tasks">A tool to automate your tasks<a aria-hidden="true" tabindex="-1" href="#a-tool-to-automate-your-tasks"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  If a step in your process is essential, you should look into automating it.
  It shouldn't be necessary for people to know the process in and out to follow it.
  All of the activities I describe work best when they run once you push code to your repository.
</p>
<p>
  It doesn't matter which platform you pick.
  Here are some that I've worked with previously.
</p>
<h3 id="jenkins">Jenkins<a aria-hidden="true" tabindex="-1" href="#jenkins"><<span></span>></<span></span>></a></h3>
<p>
  Your company might already use <a href="https://www.jenkins.io/">Jenkins</a>.
  I'd guess the likelihood increases with the age of the company you're working in.
  I must say I've had more bad experiences with it than good.
  That's not because Jenkins is terrible but because it was always self-hosted.
  Unless you're in the business of task automation for developers, you probably shouldn't host these things yourself.
  Pay a company to do it for you.
</p>
<h3 id="circleci">CircleCI<a aria-hidden="true" tabindex="-1" href="#circleci"><<span></span>></<span></span>></a></h3>
<p>
  <a href="https://circleci.com/">CircleCI</a> is great.
  I've never had any issues with it.
  They have a nice <a href="https://github.com/">GitHub</a> integration, and their support is always responsive.
</p>
<p>
  The only disadvantage I could think of is that all your <a href="https://circleci.com/docs/2.0/jobs-steps/#jobs-overview">jobs</a> and all your <a href="https://circleci.com/blog/introducing-workflows-on-circleci-2-0/">workflows</a> need to go into the same file.
  So, this file will grow over time, and it will become harder to maintain it.
</p>
<h3 id="github-actions">GitHub Actions<a aria-hidden="true" tabindex="-1" href="#github-actions"><<span></span>></<span></span>></a></h3>
<p>
  <a href="https://github.com/features/actions">GitHub Actions</a> are extremely powerful.
  You'll need to host your code on GitHub to use them.
</p>
<p>
  The most irritating thing that I encountered was that you don't want to build what GitHub calls an "action" in most cases.
  You want to create a <a href="https://docs.github.com/en/actions/quickstart#creating-your-first-workflow">workflow</a>.
  Creating your action will probably be a sporadic activity.
  More likely, you'll use actions that <a href="https://github.com/marketplace?type=actions">others have built already</a>.
</p>
<p>
  It took me way longer than I'd like to admit to figure this out.
  And if you don't figure it out, you're set up for a pretty complicated ride.
</p>
<p>
  In contrast to CircleCI, each workflow will live in its file, which makes it easier to create workflows with concise <a href="https://en.wikipedia.org/wiki/Concern_(computer_science)">concerns</a>.
  However, you'll need to redefine tasks like <code>install</code> that might be the same for each workflow (or you'll create an install action).
</p>
<h2 id="automated-code-formatting">Automated code formatting<a aria-hidden="true" tabindex="-1" href="#automated-code-formatting"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  It would be best if you didn't argue about code formatting.
  Use a tool like <a href="https://prettier.io/"><code>prettier</code></a> and never speak about the topic again.
  I don't put any effort whatsoever into formatting my code anymore.
  When I save, and nothing happens, this is a sign that there is a syntax error somewhere.
</p>
<p>
  Also, don't trust the "But we all use the <code>prettier</code> plugin for <em>[IDE]</em>."
  Someone won't, or someone will have it configured in the wrong way.
  The last project where I got this answer had violations in <strong>1500</strong> files, and everyone was sure all code was formatted correctly.
</p>
<p>
  You should have this check in your pipeline for when the tool itself is updated.
  They might have changed a rule.
  In this case, you should probably reformat the whole codebase inside the PR that introduces the update.
</p>
<h2 id="zero-lint-errors-or-warnings">Zero lint errors or warnings<a aria-hidden="true" tabindex="-1" href="#zero-lint-errors-or-warnings"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Most people agree that you shouldn't have any <a href="https://en.wikipedia.org/wiki/Lint_(software)">lint</a> errors, and I'd say you also should not have any warnings.
  If you allow warnings, you're going to end up with pointless discussions around whether an error should be a warning or a warning should be an error, or which warnings are safe to ignore.
  Save yourself time and fix all warnings and errors.
</p>
<p>
  I would also suggest that you agree on a set of rules that <em>make sense</em> in a way that there is a good reason for them to be there.
  I'll give you an example.
</p>
<h3 id="good-rule">Good Rule<a aria-hidden="true" tabindex="-1" href="#good-rule"><<span></span>></<span></span>></a></h3>
<blockquote>
  <p>Every link that has <code>target="_blank"</code> set must also define <code>rel="noreferrer noopener"</code></p>
</blockquote>
<p>
  I consider this a good rule because it statically checks for a genuine threat.
  If you don't set these attributes, you open up your page to one of the <a href="https://www.jitbit.com/alexblog/256-targetblank---the-most-underestimated-vulnerability-ever/">most prominent attacks on the internet</a>.
</p>
<h3 id="bad-rule">Bad Rule<a aria-hidden="true" tabindex="-1" href="#bad-rule"><<span></span>></<span></span>></a></h3>
<blockquote>
  <p>Imports must be sorted alphabetically</p>
</blockquote>
<p>
  The order of imports does not have any effect on your code.
  Rules like this one are the personal preferences of some individuals.
  If you want to enforce them, look at the section about automatic code formatting.
  Put this stuff in there.
  Don't make developers actively think about these things.
</p>
<p>🙏 This. 🙏 Is. 🙏 Not. 🙏 Important.</p>
<h2 id="a-check-for-cyclic-dependencies">A check for cyclic dependencies<a aria-hidden="true" tabindex="-1" href="#a-check-for-cyclic-dependencies"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  I had to learn the hard way that cyclic dependencies can cause real trouble.
  Some of the weirdest issues arise when you introduce cyclic dependencies into your codebase.
  You have a cyclic dependency when two modules depend on each other.
  Sometimes this is easy to spot, but it becomes more challenging the larger your codebase gets.
  A cycle of <code>A > B > C > D > A</code> is tough to track down but can cause you real trouble.
</p>
<p>So far, I've always used a tool called <a href="https://github.com/pahen/madge"><code>madge</code></a>, which saved my ass countless times.</p>
<p>
  The biggest issue with cyclic dependencies is that they don't <em>always</em> immediately lead to trouble, and they are ticking time bombs in your codebase.
  And who likes these?
</p>
<h2 id="automated-tests">Automated tests<a aria-hidden="true" tabindex="-1" href="#automated-tests"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>Here are some sentences I don't want to hear.</p>
<ul>
  <li>This is just a prototype. We don't need tests.</li>
  <li>We need to move fast. Tests would only slow us down.</li>
  <li>This code is too complicated. You can't test it.</li>
</ul>
<p>Yuck. Yuck! YUCK!</p>
<p>
  I've blogged about this <a href="/post/the-religion-of-test-driven-development#tdd-is-much-more-than-writing-tests">here</a>, <a href="/post/thoughts-on-technical-debt-and-continuous-improvement">here</a>, and <a href="/post/how-early-integration-creates-value-for-your-users">here</a> so I'll keep this short.
  Testing means understanding.
  If you think you don't need to understand what you're doing before doing it, go ahead.
  I <strong>really</strong> doubt that this makes anyone any faster.
  The only thing you get is the <strong>illusion</strong> of speed because you don't know what you're missing.
</p>
<p>
  I don't think there is <strong>any</strong> reason not to start with tests right away.
  It doesn't harm a prototype to work reliably.
  If your software doesn't break all the time, that makes you fast.
  If your code is that <em>complex</em>, please, add these tests!
</p>
<h2 id="automated-deploys">Automated deploys<a aria-hidden="true" tabindex="-1" href="#automated-deploys"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  To me, something is only done when users can use it.
  As long as a feature isn't deployed or released, it can't create value.
  Therefore, the step to get something out of the door and in front of users must be as easy as possible.
</p>
<p>
  Way too often, it is the case that only a few people can actually deploy and then have to follow a ton of manual steps.
  I don't get it.
  We're engineers.
  We just made the computer do a thousand things, and then we stop at the end?
</p>
<p>
  Sometimes I get the feeling that deploying is seen as something special.
  As if the ability to deploy is something you have to <em>earn</em>.
  I think that's total BS.
</p>
<p>
  If you behave like that, it is no wonder if deploys fail often.
  Deploying your software should be on the same level as running your tests.
  While there is more to this than merely automating the process, automation is a good start.
</p>
<hr>
<p>
  That's my list.
  Is there more?
  Absolutely.
  But that's for another post.
</p>
<p>
  Do you have anything to add to this list?
  Do you agree or disagree?
  Tell me on Twitter: <a href="https://twitter.com/philgiese">@philgiese</a>.
</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[ Innovation by design ]]></title>
      <description><![CDATA[ Over the years, I have seen companies and teams struggle with innovation. It might have worked initially, but after some time,e, the spark that existed when… ]]></description>
      <link>https://www.philgiese.com/post/innovation-by-design</link>
      <guid isPermaLink="false">https://www.philgiese.com/post/innovation-by-design</guid>
      <dc:creator>Philipp Giese</dc:creator>
      <pubDate>Wed, 06 Jan 2021 00:00:00 GMT</pubDate>
      <category>process</category>
      <category>architecture</category>
      <category>software-design</category>
      <category>leadership</category>
      <content:encoded><![CDATA[
<p>
  Over the years, I have seen companies and teams struggle with innovation.
  It might have worked initially, but after some time,e, the spark that existed when the company was young is now missing.
  As innovation is important, companies sometimes react with measures such as dedicated <em>innovation teams</em>.
  However, this way they make sure that innovation will only happen inside these teams and nowhere else.
  I think that's a massive waste of potential.
  I have witnessed that the teams who made innovation part of their day-to-day work were the most successful ones.
</p>
<h2 id="tldr">TL;DR<a aria-hidden="true" tabindex="-1" href="#tldr"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Innovation can be something that happens naturally.
  However, to get there, we need to make sure that teams are set up for innovation.
</p>
<p>Teams and managers need to understand that to be innovative, you need:</p>
<ul>
  <li><a href="#innovation-needs-room-to-experiment">room to run experiments</a>,</li>
  <li><a href="#different-kinds-of-innovation">understand that innovation does not only happen on the feature-level</a>, and</li>
  <li><a href="#dx-drives-ux">make sure you have a great developer experience</a>.</li>
</ul>
<h2 id="innovation-needs-room-to-experiment">Innovation needs room to experiment<a aria-hidden="true" tabindex="-1" href="#innovation-needs-room-to-experiment"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  One of the biggest killers for innovation is when workers are <a href="/post/the-productivity-paradox#busy-%E2%89%A0-productive">busy all the time</a>.
  If you ensure that your teams are buried in work, then there can't be any innovation.
  To innovate, you need to be able to experiment, and to experiment, you need to have some spare time available.
</p>
<p>
  Even more so, it <strong>must</strong> be OK that experiments fail.
  Most likely, most of the experiments will fail, but that is fine.
  This is how teams learn and gain a better understanding of a problem.
  If you only ever do experiments that you know will succeed then you're never taking risks.
  If you're never taking risks, then you'll never truly innovate.
</p>
<p>Over the past years, I've seen a couple of techniques that are supposed to give developers the time and space to work on experiments.</p>
<h3 id="gold-cards">Gold cards<a aria-hidden="true" tabindex="-1" href="#gold-cards"><<span></span>></<span></span>></a></h3>
<p>
  A <a href="https://leadingagileteams.com/2015/09/01/making-time-for-personal-development-gold-cards">gold card</a> is a mechanism to reserve time for personal activities.
  Developers can use a gold card to work on anything not related to day-to-day business whenever they want.
  Unfortunately, most of the teams I know that used gold cards had one major problem: Developers never used their gold cards.
</p>
<p>
  I believe the reason for this is that gold cards are hard to plan.
  By definition, they are something special you should only take once a <a href="https://www.atlassian.com/agile/scrum/sprints">sprint</a>/month/etc.
  This means they can easily be seen as a disruption which might be their main disadvantage.
</p>
<p>
  A lot of developers don't use their gold cards because they feel like <em>betraying</em> their team.
  How could that extra work be more important than what was already planned?
  Do other people spend a similar amount of gold cards, or am I selfish?
</p>
<p>I've heard statements like these and others.</p>
<h3 id="hack-weeks">Hack weeks<a aria-hidden="true" tabindex="-1" href="#hack-weeks"><<span></span>></<span></span>></a></h3>
<p>
  A hack week is a planned event during which teams work on improving how they work.
  This can be fixing <a href="/post/thoughts-on-technical-debt-and-continuous-improvement">tech debt</a> issues or automating manual activities.
</p>
<p>
  Hack weeks are better than gold cards because they can be planned ahead of time.
  Therefore, the whole team is on-board, which eliminates the feeling of <em>betraying the team</em>.
  This is great because that's already a significant boost in terms of psychological safety for each individual developer.
</p>
<p>
  The main issue I have with hack weeks is their frequency.
  By definition, you should spend more than one consecutive day.
  This sometimes leads to them being done only once a quarter not to take too much time away from feature work.
  However, what happens to issues that you discover right after a hack week?
  Do they need to wait until the next hack week?
  It could very well be this way.
</p>
<h3 id="hack-fridays">Hack Fridays<a aria-hidden="true" tabindex="-1" href="#hack-fridays"><<span></span>></<span></span>></a></h3>
<p>
  Google <a href="https://en.wikipedia.org/wiki/20%25_Project">did this years ago</a>.
  Every Friday is exempt from standard feature work.
</p>
<p>
  With this approach, you get proper planning (act as if every week only had 4 days) and you get fast iterations (discover an issue on Monday and fix it on Friday).
  The fact that its <em>only</em> one day is both good and bad.
  It is good because it forces you to think small and iterative.
  Since you can't do huge tasks on a Friday, you must figure out the most significant pain point and solve this one.
  However, it can still be that there are larger tasks that you cannot solve on a Friday.
  These still need to go into a proper planning cycle.
  But that isn't bad.
  If you've found a systemic issue, then you shouldn't work on fixing it alone.
  Let the team support you!
</p>
<h3 id="continuous-improvement">Continuous Improvement<a aria-hidden="true" tabindex="-1" href="#continuous-improvement"><<span></span>></<span></span>></a></h3>
<p>
  Experiment and innovate whenever you have the time to do so.
  I've spoken about <a href="https://kanbanzone.com/resources/kanban/wip-limits/">work in progress</a> limits <a href="/post/the-productivity-paradox#the-cost-of-overutilization">a lot</a>.
  If you manage to set up your team so that people aren't busy all the time, you create an environment where there is always time to experiment.
  Just use the time when you can't do feature work anyway.
  Working this way enables people to make minor improvements all the time during day-to-day work.
  It will also allow them to test out new ideas they had while working on a feature.
  Most likely even <strong>immediately</strong> after they have built the feature.
</p>
<h2 id="different-kinds-of-innovation">Different kinds of innovation<a aria-hidden="true" tabindex="-1" href="#different-kinds-of-innovation"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  When I talk to people about innovation, they usually conclude that I'm talking about innovation focused on the product (i.e., new features).
  But that's only a part of the whole picture.
  Innovation can and must happen on all levels taking in feedback from all departments.
</p>
<h3 id="product-innovation">Product innovation<a aria-hidden="true" tabindex="-1" href="#product-innovation"><<span></span>></<span></span>></a></h3>
<p>
  Your <a href="https://www.scrum.org/resources/what-is-a-product-owner">Product Owner</a> (PO) shouldn't be the only person responsible for this topic.
  Make sure that developers have direct access to end-users so that they can come up with creative ways to help people be more productive.
</p>
<p>
  For instance, if developers do some support work for the product, they build, they are likely to discover common mistakes.
  Once they understand the issues of their users, they can also come up with solutions for them.
  The PO can still assist, for instance, by making sure that not every problem is solved through code.
</p>
<h3 id="operations-innovation">Operations innovation<a aria-hidden="true" tabindex="-1" href="#operations-innovation"><<span></span>></<span></span>></a></h3>
<p>
  How we deliver our software is an often overlooked part when it comes to innovation.
  A couple of years ago services like <a href="https://auth0.com/">auth0</a>, <a href="http://vercel.com/">Vercel</a>, <a href="https://www.mongodb.com/cloud/atlas">MongoDB Atlas</a>, or <a href="https://www.netlify.com/">Netlify</a> didn't exist.
  Therefore, we needed to take care of authentication and hosting ourselves.
  Today we can save ourselves a lot of time by reducing the time we spend on these topics.
  This saves a lot of time and makes the experience for our end-users much better.
  For instance, the <a href="https://vercel.com/docs/edge-network/overview">smart CDN</a> from Vercel can make your page load faster across the globe, and you won't have to configure a thing to achieve this.
</p>
<h3 id="process-innovation">Process innovation<a aria-hidden="true" tabindex="-1" href="#process-innovation"><<span></span>></<span></span>></a></h3>
<p>
  Next to making sure that what we're building is excellent, we also need to make sure that <strong>how</strong> we're building it evolves.
  If you haven't changed your process in a couple of months, then this might mean that the process is great.
  But it can also mean that you haven't learned anything during the last months.
  Only if we constantly experiment with our processes and try out new things can we ensure that people are engaged and productive.
</p>
<h2 id="dx-drives-ux">DX drives UX<a aria-hidden="true" tabindex="-1" href="#dx-drives-ux"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  You have probably heard of UX (user experience) but have you heard about <a href="https://medium.com/swlh/what-is-dx-developer-experience-401a0e44a9d9">DX</a> (developer experience)?
  Maybe.
  However, I believe that companies all too often do not understand how vital good DX is.
  Which developer will be more motivated?
  The one that has to wait hours for a build can't run tests locally, and has no insight into production metrics?
  Or the one that can test changes quickly and make decisions based on facts?
  I know that the second developer will almost certainly be the happier one.
  Since happier goes hand in hand with motivated and motivated means engaged, I would claim that the second developer will build the better software.
</p>
<p>The lesson to learn here is that changes that seem far away from where we want to see the innovation can have a significant effect on making them happen.</p>
<p>
  In the end, we need to make sure to create an environment that motivates people to do the right thing.
  Furthermore, we need to make sure that people feel enabled to make decisions on their own.
  If we can achieve this drive in people and add enough context about end-users, then innovation will happen naturally.
  You won't even have to think about it, let alone create <em>initiatives</em> to force it to happen.
</p>
<hr>
<p>
  Developers, do you know of any more practices to foster an environment of experimentation?
  What works at your job, what doesn't?
  Managers, how does this article resonate with you? Some of the things I've said might sound counter-intuitive.
  I still urge you to give them a try.
  What's the worst that could happen?
</p>
<p>As always, feel free to reach out to <a href="https://twitter.com/philgiese">@philgiese</a> on Twitter.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[ Toggle wisely - A story about feature toggles ]]></title>
      <description><![CDATA[ I've written about early integration and why it leads to better features. While this is true you might not want to roll out changes to all users at once. For… ]]></description>
      <link>https://www.philgiese.com/post/how-many-feature-toggles-are-enough</link>
      <guid isPermaLink="false">https://www.philgiese.com/post/how-many-feature-toggles-are-enough</guid>
      <dc:creator>Philipp Giese</dc:creator>
      <pubDate>Mon, 23 Nov 2020 00:00:00 GMT</pubDate>
      <category>process</category>
      <category>architecture</category>
      <category>software-design</category>
      <content:encoded><![CDATA[
<p>
  I've written about <a href="/post/how-early-integration-creates-value-for-your-users">early integration</a> and why it leads to better features.
  While this is true you might not want to roll out changes to all users at once.
  For instance, you might be working on a feature for a very specific target group and want to make sure that once you release it for everyone there are no major hick-ups.
  At the same time, you don't want the source code to diverge and rot on a long-lived branch.
  Enter stage: <em>feature toggles</em>.
</p>
<p>
  Feature toggles allow us to reintegrate new features early but only activate them for certain customers at a time.
  This can be used for beta testing, <a href="https://en.wikipedia.org/wiki/A/B_testing">A/B testing</a>, and more.
</p>
<p>
  That's great until some of our POs required <strong>every</strong> new feature to be behind a toggle.
  This might sound like a reasonable idea but let me explain why I think you should try to keep the number of feature toggles to a minimum.
</p>
<h2 id="tldr">TL;DR<a aria-hidden="true" tabindex="-1" href="#tldr"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  This post is not anti-feature-toggles.
  It's about being aware that feature toggles aren't the silver bullet that people want them to be.
  While they can be extremely useful they can also be used to amplify bad behavior in a broken system.
</p>
<p>When you work with features toggles you'll need to be aware that:</p>
<ul>
  <li><a href="#feature-toggles-are-if-statements-on-steroids">Feature toggles introduce another layer of complexity into your system</a>,</li>
  <li><a href="#when-everything-is-toggled-nothing-is-done">they can hide that more work is in progress than you think</a>, and</li>
  <li><a href="#favor-small-changes-over-a-feature-toggle">that you should favor incremental changes over big features</a></li>
</ul>
<h2 id="feature-toggles-are-if-statements-on-steroids">Feature toggles are if-statements on steroids<a aria-hidden="true" tabindex="-1" href="#feature-toggles-are-if-statements-on-steroids"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Have you heard about <a href="https://en.wikipedia.org/wiki/Cyclomatic_complexity">cyclomatic complexity</a> (also known as McCabe complexity)?
  In a nutshell, this metric tells you how many distinct paths there are in your code<sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref aria-describedby="footnote-label">1</a></sup>.
  For instance, if you have one <code>if</code>-statement then there are two possible paths.
</p>
<ol>
  <li>The <code>if</code>-condition is <code>true</code></li>
  <li>The <code>if</code>-condition is <code>false</code> (i.e. the <code>else</code>-path)</li>
</ol>
<p>
  I think the most basic lecture I give to less experienced engineers is how to reduce the amount of <code>if</code>-statements in code.
  Because the more conditionals there are the harder it is to reason about the code.
</p>
<p>
  Now, if you're on the lookout for this kind of complexity on a method level, then you should definitely be on the lookout on the <strong>feature</strong> level.
  Each feature you're toggling adds a <em>condition</em> to your application.
  One path where the feature is active and another one where it isn't.
</p>
<p>
  What this means is that you'll need to add integration tests for all possible scenarios where different features overlap.
  This can add significant effort to your development process.
  It can also increase the chance of defects that are harder to trace because your production system might have many different feature configurations.
</p>
<h2 id="when-everything-is-toggled-nothing-is-done">When everything is toggled nothing is done<a aria-hidden="true" tabindex="-1" href="#when-everything-is-toggled-nothing-is-done"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  When you're not releasing a feature for everyone this usually means that it is not completely done.
  Maybe you want to evaluate whether a certain hypothesis holds or you need to check whether the performance of the feature is at a level that you're confident with.
</p>
<p>
  Unfortunately, toggled features do not take up space<sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref aria-describedby="footnote-label">2</a></sup> in most development boards I've seen teams use.
  That means that there is no <a href="https://kanbanize.com/kanban-resources/getting-started/what-is-wip">WIP limit</a> on non-<a href="https://www.productplan.com/glossary/general-availability">GA</a> features.
  <strong>Oof</strong>.
  If that's the case then we might have removed bottlenecks from our development process but we've added a monster of a bottleneck at the end.
  This is problematic because we're doing a lot of work and not all users can see it.
  If not all users can use it you're going to miss edge cases.
  When you're missing edge cases you create defects.
</p>
<p>
  Long story short: a feature that is toggled <strong>cannot</strong> be considered done.
  When a feature is not done this should prevent the team from starting something else.
  If this isn't the case you <a href="/post/the-productivity-paradox#the-cost-of-overutilization">have a problem</a>.
</p>
<h2 id="favor-small-changes-over-a-feature-toggle">Favor small changes over a feature toggle<a aria-hidden="true" tabindex="-1" href="#favor-small-changes-over-a-feature-toggle"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>Before you add a feature toggle so that you can hide a new, <strong>big</strong> feature behind it consider the following:</p>
<h3 id="could-you-also-add-a-smaller-version-of-the-feature-without-a-feature-toggle">Could you also add a smaller version of the feature without a feature toggle?<a aria-hidden="true" tabindex="-1" href="#could-you-also-add-a-smaller-version-of-the-feature-without-a-feature-toggle"><<span></span>></<span></span>></a></h3>
<p>
  You probably should not use feature toggles to hide the fact that you're doing <a href="https://svpg.com/big-bang-releases/">big bang releases</a><sup><a href="#user-content-fn-3" id="user-content-fnref-3" data-footnote-ref aria-describedby="footnote-label">3</a></sup>.
  Yes, you're already integrating the feature code back into your codebase.
  But: if no user can use it and, therefore, run the code then how much integration is really happening?
</p>
<p>
  Use a feature toggle when you're unsure whether to add the feature at all.
  Then build a <a href="/post/how-early-integration-creates-value-for-your-users#how-this-relates-to-your-mvp"><strong>minimal</strong></a> version and test it with a dedicated user group.
  Based on that result you either throw it away or continue (in which case you can probably already remove the initial toggle).
  If you're simply hiding regular development behind a toggle then I'd say you're doing it wrong.
</p>
<h3 id="do-you-expect-a-negative-effect-when-your-users-see-the-new-feature">Do you expect a negative effect when your users see the new feature?<a aria-hidden="true" tabindex="-1" href="#do-you-expect-a-negative-effect-when-your-users-see-the-new-feature"><<span></span>></<span></span>></a></h3>
<p>
  Is the feature disruptive?
  Are you, for instance, altering a core user flow inside your application?
  Then that's a good reason to not just roll it out to everybody but to do a small test run (see the section above).
</p>
<p>
  However, if you're adding a new feature which does not impact the general user flow then why are you hiding it?
  You might prevent your users from being more productive faster.
  If there's nothing to test then don't hide it.
</p>
<p>
  Are you not sure whether the feature makes sense at all?
  Then why are you already writing code for it?
  That's a pretty expensive experiment you're running!
  Paper prototypes or tools like <a href="https://www.figma.com/">Figma</a> for high fidelity mock-ups might be a better alternative.
</p>
<h3 id="do-you-add-the-feature-toggle-to-have-fewer-bugs-in-production">Do you add the feature toggle to have fewer bugs in production?<a aria-hidden="true" tabindex="-1" href="#do-you-add-the-feature-toggle-to-have-fewer-bugs-in-production"><<span></span>></<span></span>></a></h3>
<p>
  <strong>Oh boy</strong>.
  I guess this combines both previous sections.
  Where should I start?
</p>
<p><strong>🚨 Feature toggles will not fix a broken development process! 🚨</strong></p>
<p>
  That felt good...
  If you have a problem with too many bugs in production then I'd recommend doing one or more of the following:
</p>
<ul>
  <li>define a <a href="https://sookocheff.com/post/process/zero-bug-policy/">zero-bug policy</a>,</li>
  <li>do <a href="/post/the-religion-of-test-driven-development">TDD</a> (not preaching, read the article 😉),</li>
  <li>make sure that <a href="/post/thoughts-on-technical-debt-and-continuous-improvement">continuous improvement</a> is part of your process,</li>
  <li>fix <a href="/post/how-to-solve-problems">problems instead of symptoms</a>,</li>
  <li>integrate <a href="/post/how-early-integration-creates-value-for-your-users">as early as possible</a></li>
</ul>
<p>
  I'm running out of posts to link here but that list is not exhaustive.
  The key takeaway is that releasing features (either by not having the code online or hidden behind a toggle) will <strong>not</strong> solve your bug problem.
</p>
<hr>
<p>
  What do you think?
  Am I crazy?
  have you seen feature toggles being used for the wrong reasons?
  I'd love to hear your stories!
  Reach out to <a href="https://twitter.com/philgiese">@philgiese</a> on Twitter!
</p>
<section data-footnotes class="footnotes">
  <h2 class="sr-only" id="footnote-label">Footnotes<a aria-hidden="true" tabindex="-1" href="#footnote-label"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
  <ol>
    <li id="user-content-fn-1">
      <p>A certain someone added a longer explanation to his <a href="/about">master's thesis</a> <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩</a></p>
    </li>
    <li id="user-content-fn-2">
      <p>Once again, I'm talking about teams using <a href="https://en.wikipedia.org/wiki/Kanban">Kanban</a>. <a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to reference 2" class="data-footnote-backref">↩</a></p>
    </li>
    <li id="user-content-fn-3">
      <p>Oh hi, <a href="https://en.wikipedia.org/wiki/Waterfall_model">waterfall</a> <a href="#user-content-fnref-3" data-footnote-backref="" aria-label="Back to reference 3" class="data-footnote-backref">↩</a></p>
    </li>
  </ol>
</section>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[ What does a Tech Lead do? ]]></title>
      <description><![CDATA[ I'm transitioning out of my current job as Tech Lead at Signavio. One action item that came out of our last retrospective was that I should compile a list of… ]]></description>
      <link>https://www.philgiese.com/post/responsibilities-of-a-tech-lead</link>
      <guid isPermaLink="false">https://www.philgiese.com/post/responsibilities-of-a-tech-lead</guid>
      <dc:creator>Philipp Giese</dc:creator>
      <pubDate>Mon, 09 Nov 2020 00:00:00 GMT</pubDate>
      <category>leadership</category>
      <category>tech-lead</category>
      <category>reflection</category>
      <content:encoded><![CDATA[
<p>
  I'm transitioning out of my current job as Tech Lead at <a href="https://www.signavio.com">Signavio</a>.
  One action item that came out of our last <a href="https://www.scrum.org/resources/what-is-a-sprint-retrospective">retrospective</a> was that I should compile a list of my responsibilities.
  That does make sense, given that I won't be around come December.
  However, I <strong>don't</strong> have a list of recurring activities.
  So, this blog post isn't necessarily about what <em>any</em> Tech Lead does, but what <em>I</em> as a Tech Lead do.
</p>
<h2 id="tldr">TL;DR<a aria-hidden="true" tabindex="-1" href="#tldr"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  This time there won't be a TL;DR.
  If you think there is a shortcut to becoming a good leader, then you've opened the wrong article.
</p>
<h2 id="do-not-become-a-bottleneck">Do not become a bottleneck<a aria-hidden="true" tabindex="-1" href="#do-not-become-a-bottleneck"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  I've heard that some people think they need to be involved in everything when they are leaders.
  I couldn't disagree more!
  You need to trust your people and let them do their jobs.
  Otherwise, you'll <a href="/post/the-productivity-paradox#busy-%E2%89%A0-productive">always be busy, which means you probably will never be productive</a>.
</p>
<p>On a high level, I need to be aware of everything that is happening around me.</p>
<ul>
  <li>What projects are in progress?</li>
  <li>What's up next?</li>
  <li>Is the team blocked in any way?</li>
  <li>Is the infrastructure up and running?</li>
  <li>Do we need to work on any critical updates?</li>
</ul>
<p>
  Because I have to make sure that everything runs smoothly, I can't get deeply involved with one topic in particular.
  Even if I'm working on an essential feature, I cannot wholly neglect all other aspects of my job.
  The result would be that I will be in a situation where I'm responsible for the most crucial feature, but I'm doing something else.
  That's not good!
</p>
<p>
  I'm trying<sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref aria-describedby="footnote-label">1</a></sup> to avoid this situation by not working on <a href="https://en.wikipedia.org/wiki/User_story">user stories</a>.
  Well, at least I don't pull them into the "In progress" column<sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref aria-describedby="footnote-label">2</a></sup>.
  By doing so, I can still <a href="https://en.wikipedia.org/wiki/Pair_programming">pair program</a> with other developers, but the chances that someone is waiting for me to finish a story are pretty low.
</p>
<h2 id="help-others-to-grow-and-learn">Help others to grow and learn<a aria-hidden="true" tabindex="-1" href="#help-others-to-grow-and-learn"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  If you're not helping others become better at what they do, I would not consider you a leader.
  Unfortunately, I also had to learn that doing so is easier said than done.
  Here are some mistakes I've made.
</p>
<h3 id="handing-out-solutions-like-free-candy">Handing out solutions like free candy<a aria-hidden="true" tabindex="-1" href="#handing-out-solutions-like-free-candy"><<span></span>></<span></span>></a></h3>
<p>
  When someone asks you a question, your first intention might be to answer it.
  That's normal.
  <strong>But</strong> when you do this, you rob them of an opportunity to learn.
  Because solely when you get to a solution yourself, and you understand all the steps it took to get there, then you learn something.
  Otherwise, you might learn to ask me again the next time you face a similar challenge.
  And that doesn't scale!
</p>
<p>
  I've come up with my own <a href="/post/how-to-solve-problems">set of rules to solve problems</a>, and I'm now trying to teach them.
  I'll ask questions like "What did you try already?" or "What do you know? What do you not know?".
  These questions should help your brain figure out the problem on its own.
</p>
<h3 id="if-one-person-needs-to-learn-something-everybody-can-learn-something">If one person needs to learn something everybody can learn something<a aria-hidden="true" tabindex="-1" href="#if-one-person-needs-to-learn-something-everybody-can-learn-something"><<span></span>></<span></span>></a></h3>
<p>
  Pair programming is nice.
  <a href="https://en.wikipedia.org/wiki/Mob_programming">Mob programming</a> is better!
</p>
<p>
  At first, when we ventured into a new area, the new knowledge was restricted to the one or two people who worked on the first user story.
  It's better than nothing, but we still needed to do the initial onboarding into the topic a couple of times.
  This led to different people understanding the problem in different ways and lots of rework.
  When a new topic is on the horizon, we have a team session upfront to make sure everyone is on the same page and understands the problem.
  We (usually) also start working on the topic together.
  This means the whole team works on the first user story.
  Stuff like this sounds like we're wasting much time, but I'd argue that we're saving much time because there are fewer misunderstandings and rework.
</p>
<h3 id="not-being-aware-of-how-im-perceived">Not being aware of how I'm perceived<a aria-hidden="true" tabindex="-1" href="#not-being-aware-of-how-im-perceived"><<span></span>></<span></span>></a></h3>
<p>
  Not only do the things you say matter, but also <strong>how</strong> you say them.
  I had to learn that sometimes even exhaling too loudly could stress the other person and prevent them from learning anything.
  What helped me the most was learning about <a href="/post/non-violent-communication">non-violent communication</a> and how I can use it to make people more comfortable around me.
  It also helped me understand that I need to be clear about my needs because it also does not help if I get frustrated.
</p>
<p>Also, do not <a href="/post/non-violent-communication#demands-and-requests">disguise requests as demands</a>.</p>
<h2 id="help-people-make-more-minor-mistakes">Help people make more minor mistakes<a aria-hidden="true" tabindex="-1" href="#help-people-make-more-minor-mistakes"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Bugs happen.
  Mistakes happen.
  However, you can actively help your team reduce the severity of them.
</p>
<p>
  When shit hits the fan, the most important thing to do is to <strong>stay calm</strong>.
  It never helps to start rushing work in the middle of a crisis.
  As soon as the crisis is over, you need to make sure it can't happen again.
  For that to work out, two things need to happen:
</p>
<ul>
  <li>Everyone needs to understand <strong>what</strong> happened and <strong>why</strong> it happened.</li>
  <li>You need to check whether a change to your team's processes would prevent the thing from happening again.</li>
</ul>
<p>
  Your job is to make sure both actions are taken.
  You don't have to do all the explaining or propose adjustments.
  However, you should be the one who makes sure that these activities are taken care of.
</p>
<p>Here is a non-exhaustive list of things our team does (and I blogged about) to avoid large scale defects.</p>
<ul>
  <li>We do <a href="https://en.wikipedia.org/wiki/Test-driven_development">TDD</a> <a href="/post/the-religion-of-test-driven-development">as much as possible</a>,</li>
  <li>we write tests that <a href="/post/tests-that-help-you-find-defects-faster">help us find and fix defects faster</a>,</li>
  <li>we always <a href="/post/how-to-solve-problems">get to the bottom of problems</a>, and</li>
  <li>we <a href="/post/thoughts-on-technical-debt-and-continuous-improvement">continuously improve</a> how we work.</li>
</ul>
<h2 id="make-others-more-productive">Make others more productive<a aria-hidden="true" tabindex="-1" href="#make-others-more-productive"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  I've seen some people interpret this as "make any other person, inside your team, with a technical focus more productive."
  Unfortunately, that excludes <strong>a lot</strong> of other people that you might interact with each day.
  Here are two groups of people you might be excluding even though you shouldn't.
</p>
<h3 id="do-you-help-your-product-owner">Do you help your product owner?<a aria-hidden="true" tabindex="-1" href="#do-you-help-your-product-owner"><<span></span>></<span></span>></a></h3>
<p>OK, you can ignore this part if you don't have a <a href="https://www.scrum.org/resources/what-is-a-product-owner">product owner</a> (PO).</p>
<p>
  My team has a great PO.
  She tries her best to be always approachable and get as much structured feedback as possible from our customers.
  In the past, she also wrote most of our user stories.
  The issue is that writing user stories isn't necessarily what she should be doing most of her time.
  Why?
  Because she needs to both write the story and then explain it when a developer picks it up.
  That can be cumbersome.
</p>
<p>
  We've also faced situations where stories were split in a way that makes sense for the end-user but didn't consider our system design.
  That sometimes left us spending more work on two stories than would have been needed if it would have been only one.
</p>
<p>
  We've talked about this and restructured the process so that developers write stories themselves after we've had a session in which we made sure everyone understands the problem we're trying to solve.
  Our PO is the facilitator for these sessions.
  This way, questions are asked and answered in a larger group.
</p>
<h3 id="do-you-integrate-design-into-the-development-flow">Do you integrate design into the development flow?<a aria-hidden="true" tabindex="-1" href="#do-you-integrate-design-into-the-development-flow"><<span></span>></<span></span>></a></h3>
<p>Admittedly, I haven't figured this one out yet.</p>
<p>
  I try to remove hand-offs as much as possible.
  I find the idea of a hand-off somewhat appalling because it implies that some people can think everything through and then are done.
  I've never seen this work.
</p>
<p>
  Our designers are doing a great job.
  However, they are also humans and, therefore, forget things or make mistakes.
  When they work on a design for two weeks, then hand it over, and an engineer discovers that this will never work they've just wasted <strong>a lot</strong> of time.
  I'd love to see that designers and developers collaborate and work on these features <strong>together</strong>.
</p>
<p>
  But... I haven't found the magic spell to make this work.
  What I try is to lead by example.
</p>
<ul>
  <li>I try to get our designer involved early in the process,</li>
  <li>I make it clear that nothing is ever set in stone, and we'll always be able to change things, and</li>
  <li>I try to instill a sense of incremental development in designers (I've found that some of them are somewhat resistant to that idea)</li>
</ul>
<p>By doing the above, I hope that, over time, both designers and developers will treat each other as equals and collaborate more closely.</p>
<h2 id="reserve-some-room-for-self-reflection">Reserve some room for self-reflection<a aria-hidden="true" tabindex="-1" href="#reserve-some-room-for-self-reflection"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Even though I might risk repeating myself, let me say that again: You should not be busy all the time.
  In your role as Tech Lead, you also need to reserve the room to think and reflect.
</p>
<p>
  I sometimes re-read comments I made on PRs when I had a stressful day.
  The chances are high that my stress level leaked into my tone while writing<sup><a href="#user-content-fn-3" id="user-content-fnref-3" data-footnote-ref aria-describedby="footnote-label">3</a></sup>.
  If others feel bad because I had a bad day, then this sucks.
  Since I don't want to be that person, I try to correct my wrongs whenever possible.
</p>
<p>
  Also, blogging helped me a lot this year.
  To write a post, I need to get my thoughts in order first.
  Sometimes I also need to visualize certain parts of my thought process.
  That allows others to look into my head, but it also helps me think about the person I'd like to be.
  I think while writing about <a href="/goal-setting">goals</a>, <a href="/process">processes</a>, and <a href="/communication">communication</a>, I've also reflected on what I did wrong in the past and would like to do in the future.
</p>
<hr>
<p>
  This time I'd like to emphasize even more that I appreciate any form of feedback regarding this article.
  Please reach out to <a href="https://twitter.com/philgiese">@philgiese</a> with questions, remarks, and ideas to try out when leading development teams.
</p>
<section data-footnotes class="footnotes">
  <h2 class="sr-only" id="footnote-label">Footnotes<a aria-hidden="true" tabindex="-1" href="#footnote-label"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
  <ol>
    <li id="user-content-fn-1">
      <p>
        Of course, I work on the occasional user story.
        There is always an exception to the rule.
        The most important aspect is that I'm aware of what's going on around me. <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩</a>
      </p>
    </li>
    <li id="user-content-fn-2">
      <p>
        We're working with <a href="https://en.wikipedia.org/wiki/Kanban_(development)">Kanban</a>, which means tickets progress through different stages.
        When someone picks up a ticket to work on it, it will move into the "In progress" column so that everyone sees that work is happening. <a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to reference 2" class="data-footnote-backref">↩</a>
      </p>
    </li>
    <li id="user-content-fn-3">
      <p>Tools like <a href="https://www.grammarly.com/">Grammarly</a> can help you with that. <a href="#user-content-fnref-3" data-footnote-backref="" aria-label="Back to reference 3" class="data-footnote-backref">↩</a></p>
    </li>
  </ol>
</section>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[ How early integration creates value for your users ]]></title>
      <description><![CDATA[ Have you worked on a larger project? Maybe something that required you to work in more than one code base or more than one package? Then you might have already… ]]></description>
      <link>https://www.philgiese.com/post/how-early-integration-creates-value-for-your-users</link>
      <guid isPermaLink="false">https://www.philgiese.com/post/how-early-integration-creates-value-for-your-users</guid>
      <dc:creator>Philipp Giese</dc:creator>
      <pubDate>Tue, 20 Oct 2020 00:00:00 GMT</pubDate>
      <category>process</category>
      <category>feedback</category>
      <category>lean</category>
      <content:encoded><![CDATA[
<p>
  Have you worked on a larger project?
  Maybe something that required you to work in more than one code base or more than one package?
  Then you might have already encountered situations in which you needed to take a problem apart into pieces.
  This is by no means an easy task.
  And that is what makes it interesting. 😄
</p>
<p>
  I'm going to assume that when you're faced with a problem you're going to split it into smaller chunks.
  There are lots of ways how to do this <sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref aria-describedby="footnote-label">1</a></sup>.
  While there are no wrong decisions, some might be better than the others.
  Because we're not solely taking a problem apart, we're looking for ways how to <a href="#deliver-value-faster">deliver value faster</a> and <a href="#identify-wrong-assumptions-earlier">reduce risk</a>.
</p>
<h2 id="tldr">TL;DR<a aria-hidden="true" tabindex="-1" href="#tldr"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  In a nutshell, this article is about <a href="https://en.wikipedia.org/wiki/Lean_software_development#Deliver_as_fast_as_possible">Lean development</a>.
  I believe you should always do as much as needed and as little as possible to get the current task done.
  By doing this you <a href="#deliver-value-faster">decrease the time-to-value</a> for your users.
  When you do more you're placing bets on whether your <a href="#identify-wrong-assumptions-earlier">current assumptions are right</a>.
  Sometimes these bets will play out and sometimes they won't.
  The trick is to be aware of the risks you're taking.
</p>
<p>Especially when you're <a href="#how-this-relates-to-your-mvp">creating something new</a> and you want to test out ideas you need to make sure that you're not wasting time on the non-essential parts.</p>
<h2 id="deliver-value-faster">Deliver value faster<a aria-hidden="true" tabindex="-1" href="#deliver-value-faster"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  I believe that we all create software to make other people happier or more productive.
  Maybe our software lets people create things faster or helps them avoid certain mistakes.
  However, sometimes developers believe that <em>solely</em> a <strong>100%</strong> complete feature accomplishes this job.
  Otherwise, your customer might hit that edge case the developer knows of and this is not acceptable <sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref aria-describedby="footnote-label">2</a></sup>.
  At the same time, you might have heard about the <a href="https://en.wikipedia.org/wiki/Pareto_principle">Pareto principle</a>.
  According to it, you're going to build 80% of a feature in 20% of the time.
  Vice versa this means that 80% of your time is required to build the last 20% of the feature.
</p>
<p>I got a couple of questions for you.</p>
<ul>
  <li>Is the real customer value in the last 20%</li>
  <li>If <strong>yes</strong>: Why didn't you start with them?</li>
  <li>If <strong>no</strong>: Why let the customer wait?</li>
</ul>
<p>
  Ask yourself "Why would I let my customer wait 80% of the time if the good part of a feature is already done?"
  I'm pretty certain that the first 80% include useful functionality.
  If we release these features once they are ready we can help our customers faster.
</p>
<h2 id="identify-wrong-assumptions-earlier">Identify wrong assumptions earlier<a aria-hidden="true" tabindex="-1" href="#identify-wrong-assumptions-earlier"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Once you are able to deliver value faster you'll also shorten the feedback loop.
  Even better, since the changes you're going to roll out will be smaller you can also get more focused feedback.
  That's great.
</p>
<p>
  Imagine you're building a design system.
  You'll probably start by defining the colors and some basic rules for typography.
  After you've done this, would you place a bet that these definitions will <strong>not</strong> change while you build the rest?
  Are you also sure that they don't <strong>already</strong> conflict with what people have done so far (i.e. while the design system was not around)?
  I would claim that the safe way would be to take solely these changes and roll them out.
  You'll probably get a lot of feedback and find some issues.
  Fixing them now shouldn't be that hard since there is nothing else in the design system yet.
  If you would have built buttons, form components, etc. and only rolled out the design system once it was "done" this situation might be different.
</p>
<p>
  The worst thing that can happen to you isn't that you need to fix a lot of components.
  It would be that people reject the design system completely because they can't fit it into their daily job.
  This would mean all of the time and effort you've put into creating the design system is wasted.
</p>
<p>
  By making sure we're rolling out changes constantly and in small batches, we can keep our bets small.
  This reduces the risks we're taking at a time.
  The smaller the risks the higher the chances that everything will play out in the end<sup><a href="#user-content-fn-3" id="user-content-fnref-3" data-footnote-ref aria-describedby="footnote-label">3</a></sup>.
</p>
<h2 id="reduce-waste">Reduce waste<a aria-hidden="true" tabindex="-1" href="#reduce-waste"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  When we deliver faster and verify our assumptions early on we're making sure that we're not wasting time.
  Neither ours nor the time of our customers.
  In order for this to work, it must be OK to acknowledge that we don't know <strong>everything</strong>.
  That is fine.
  Nobody does.
  Even if they claim they do.
  Yes, I'm looking at you <a href="https://www.enricdurany.com/agile-startup-entrepreneur/hippos-highest-paid-person-opinion-data-driven-decision-making">HiPPO</a>.
</p>
<p>
  Should you speak with your customer whenever you're unsure about something?
  Maybe.
  Personally, if the impact of the decision is large and hard to reverse then go ahead and talk to them.
  If the impact is small though and the decision can be easily reverted then it might also be fine to just go with a gut feeling.
  The important part is to know when to do what and to also document that somewhere.
  Because our time is also valuable and we should spend it with the efforts that are likely to create the most value.
</p>
<h2 id="how-this-relates-to-your-mvp">How this relates to your MVP<a aria-hidden="true" tabindex="-1" href="#how-this-relates-to-your-mvp"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  An MVP or <a href="https://en.wikipedia.org/wiki/Minimum_viable_product">minimum viable product</a> is something you built to, for instance, test a hypothesis.
  The hypothesis can be about a feature, user behavior, or anything else really.
  The important part is that you want to spend <strong>as little time as possible</strong> to figure out whether your hypothesis is correct or incorrect.
</p>
<p>
  I'd like to add that you also don't want to build them in a way that they are in your way when you decide to move forward.
  Why do I say that?
  Because I often hear people describe them as prototypes.
  However, I think you should throw away a prototype after you've used it to figure something out.
  MVPs, on the other hand, are a starting point that you want to eventually grow into something bigger.
  That's why I would even call it <strong>harmful</strong> to treat them as if they were prototypes.
</p>
<p>
  <img src="/posts/how-early-integration-creates-value-for-your-users/slicing-options.png" alt="Effect on MVP">
</p>
<p>
  Let's have a look at the image above.
  It describes two different ways to slice a larger feature into an MVP (the colored parts are what will be included in the MVP).
</p>
<p>
  Option <strong>A</strong> doesn't look too bad.
  Build some of the foundation (because we said we're not going to throw away the MVP) and add some features on top of that.
  To get to the finish line faster we're not going to include delighters<sup><a href="#user-content-fn-4" id="user-content-fnref-4" data-footnote-ref aria-describedby="footnote-label">4</a></sup> though.
  If you decide to take this approach I'm generally on your side.
  <strong>But</strong> do we really need to build that much of the foundation <em>now</em>?
  Sometimes developers creep more features into the foundation <em>because</em> we said that we're not going to throw it away.
  Yes, but <strong>only</strong> if we figure out it makes sense.
  If the result of our experiment is that no one wants that feature, we're still going to remove it.
  So by creating a foundation for a <em>possible</em> future we're hoping that all our assumptions won't change.
  Even worse, once we've built it we might fall victim to <a href="https://en.wikipedia.org/wiki/Confirmation_bias">confirmation bias</a> and only accept the feedback that lets us keep it.
</p>
<p>
  <strong>Update 2020-11-25:</strong> I've just rediscovered this picture which brilliantly shows a bad MVP.
  Functionality is all there but would you use it?
</p>
<p>
  <img src="/posts/how-early-integration-creates-value-for-your-users/bad-mvp.jpg" alt="Bad MVP">
</p>
<p>
  When you focus mostly on the foundation and not on the user and how you might even delight them what are your really validating here?
  I've seen a lot of MVPs that have been built like this.
  Users like to reject them because the features they offer are oftentimes worse than what is already there.
  I would argue that's due to the fact that there was little work on the things that <strong>matter</strong> to the users and a lot of work on the things that <strong>matter</strong> to the developer.
  The developers used the MVP mostly to validate some technical aspects.
  And when they ran out of time, they shipped what they had and the user wasn't happy.
  If you work like this I'd say you're setting yourself up for failure.
</p>
<p>
  By now you might have guessed what is different about option <strong>B</strong>.
  Here, we're looking at one use case end-to-end.
  We're going to do what is necessary to make sure the foundation for the feature is good.
  However, we're not going to make assumptions about the next feature just now.
  Then, we're going to use the time we just saved and use it to build something that highlights the extra value this feature is supposed to create.
  By doing this we're making sure that the value proposition reaches our users.
  Now we can truly validate whether we're on the correct path or not.
</p>
<hr>
<p>
  Creating the right slice of a new feature to test an assumption might be the most difficult skill I have yet to master.
  In the end, everyone wants to do the right thing but sometimes these intentions conflict with each other.
  Navigating these conflicts without hurting people's feelings can be extremely difficult.
</p>
<p>
  How do you tackle this kind of task?
  Do you agree that releasing small and often is the right approach?
  As always, I'm keen to hear other opinions.
  Reach out to <a href="https://twitter.com/philgiese">@philgiese</a> on Twitter.
</p>
<section data-footnotes class="footnotes">
  <h2 class="sr-only" id="footnote-label">Footnotes<a aria-hidden="true" tabindex="-1" href="#footnote-label"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
  <ol>
    <li id="user-content-fn-1">
      <p>If you're working with user stories, you might find <a href="https://agile-mercurial.com/2019/04/25/how-do-you-split-user-stories/">this article</a> helpful. <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩</a></p>
    </li>
    <li id="user-content-fn-2">
      <p>
        My rule of thumb is to not argue out of an edge case.
        If you do, then this can easily lead to a situation where you spend most of your time on the parts that people will most likely not encounter.
        This takes away precious time from the features you should actually be focusing on. <a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to reference 2" class="data-footnote-backref">↩</a>
      </p>
    </li>
    <li id="user-content-fn-3">
      <p>
        If your risks are low and the chances increase that you're building the right thing then this sometimes also means that planning becomes easier.
        Since you're not doing a lot of rework as you keep your batches small you might be able to make better estimates.
        However, you've never heard me say this. <a href="#user-content-fnref-3" data-footnote-backref="" aria-label="Back to reference 3" class="data-footnote-backref">↩</a>
      </p>
    </li>
    <li id="user-content-fn-4">
      <p>
        Delighters are features that, strictly speaking, are not necessary but add that little extra that gets your feature from being good to great.
        For instance, my car has small lights in its rear mirrors that project the logo onto the street when I open the door.
        Does this add value? No. Do I love it and show it to everyone whether they want to see it or not? Absolutely! <a href="#user-content-fnref-4" data-footnote-backref="" aria-label="Back to reference 4" class="data-footnote-backref">↩</a>
      </p>
    </li>
  </ol>
</section>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[ Undo-redo and its effects on your architecture ]]></title>
      <description><![CDATA[ It's a running joke at Signavio that the product I'm working on does not support undo and redo. And even though we built the tool with redux we're still… ]]></description>
      <link>https://www.philgiese.com/post/undo-redo-architecture</link>
      <guid isPermaLink="false">https://www.philgiese.com/post/undo-redo-architecture</guid>
      <dc:creator>Philipp Giese</dc:creator>
      <pubDate>Mon, 12 Oct 2020 00:00:00 GMT</pubDate>
      <category>software-design</category>
      <category>architecture</category>
      <category>example</category>
      <content:encoded><![CDATA[
<p>
  It's a running joke at <a href="https://www.signavio.com/">Signavio</a> that the product I'm working on does not support undo and redo.
  And even though we built the tool with <a href="https://redux.js.org/">redux</a> we're still struggling to get that functionality in.
  I'm not going to bore you with the details of why it's hard for us but over the <em>years</em>(!) I got an idea of why it might be hard, in general, to get features like undo-redo into an existing app.
  The good news is that I believe there are steps you can take to make it easier.
</p>
<h2 id="tldr">TL;DR<a aria-hidden="true" tabindex="-1" href="#tldr"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>I've built a library called <a href="https://github.com/frontendphil/react-undo-redo">react-undo-redo</a>. Check it out on GitHub. 😄</p>
<p>
  However, this post is more about architecture than it is about undo-redo.
  The topic is a good example to showcase how certain choices for your architecture can help you built new features faster.
  Also, you'll see how small decisions can have large impacts.
  So, go ahead and learn about:
</p>
<ul>
  <li><a href="#the-basics-of-undo-and-redo">The principles behind undo-redo</a>,</li>
  <li><a href="#how-your-state-access-might-cause-you-trouble">that your components should not care about how they get their data</a>, and</li>
  <li><a href="#extract-concerns-to-make-your-life-easier">that some concerns are better handled in isolation.</a></li>
</ul>
<h2 id="the-basics-of-undo-and-redo">The basics of undo and redo<a aria-hidden="true" tabindex="-1" href="#the-basics-of-undo-and-redo"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Let's imagine an application that processes state updates.
  If there is no notion of undoing or redoing then any update will create a new state which represents the current present.
  If you happen to <a href="https://www.youtube.com/watch?v=xsSnOQynTHs">use reducers</a> then you might have encountered this as
</p>
<pre class="language-js"><code class="language-js code-highlight"><span class="code-line"><span class="token function">f</span><span class="token punctuation">(</span><span class="token parameter">state<span class="token punctuation">,</span> action</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> state<span class="token operator">*</span>
</span></code></pre>
<p>
  <img src="/posts/undo-redo-architecture/without-undo-redo.png" alt="Without undo-redo">
</p>
<p>
  Every time something happens inside our app we create a new present state.
  By doing this we also disregard any information about what came before.
  It becomes clear that to undo an action we'll need to keep track of our past and also our future (that's redo).
</p>
<p>
  <img src="/posts/undo-redo-architecture/undo-redo-basics.png" alt="Undo-redo basics">
</p>
<p>
  The most basic implementation I know to built undo-redo is to introduce two <a href="https://en.wikipedia.org/wiki/Stack_(abstract_data_type)">stacks</a> next to the present state.
  One stack keeps track of what happened before and the other stack tracks what would happen next.
  I like to use stacks because they best fit my mental model.
  This way we're coming from the past, move over to the present, and into the future.
  You could also use arrays and always append to the end but this would make popping items just that tiny bit harder.
</p>
<p>With the above data structure in place, we need to establish some ground rules for how we want to work with it.</p>
<h3 id="progressing-the-present">Progressing the present<a aria-hidden="true" tabindex="-1" href="#progressing-the-present"><<span></span>></<span></span>></a></h3>
<p>Whenever an action happens that is neither "undo" nor "redo" we need to first move the <em>current</em> present into the past and then create a <em>new</em> present which is our updated application state.</p>
<p>
  <img src="/posts/undo-redo-architecture/move-present-around.png" alt="Progressing the present">
</p>
<p>
  With every user action, we also need to clear the <code>future</code> stack.
  That's mostly to save ourselves from having some bad headaches.
  If we would not do that then with every "redo" we would need to figure out which of our possible futures we're going to choose.
  Everyone who has ever watched <a href="https://en.wikipedia.org/wiki/Back_to_the_Future">Back to the future</a> knows that you don't want to do that.
</p>
<p>
  By the way, I'm not talking about redux actions or reducers here.
  When I'm talking about actions in this article I mean "the user has done something and our application state is somehow updated".
  It's important to understand this to not get tricked into thinking undo-redo can solely be built with a redux based architecture.
</p>
<h3 id="undo">Undo<a aria-hidden="true" tabindex="-1" href="#undo"><<span></span>></<span></span>></a></h3>
<p>
  You might have guessed already what is going to happen when we undo an action.
  When this happens we're going to take the most recent item that's in the past stack and make it our present.
  Also, we're pushing the current present into the future stack (that's important for redo).
</p>
<p>
  <img src="/posts/undo-redo-architecture/undo.png" alt="Undo">
</p>
<h3 id="redo">Redo<a aria-hidden="true" tabindex="-1" href="#redo"><<span></span>></<span></span>></a></h3>
<p>
  When we "redo" an action we're making the immediate future our current present and the current present becomes the past again.
  Are you still with me?
  This is usually the point where I've made sure I've lost everyone in the room.
</p>
<p>
  <img src="/posts/undo-redo-architecture/redo.png" alt="Redo">
</p>
<p>Now that I've confused you let's move on to the actual topic of this blog post: the effect this has on your application architecture.</p>
<h2 id="how-your-state-access-might-cause-you-trouble">How your state access might cause you trouble<a aria-hidden="true" tabindex="-1" href="#how-your-state-access-might-cause-you-trouble"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  For this section let's assume you have an architecture that uses a reducer and actions for state handling.
  Also, I'm going to use the classic "counter" example to keep it simple in here even though we all know the real world can be much harder.
  Without any notion of undo nor redo we have come up with the following code.
</p>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token keyword module">import</span> <span class="token imports"><span class="token maybe-class-name">React</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> useReducer <span class="token punctuation">}</span></span> <span class="token keyword module">from</span> <span class="token string">"react"</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">function</span> <span class="token function">counterReducer</span><span class="token punctuation">(</span><span class="token parameter">state<span class="token punctuation">,</span> action</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">switch</span> <span class="token punctuation">(</span>action<span class="token punctuation">.</span><span class="token property-access">type</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token keyword">case</span> <span class="token string">"increment"</span><span class="token operator">:</span>
</span><span class="code-line">      <span class="token keyword control-flow">return</span> state <span class="token operator">+</span> <span class="token number">1</span>
</span><span class="code-line">    <span class="token keyword">case</span> <span class="token string">"decrement"</span><span class="token operator">:</span>
</span><span class="code-line">      <span class="token keyword control-flow">return</span> state <span class="token operator">-</span> <span class="token number">1</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">function</span> <span class="token function"><span class="token maybe-class-name">Counter</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword">const</span> <span class="token punctuation">[</span>count<span class="token punctuation">,</span> dispatch<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useReducer</span><span class="token punctuation">(</span>counterReducer<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token punctuation">(</span>
</span><span class="code-line">    <span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span></span><span class="token punctuation">></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      Count: </span><span class="token punctuation">{</span>count<span class="token punctuation">}</span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token function">dispatch</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"decrement"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">-</span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span>button</span><span class="token punctuation">></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token function">dispatch</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"increment"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">+</span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span>button</span><span class="token punctuation">></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span></span><span class="token punctuation">></span></span>
</span><span class="code-line">  <span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  What implications would it have if we would add undo-redo functionality to our application?
  Quite a lot I would say.
  We need to ask ourselves a couple of questions.
</p>
<ul>
  <li>Do we want the <code>counterReducer</code> to "know" that there is a <code>past</code>, <code>present</code>, and <code>future</code> state?</li>
  <li>If the <code>count</code> state would be used in multiple places in our application, would we want all consumers to know about the <code>past</code> and <code>future</code> bits as well?</li>
  <li>What impact would it have if we later decide to use a different approach to get undo-redo working?</li>
</ul>
<p>
  Personally, the last question got me thinking the most.
  You might have read my post about <a href="/post/what-is-cohesion-and-why-should-you-care">cohesion</a> and the section about <a href="/post/what-is-cohesion-and-why-should-you-care#afferent-and-efferent-coupling">different kinds of coupling</a>.
  If we would decide to make the application aware of the past and the present then this would mean a large value for afferent coupling.
  In other words, undo-redo then will be coupled to everything else in our application.
  Stuff like this keeps me awake in the evenings.
  It just sounds wrong.
</p>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token keyword module">import</span> <span class="token imports"><span class="token maybe-class-name">React</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> useReducer <span class="token punctuation">}</span></span> <span class="token keyword module">from</span> <span class="token string">"react"</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">function</span> <span class="token function">counterReducer</span><span class="token punctuation">(</span><span class="token parameter">state<span class="token punctuation">,</span> action</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">switch</span> <span class="token punctuation">(</span>action<span class="token punctuation">.</span><span class="token property-access">type</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token keyword">case</span> <span class="token string">"increment"</span><span class="token operator">:</span>
</span><span class="code-line">      <span class="token keyword control-flow">return</span> <span class="token punctuation">{</span>
</span><span class="code-line highlight-line">        <span class="token literal-property property">past</span><span class="token operator">:</span> <span class="token punctuation">[</span>state<span class="token punctuation">.</span><span class="token property-access">present</span><span class="token punctuation">,</span> <span class="token spread operator">...</span>state<span class="token punctuation">.</span><span class="token property-access">past</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
</span><span class="code-line highlight-line">        <span class="token literal-property property">present</span><span class="token operator">:</span> state<span class="token punctuation">.</span><span class="token property-access">present</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span>
</span><span class="code-line highlight-line">        <span class="token literal-property property">future</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
</span><span class="code-line">      <span class="token punctuation">}</span>
</span><span class="code-line">    <span class="token keyword">case</span> <span class="token string">"decrement"</span><span class="token operator">:</span>
</span><span class="code-line">      <span class="token keyword control-flow">return</span> <span class="token punctuation">{</span>
</span><span class="code-line highlight-line">        <span class="token literal-property property">past</span><span class="token operator">:</span> <span class="token punctuation">[</span>state<span class="token punctuation">.</span><span class="token property-access">present</span><span class="token punctuation">,</span> <span class="token spread operator">...</span>state<span class="token punctuation">.</span><span class="token property-access">past</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
</span><span class="code-line highlight-line">        <span class="token literal-property property">present</span><span class="token operator">:</span> state<span class="token punctuation">.</span><span class="token property-access">present</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">,</span>
</span><span class="code-line highlight-line">        <span class="token literal-property property">future</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
</span><span class="code-line">      <span class="token punctuation">}</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">function</span> <span class="token function"><span class="token maybe-class-name">Counter</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line highlight-line">  <span class="token keyword">const</span> <span class="token punctuation">[</span><span class="token punctuation">{</span> <span class="token literal-property property">present</span><span class="token operator">:</span> count <span class="token punctuation">}</span><span class="token punctuation">,</span> dispatch<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useReducer</span><span class="token punctuation">(</span>counterReducer<span class="token punctuation">,</span> <span class="token punctuation">{</span>
</span><span class="code-line highlight-line">    <span class="token literal-property property">past</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
</span><span class="code-line highlight-line">    <span class="token literal-property property">present</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
</span><span class="code-line highlight-line">    <span class="token literal-property property">future</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
</span><span class="code-line highlight-line">  <span class="token punctuation">}</span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token punctuation">(</span>
</span><span class="code-line">    <span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span></span><span class="token punctuation">></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      Count: </span><span class="token punctuation">{</span>count<span class="token punctuation">}</span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token function">dispatch</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"increment"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">+</span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span>button</span><span class="token punctuation">></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token function">dispatch</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"decrement"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">-</span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span>button</span><span class="token punctuation">></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span></span><span class="token punctuation">></span></span>
</span><span class="code-line">  <span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  I pondered some time about this topic and why it bothered me.
  After a while, it struck me.
  Of course, it had nothing to do with undo-redo.
  What I believe we often times get "wrong" (at least to a certain degree) is to move logic too close to the primitives (e.g. <a href="https://reactjs.org/docs/hooks-reference.html#usereducer">useReducer</a>) that manage our state.
</p>
<p>Alright, I'll explain.</p>
<p>
  Given its name, the <code>Counter</code> component should solely concern itself with counting.
  However, by directly using <code>useReducer</code> it also deals with state management on a very detailed level.
  The component "knows" that state is handled by a reducer.
  By coupling the view with how the state is managed we make it harder to change any one of these concerns.
  Luckily, <a href="https://en.wikipedia.org/wiki/Indirection">every problem in software can be solved by adding a layer of indirection</a>.
</p>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token keyword module">import</span> <span class="token imports"><span class="token maybe-class-name">React</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> useReducer <span class="token punctuation">}</span></span> <span class="token keyword module">from</span> <span class="token string">"react"</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">function</span> <span class="token function">counterReducer</span><span class="token punctuation">(</span><span class="token parameter">state<span class="token punctuation">,</span> action</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">switch</span> <span class="token punctuation">(</span>action<span class="token punctuation">.</span><span class="token property-access">type</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token keyword">case</span> <span class="token string">"increment"</span><span class="token operator">:</span>
</span><span class="code-line">      <span class="token keyword control-flow">return</span> state <span class="token operator">+</span> <span class="token number">1</span>
</span><span class="code-line">    <span class="token keyword">case</span> <span class="token string">"decrement"</span><span class="token operator">:</span>
</span><span class="code-line">      <span class="token keyword control-flow">return</span> state <span class="token operator">-</span> <span class="token number">1</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line highlight-line"><span class="token keyword">function</span> <span class="token function">useCounter</span><span class="token punctuation">(</span><span class="token parameter">initialCount</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line highlight-line">  <span class="token keyword">const</span> <span class="token punctuation">[</span>count<span class="token punctuation">,</span> dispatch<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useReducer</span><span class="token punctuation">(</span>counterReducer<span class="token punctuation">,</span> initialCount<span class="token punctuation">)</span>
</span><span class="code-line highlight-line">
</span><span class="code-line highlight-line">  <span class="token keyword control-flow">return</span> <span class="token punctuation">[</span>count<span class="token punctuation">,</span> dispatch<span class="token punctuation">]</span>
</span><span class="code-line highlight-line"><span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">function</span> <span class="token function"><span class="token maybe-class-name">Counter</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line highlight-line">  <span class="token keyword">const</span> <span class="token punctuation">[</span>count<span class="token punctuation">,</span> dispatch<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useCounter</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token punctuation">(</span>
</span><span class="code-line">    <span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span></span><span class="token punctuation">></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      Count: </span><span class="token punctuation">{</span>count<span class="token punctuation">}</span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token function">dispatch</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"increment"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">+</span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span>button</span><span class="token punctuation">></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token function">dispatch</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"decrement"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">-</span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span>button</span><span class="token punctuation">></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span></span><span class="token punctuation">></span></span>
</span><span class="code-line">  <span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  The new <code>useCounter</code> hook creates an abstraction that helps us to decouple the component from the details of the sate.
  With this change, we can make changes to how the state and reducers work without breaking the component.
  In other words, the <code>Counter</code> component does no longer <strong>care</strong>.
  However, the reducer still cares.
  A lot.
</p>
<h2 id="extract-concerns-to-make-your-life-easier">Extract concerns to make your life easier<a aria-hidden="true" tabindex="-1" href="#extract-concerns-to-make-your-life-easier"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  In the last section, we decoupled our component code from the state.
  This way we could add undo-redo functionality without needing to make the component aware of that.
  However, the reducer would need quite some adjustments.
</p>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token keyword">function</span> <span class="token function">counterReducer</span><span class="token punctuation">(</span><span class="token parameter">state<span class="token punctuation">,</span> action</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">switch</span> <span class="token punctuation">(</span>action<span class="token punctuation">.</span><span class="token property-access">type</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token keyword">case</span> <span class="token string">"increment"</span><span class="token operator">:</span>
</span><span class="code-line">      <span class="token keyword control-flow">return</span> <span class="token punctuation">{</span>
</span><span class="code-line highlight-line">        <span class="token literal-property property">past</span><span class="token operator">:</span> <span class="token punctuation">[</span>state<span class="token punctuation">.</span><span class="token property-access">present</span><span class="token punctuation">,</span> <span class="token spread operator">...</span>state<span class="token punctuation">.</span><span class="token property-access">past</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
</span><span class="code-line highlight-line">        <span class="token literal-property property">present</span><span class="token operator">:</span> state<span class="token punctuation">.</span><span class="token property-access">present</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span>
</span><span class="code-line highlight-line">        <span class="token literal-property property">future</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
</span><span class="code-line">      <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">    <span class="token keyword">case</span> <span class="token string">"decrement"</span><span class="token operator">:</span>
</span><span class="code-line">      <span class="token keyword control-flow">return</span> <span class="token punctuation">{</span>
</span><span class="code-line highlight-line">        <span class="token literal-property property">past</span><span class="token operator">:</span> <span class="token punctuation">[</span>state<span class="token punctuation">.</span><span class="token property-access">present</span><span class="token punctuation">,</span> <span class="token spread operator">...</span>state<span class="token punctuation">.</span><span class="token property-access">past</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
</span><span class="code-line highlight-line">        <span class="token literal-property property">present</span><span class="token operator">:</span> state<span class="token punctuation">.</span><span class="token property-access">present</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">,</span>
</span><span class="code-line highlight-line">        <span class="token literal-property property">future</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
</span><span class="code-line">      <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">    <span class="token keyword">case</span> <span class="token string">"undo"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
</span><span class="code-line">      <span class="token keyword">const</span> <span class="token punctuation">[</span>present<span class="token punctuation">,</span> <span class="token spread operator">...</span>past<span class="token punctuation">]</span> <span class="token operator">=</span> state<span class="token punctuation">.</span><span class="token property-access">past</span>
</span><span class="code-line">
</span><span class="code-line">      <span class="token keyword control-flow">return</span> <span class="token punctuation">{</span>
</span><span class="code-line">        past<span class="token punctuation">,</span>
</span><span class="code-line">        present<span class="token punctuation">,</span>
</span><span class="code-line">        <span class="token literal-property property">future</span><span class="token operator">:</span> <span class="token punctuation">[</span>state<span class="token punctuation">.</span><span class="token property-access">present</span><span class="token punctuation">,</span> <span class="token spread operator">...</span>state<span class="token punctuation">.</span><span class="token property-access">future</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
</span><span class="code-line">      <span class="token punctuation">}</span>
</span><span class="code-line">    <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">    <span class="token keyword">case</span> <span class="token string">"redo"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
</span><span class="code-line">      <span class="token keyword">const</span> <span class="token punctuation">[</span>present<span class="token punctuation">,</span> <span class="token spread operator">...</span>future<span class="token punctuation">]</span> <span class="token operator">=</span> state<span class="token punctuation">.</span><span class="token property-access">future</span>
</span><span class="code-line">
</span><span class="code-line">      <span class="token keyword control-flow">return</span> <span class="token punctuation">{</span>
</span><span class="code-line">        <span class="token literal-property property">past</span><span class="token operator">:</span> <span class="token punctuation">[</span>state<span class="token punctuation">.</span><span class="token property-access">present</span><span class="token punctuation">,</span> <span class="token spread operator">...</span>state<span class="token punctuation">.</span><span class="token property-access">past</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
</span><span class="code-line">        present<span class="token punctuation">,</span>
</span><span class="code-line">        future<span class="token punctuation">,</span>
</span><span class="code-line">      <span class="token punctuation">}</span>
</span><span class="code-line">    <span class="token punctuation">}</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  If you'd ask me that is a lot of overhead in there.
  Have a look at the handlers for <code>increment</code> and <code>decrement</code>.
  Except for the <code>present</code> bit they are the same.
  By making our reducer aware of the undo-redo feature we're going to have to do a lot of extra typing in the future.
  Unless, of course, we have the final realization in this blog post.
  Your reducers probably also <strong>do not need to care</strong> about undo-redo.
</p>
<p>
  Your reducers "live" in the present.
  So, why should they care about the past or the future?
  <code>past</code> and <code>future</code> are concepts that <strong>only</strong> undo-redo should be aware of.
  Otherwise, we're back to needing to change all reducers whenever we change something around undo-redo.
</p>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token keyword">function</span> <span class="token function">createUndoRedo</span><span class="token punctuation">(</span><span class="token parameter">presentReducer</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token keyword">function</span> <span class="token function">undoRedoReducer</span><span class="token punctuation">(</span><span class="token parameter">state<span class="token punctuation">,</span> action</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token keyword control-flow">switch</span> <span class="token punctuation">(</span>action<span class="token punctuation">.</span><span class="token property-access">type</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">      <span class="token keyword">case</span> <span class="token string">"undo"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
</span><span class="code-line">        <span class="token keyword">const</span> <span class="token punctuation">[</span>present<span class="token punctuation">,</span> <span class="token spread operator">...</span>past<span class="token punctuation">]</span> <span class="token operator">=</span> state<span class="token punctuation">.</span><span class="token property-access">past</span>
</span><span class="code-line">
</span><span class="code-line">        <span class="token keyword control-flow">return</span> <span class="token punctuation">{</span>
</span><span class="code-line">          past<span class="token punctuation">,</span>
</span><span class="code-line">          present<span class="token punctuation">,</span>
</span><span class="code-line">          <span class="token literal-property property">future</span><span class="token operator">:</span> <span class="token punctuation">[</span>state<span class="token punctuation">.</span><span class="token property-access">present</span><span class="token punctuation">,</span> <span class="token spread operator">...</span>state<span class="token punctuation">.</span><span class="token property-access">future</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
</span><span class="code-line">        <span class="token punctuation">}</span>
</span><span class="code-line">      <span class="token punctuation">}</span>
</span><span class="code-line">      <span class="token keyword">case</span> <span class="token string">"redo"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
</span><span class="code-line">        <span class="token keyword">const</span> <span class="token punctuation">[</span>present<span class="token punctuation">,</span> <span class="token spread operator">...</span>future<span class="token punctuation">]</span> <span class="token operator">=</span> state<span class="token punctuation">.</span><span class="token property-access">future</span>
</span><span class="code-line">
</span><span class="code-line">        <span class="token keyword control-flow">return</span> <span class="token punctuation">{</span>
</span><span class="code-line">          <span class="token literal-property property">past</span><span class="token operator">:</span> <span class="token punctuation">[</span>state<span class="token punctuation">.</span><span class="token property-access">present</span><span class="token punctuation">,</span> <span class="token spread operator">...</span>state<span class="token punctuation">.</span><span class="token property-access">past</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
</span><span class="code-line">          present<span class="token punctuation">,</span>
</span><span class="code-line">          future<span class="token punctuation">,</span>
</span><span class="code-line">        <span class="token punctuation">}</span>
</span><span class="code-line">      <span class="token punctuation">}</span>
</span><span class="code-line">      <span class="token keyword module">default</span><span class="token operator">:</span> <span class="token punctuation">{</span>
</span><span class="code-line">        <span class="token keyword control-flow">return</span> <span class="token punctuation">{</span>
</span><span class="code-line">          <span class="token literal-property property">past</span><span class="token operator">:</span> <span class="token punctuation">[</span>state<span class="token punctuation">.</span><span class="token property-access">present</span><span class="token punctuation">,</span> <span class="token spread operator">...</span>state<span class="token punctuation">.</span><span class="token property-access">past</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
</span><span class="code-line">          <span class="token literal-property property">present</span><span class="token operator">:</span> <span class="token function">presentReducer</span><span class="token punctuation">(</span>state<span class="token punctuation">.</span><span class="token property-access">present</span><span class="token punctuation">,</span> action<span class="token punctuation">)</span><span class="token punctuation">,</span>
</span><span class="code-line">          <span class="token literal-property property">future</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
</span><span class="code-line">        <span class="token punctuation">}</span>
</span><span class="code-line">      <span class="token punctuation">}</span>
</span><span class="code-line">    <span class="token punctuation">}</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  Using the above <code>createUndoRedo</code> method we can enhance <strong>any</strong> other reducer and give it undo-redo powers.
  All without the need to make the reducer (or reducers) aware of this feature.
  How would this change our application code?
</p>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token keyword module">import</span> <span class="token imports"><span class="token maybe-class-name">React</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> useReducer <span class="token punctuation">}</span></span> <span class="token keyword module">from</span> <span class="token string">"react"</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">function</span> <span class="token function">counterReducer</span><span class="token punctuation">(</span><span class="token parameter">state<span class="token punctuation">,</span> action</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">switch</span> <span class="token punctuation">(</span>action<span class="token punctuation">.</span><span class="token property-access">type</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token keyword">case</span> <span class="token string">"increment"</span><span class="token operator">:</span>
</span><span class="code-line">      <span class="token keyword control-flow">return</span> state <span class="token operator">+</span> <span class="token number">1</span>
</span><span class="code-line">    <span class="token keyword">case</span> <span class="token string">"decrement"</span><span class="token operator">:</span>
</span><span class="code-line">      <span class="token keyword control-flow">return</span> state <span class="token operator">-</span> <span class="token number">1</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">function</span> <span class="token function">useCounter</span><span class="token punctuation">(</span><span class="token parameter">initialCount</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line highlight-line">  <span class="token keyword">const</span> <span class="token punctuation">[</span><span class="token punctuation">{</span> <span class="token literal-property property">present</span><span class="token operator">:</span> count <span class="token punctuation">}</span><span class="token punctuation">,</span> dispatch<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useReducer</span><span class="token punctuation">(</span>
</span><span class="code-line highlight-line">    <span class="token function">createUndoRedo</span><span class="token punctuation">(</span>counterReducer<span class="token punctuation">)</span><span class="token punctuation">,</span>
</span><span class="code-line highlight-line">    <span class="token punctuation">{</span>
</span><span class="code-line highlight-line">      <span class="token literal-property property">past</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
</span><span class="code-line highlight-line">      <span class="token literal-property property">present</span><span class="token operator">:</span> initialCount<span class="token punctuation">,</span>
</span><span class="code-line highlight-line">      <span class="token literal-property property">future</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
</span><span class="code-line highlight-line">    <span class="token punctuation">}</span>
</span><span class="code-line highlight-line">  <span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token punctuation">[</span>count<span class="token punctuation">,</span> dispatch<span class="token punctuation">]</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">function</span> <span class="token function"><span class="token maybe-class-name">Counter</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword">const</span> <span class="token punctuation">[</span>count<span class="token punctuation">,</span> dispatch<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useCounter</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token punctuation">(</span>
</span><span class="code-line">    <span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span></span><span class="token punctuation">></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      Count: </span><span class="token punctuation">{</span>count<span class="token punctuation">}</span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token function">dispatch</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"increment"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">+</span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span>button</span><span class="token punctuation">></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token function">dispatch</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"decrement"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">-</span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span>button</span><span class="token punctuation">></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span></span><span class="token punctuation">></span></span>
</span><span class="code-line">  <span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  By extracting the concern of the undo-redo feature we can limit its effect on our implementation.
  The whole notion that we want something to be undoable is encapsulated inside the <code>useCounter</code> hook.
  This makes sense since, ultimately, this hook defines where the state lives and what shape it has.
  Since this is the place where we use <code>createUndoRedo</code> it's also reasonable that this hooks "knows" about the <code>present</code> part of the state.
  The important part still is that with this abstraction none of our reducers and none of our components need to know about this.
</p>
<p>
  While I was writing this post I thought this would make a nice and small side-project.
  Enter stage: <a href="https://github.com/frontendphil/react-undo-redo">react-undo-redo</a>, available today.
</p>
<hr>
<p>
  When do you use abstractions to better design your applications?
  Do you think I've made reasonable decisions or would you have done things differently?
  Let know <a href="https://www.twitter.com/philgiese">on Twitter</a>.
</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[ Thoughts on technical debt and continuous improvement ]]></title>
      <description><![CDATA[ Lately, I've come across a couple of blog posts like "Most Technical Debt Is Just Bullshit" and "Technical Debt Isn’t Real". They're discussing whether we… ]]></description>
      <link>https://www.philgiese.com/post/thoughts-on-technical-debt-and-continuous-improvement</link>
      <guid isPermaLink="false">https://www.philgiese.com/post/thoughts-on-technical-debt-and-continuous-improvement</guid>
      <dc:creator>Philipp Giese</dc:creator>
      <pubDate>Tue, 06 Oct 2020 00:00:00 GMT</pubDate>
      <category>process</category>
      <category>technical-debt</category>
      <category>software-design</category>
      <category>productivity</category>
      <content:encoded><![CDATA[
<p>
  Lately, I've come across a couple of blog posts like <a href="https://louwrentius.com/most-technical-debt-is-just-bullshit.html">"Most Technical Debt Is Just Bullshit"</a> and <a href="https://medium.com/swlh/technical-debt-isnt-real-8803ce021caa">"Technical Debt Isn’t Real"</a>.
  They're discussing whether we twisted the <a href="http://wiki.c2.com/?WardExplainsDebtMetaphor">initial definition</a> of technical debt to mean anything and thus nothing.
  People have since then asked me about my opinion on the topic.
  So, here it is.
</p>
<p>
  Before I start I'd like to state one thing I particularly don't like about any of those articles: Their catchy but aggressive titles.
  I've written about <a href="/post/non-violent-communication">non-violent communication</a> and I believe that if you want to have an earnest discussion you can't use such titles.
  This article contains my thoughts on the topic and I'm trying to keep emotion out of it.
</p>
<h2 id="tldr">TL;DR<a aria-hidden="true" tabindex="-1" href="#tldr"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  I believe that when people argue about the <a href="#what-is-technical-debt">definition of technical debt</a> this is <a href="/post/how-to-solve-problems">a symptom</a> of a larger organizational problem.
  If engineering teams are not <a href="#engaged-teams">empowered to make decisions</a> on their own this can lead to large-scale problems that no product manager will be able to solve.
  We need to acknowledge that it's <a href="#avoiding-technical-debt">impossible to avoid technical debt</a> and we should, therefore, design our development process in a way to reduce it every day.
  One way of doing this is through <a href="#continuous-improvement">continuous improvement</a> which can come in all sorts and flavors.
  In the end, it doesn't matter so much what we improve but that we're improving the system because the alternative is doing nothing and this will always hurt us.
</p>
<h2 id="what-is-technical-debt">What is technical debt?<a aria-hidden="true" tabindex="-1" href="#what-is-technical-debt"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  If you build a house today you'll have to renew the paint roughly ten years from now.
  This does neither mean that you were sloppy today nor that the paint you picked is bad.
  The paint wears off over time and at some point, you will need to redo it.
  Not the people or the tools are your enemies; time is.
</p>
<p>
  <a href="https://hilton.org.uk/">Peter Hilton</a> once told me "The moment you write a line of code you also put an expiry date on it".
  For me, this is what technical debt is all about.
  Making sure to refactor code before it reaches its expiry date.
  Because when this happens you end up in a situation where:
</p>
<ul>
  <li>developers aren't familiar with the used technology anymore,</li>
  <li>the system around the code has changed so drastically that it might be impossible to adjust, or</li>
  <li>it seems easier to rewrite the code instead of refactoring it (which means duplicate work).</li>
</ul>
<p>In short, by not making sure that you update your code before it expires you create <a href="https://en.wikipedia.org/wiki/Lean_software_development#Eliminate_waste">waste</a>.</p>
<h2 id="taking-on-technical-debt">Taking on technical debt<a aria-hidden="true" tabindex="-1" href="#taking-on-technical-debt"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  During my career, I got to see software development both from the perspective of an engineer and of a product manager.
  I've used a language that I would not use today and I've also heard other people make statements that sounded wrong in the past and ring all my alarms today.
  Let me give you an example.
</p>
<blockquote>
  <p>As a product manager, you need to know when to take up technical debt</p>
</blockquote>
<p>
  This single sentence might summarize everything that can be wrong in a company.
  I believe that as a product manager you should:
</p>
<ul>
  <li>make sure that the team(s) you're working with understand the problems they're trying to solve,</li>
  <li>that they have access to the customers who use their product, and</li>
  <li>that you are able to answer all the questions around problems and features they might have.</li>
</ul>
<p>
  Should you be telling them <strong>how</strong> to solve these problems?
  Even more, that they <strong>should</strong> take on technical debt?
  <a href="https://www.youtube.com/watch?v=j4ovbmsp6p0">I doubt it</a>.
</p>
<p>I now think that the real meaning of the statement above is</p>
<blockquote>
  <p>As a product manager, you need to make sure the team cuts corners to get those features delivered faster.</p>
</blockquote>
<p>
  But this doesn't sound so good if you'd actually say it out loud.
  Even worse, this has nothing to do with technical debt.
  This is asking the team to ignore defects in the software to gain the <strong>illusion</strong> of speed.
  It's a bit like stating that breaks make a car heavier, and, therefore, slower so why not remove them?
</p>
<h2 id="engaged-teams">Engaged teams<a aria-hidden="true" tabindex="-1" href="#engaged-teams"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Even if a product manager makes such statements this shouldn't affect the product.
  Why?
  Because it's still the engineers who build the product.
  They decide what to type into their editor.
  So, what might be the reason that teams still struggle with the topic?
</p>
<blockquote>
  <p>Product management never prioritizes work to reduce technical debt.</p>
</blockquote>
<p>
  And they don't have to.
  If you'd ask me I'd like the product manager to stay focussed on the customer.
  When an engineer says something like that I think in most scenarios it's because the team isn't empowered to make its own decisions.
  They might be used to a process where managers make decisions and the team then does the work.
  The company might even like this way of working.
  However, if you don't make sure that you listen to your engineers then it is only a matter of time until your software rushes past its expiry date.
</p>
<p>
  The issue with refactoring is that the benefits are not as obvious as product managers would like them to be.
  You try to improve your code <strong>before</strong> it causes issues and this is hard to report on.
  Because you would need to measure the time <strong>not</strong> spent.
  That's an impossible task.
</p>
<p>
  You will not be able to fix this with any spreadsheet.
  The only way out of this is trust.
</p>
<ul>
  <li>Trust your engineers that they want to do a great job,</li>
  <li>trust the teams that they prioritize the right work at the right time, and</li>
  <li>make sure the team has access to all information it needs to make these decisions.</li>
</ul>
<h2 id="avoiding-technical-debt">Avoiding technical debt<a aria-hidden="true" tabindex="-1" href="#avoiding-technical-debt"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  I don't think there is a way to avoid technical debt.
  However, you can avoid bad code.
  Here's how I suggest doing that.
</p>
<h3 id="reduce-scope-not-quality">Reduce scope not quality<a aria-hidden="true" tabindex="-1" href="#reduce-scope-not-quality"><<span></span>></<span></span>></a></h3>
<p>
  There will probably never be enough time to build <strong>all</strong> the features.
  So, when faced with a deadline I'd suggest to rather reduce the scope of the feature.
  Never "save" time by reducing quality.
  Because when you reduce the scope of the feature you still ship software that works.
  This means that when you continue with the next feature you don't have to spend a lot of time fixing what is already out there.
  In other words, you can continue to move at a steady pace.
</p>
<p>
  When you reduce the quality of your software it means that you're most like busy fixing bugs you don't know about after you have shipped the initial version.
  This takes away time from any further feature development.
  If this means that the next deadline is also at risk you find yourself on a downward spiral where you spend most of your time fixing bugs and not building features.
</p>
<h3 id="zero-bug-policy">Zero-bug policy<a aria-hidden="true" tabindex="-1" href="#zero-bug-policy"><<span></span>></<span></span>></a></h3>
<p>
  One way of getting ahead of the management game can be a zero-bug policy.
  I would guess that it's pretty hard to argue against such a policy.
  It also gives the teams some leverage as long as they are the ones who decide what a bug is and what isn't.
  By immediately fixing bugs when you find them you make sure that you're always working on the best foundation possible at any given time.
  This usually leads to better software quality in general.
</p>
<p>
  Also, this can lead to more time for feature development even though this might seem counter-intuitive at the beginning.
  Because when you make sure there are no unresolved known bugs then you also reduce the risk of "surprises".
  Any unresolved bug comes with a risk that something larger and unknown isn't working properly.
  However, if all bugs are resolved you reduce this risk as much as possible.
</p>
<h2 id="continuous-improvement">Continuous improvement<a aria-hidden="true" tabindex="-1" href="#continuous-improvement"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Everything I wrote above boils down to one basic rule.
  Never stop improving your software.
  Technical improvements are not projects or initiatives.
  They are something the team has to constantly do.
  Compare it to cleaning your bathroom.
  You wouldn't do that only once a quarter (at least I wouldn't).
</p>
<p>A couple of techniques I've used in the past are:</p>
<h3 id="boy-scout-rules">Boy Scout rules<a aria-hidden="true" tabindex="-1" href="#boy-scout-rules"><<span></span>></<span></span>></a></h3>
<p>
  I've constantly used this rule.
  Essentially it means that you should always leave a place a bit tidier than you found it.
  While this is also a good rule in the real-world it also helps to keep a software project up-to-date.
</p>
<p>
  For instance, we have the rule to remove <a href="https://lodash.com/">lodash</a> methods for <code>filter</code>, <code>map</code>, <code>reduce</code>, etc, and replace them with their respective native counterparts.
  I did not want to turn this into a full-blown project because there is no big immediate benefit.
  In the long term, this means we're getting rid of a library that is no longer needed and can reduce our bundle size.
  Also, while <code>lodash</code> might be known amongst developers right now this does not have to be true in the future so we're making sure that we're slowly but steadily getting rid of it.
</p>
<h3 id="funny-fridays">Funny Fridays<a aria-hidden="true" tabindex="-1" href="#funny-fridays"><<span></span>></<span></span>></a></h3>
<p>
  On any given Friday the members of my team are free to work on any experiments they'd like to.
  This means they can test out a new library, spike on a refactoring, or try to build a feature they think is awesome.
  If they choose to not use the time that's also fine.
</p>
<p>
  What I'm trying to do is give them a dedicated space to explore new ideas.
  Whether they're doing this is up to them.
  However, I'm also trying to lead by example and pitch ideas I have for possible new "Friday projects".
</p>
<h3 id="reduce-team-utilization">Reduce team utilization<a aria-hidden="true" tabindex="-1" href="#reduce-team-utilization"><<span></span>></<span></span>></a></h3>
<p>
  I've previously blogged about the <a href="/post/the-productivity-paradox#the-cost-of-overutilization">difference between being busy and being productive</a>.
  If the team is busy all the time then there is no time for reflection and improvement.
  That's why I believe you need to create an environment that prevents people from being busy all the time.
  Similar to "funny Fridays" this helps to create an environment where improvements can happen more naturally.
</p>
<hr>
<p>
  How is technical debt handled at your company?
  Do you have more rituals you'd like to see listed in this article?
  I'm interested in hearing about them!
</p>
<p>
  You're a product manager and disagree with what I said?
  Also, please reach out and let's talk.
  I'm always interested in hearing other opinions.
</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[ Violent communication ]]></title>
      <description><![CDATA[ This post is brought to you by Jonathan Soifer. Well, at least without him I wouldn't be able to write it. Jonathan was my manager at Signavio and when I… ]]></description>
      <link>https://www.philgiese.com/post/non-violent-communication</link>
      <guid isPermaLink="false">https://www.philgiese.com/post/non-violent-communication</guid>
      <dc:creator>Philipp Giese</dc:creator>
      <pubDate>Tue, 22 Sep 2020 00:00:00 GMT</pubDate>
      <category>nvc</category>
      <category>communication</category>
      <category>leadership</category>
      <content:encoded><![CDATA[
<p>
  This post is brought to you by <a href="https://www.linkedin.com/in/jaysoifer/">Jonathan Soifer</a>.
  Well, at least without him I wouldn't be able to write it.
  Jonathan was my manager at <a href="https://www.signavio.com/">Signavio</a> and when I received the feedback that I sometimes come across as too aggressive he recommended reading <a href="https://www.goodreads.com/book/show/71730.Nonviolent_Communication">the nonviolent communication (NVC) book</a>.
  At first, it sounded like one of these mushy books that I definitively do not want to read.
  But I trust Jonathan and so I straight up ordered it.
</p>
<h2 id="tldr">TL;DR<a aria-hidden="true" tabindex="-1" href="#tldr"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  <strong>Read it.</strong>
  Sometimes you need another person to tell you something so that you can reflect better.
  This is what this book does.
  And it does it in a great way.
</p>
<p>
  After you've read it you're probably never going to communicate in the same way again.
  Also, this book reduced my personal stress level by an order of magnitude at least.
  It does this by teaching you to approach situations where someone else is aggressive towards you slightly differently.
  But it's that slightly different approach that creates a huge difference in your reaction.
</p>
<p>In this post I'd like to focus on my top takeaways so far:</p>
<ul>
  <li><a href="#describing-without-judging">being able to describe a situation without judging it</a>,</li>
  <li><a href="#say-what-you-need">clearly formulating what I need and expect from others</a>, and</li>
  <li><a href="#demands-and-requests">understanding when "No" is a perfectly sensible answer</a></li>
</ul>
<h2 id="describing-without-judging">Describing without judging<a aria-hidden="true" tabindex="-1" href="#describing-without-judging"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Imagine you're living with someone else.
  You go into the kitchen and there is a stench in the air.
  It can't be that your housemate did not take out the garbage <strong>again</strong>, can it?
  You open up the drawer and flies come swarming out.
</p>
<p>
  Now, you might have already heard that it doesn't help if you snap at the other person (even though this might be what you <strong>want</strong> to do).
  Instead, you should describe the situation so that the two of you can talk about it and not get into a fight.
  You call your housemate into the kitchen, pull yourself together, and say...
</p>
<blockquote>
  <p>You never take out the garbage!</p>
</blockquote>
<p>
  But to your surprise, your housemate does not acknowledge their mistake.
  You make out a flash of surprise on their face before they reply...
</p>
<blockquote>
  <p>So? You never put down the toilet seat!</p>
</blockquote>
<p>
  This didn't quite go as planned, didn't it?
  What happened?
</p>
<p>
  You did not solely describe the situation, you were judgemental.
  When you exclaimed that they <strong>never</strong> do something (and probably they took out the garbage <em>at least</em> once) you put them into a corner.
  In this situation, all they could do is become defensive.
  From there on it's much harder to have a sensible discussion with them.
</p>
<p>Here's an alternative.</p>
<blockquote>
  <p>For the last 3 weeks you have not taken out the garbage.</p>
</blockquote>
<p>
  Now you're stating facts.
  This doesn't drive them into a corner and they can respond better.
  For instance, your housemate could now respond with:
</p>
<blockquote>
  <p>
    You're right.
    The last couple of weeks were really stressful for me because I had to study for a very important test.
    I probably have neglected a lot of things because of that.
  </p>
</blockquote>
<p>With this extra information, you can explain that while you acknowledge that this is a stressful situation for them and you're happy to help them you also need them to take out the trash from time to time because you need the kitchen to be clean.</p>
<p>Being able to state what we're experiencing without judging the other side is an important step when you embark on the journey to nonviolent communication.</p>
<h2 id="say-what-you-need">Say what you need<a aria-hidden="true" tabindex="-1" href="#say-what-you-need"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Being able to clearly express what you need is important.
  I had to learn that I didn't always state my needs and feelings in a way that was helping the conversation.
  You might have already heard that when you're in a stressful situation you should describe your emotions to help the other party understand what you're going through.
  If done properly this can be a valuable tool.
  But as so often in life things are a bit more complicated than they might seem at first.
</p>
<p>Let's look at an example.</p>
<blockquote>
  <p>I feel frustrated when you're on the phone while we pair-program.</p>
</blockquote>
<p>
  Sounds good, right?
  You described the situation, and you mentioned your feelings.
  The other person should now be able to change their behavior in a way that defuses the situation.
</p>
<p>
  Unfortunately not.
  Imagine the other person now puts away their phone but starts reading a magazine instead.
  Would this make you less frustrated?
  My guess is it wouldn't.
  Right now you imply that the actions of the other person are solely responsible for your feelings.
  But in most cases, this is not true.
  Usually, there is a <strong>need</strong> hidden somewhere.
</p>
<p>I'm gonna rephrase the above statement a little.</p>
<blockquote>
  <p>I feel frustrated when you're on the phone while pair-programming because I want to avoid rework through a second pair of eyes.</p>
</blockquote>
<p>
  Now the statement contains a clear need.
  By stating that you want to avoid rework the other person knows your intentions.
  When you communicate your needs and connect them to your feelings you enable the other person to act towards your needs.
  For instance, your pair programming partner could help you write tests so that you build a safety net while you code.
</p>
<h2 id="demands-and-requests">Demands and requests<a aria-hidden="true" tabindex="-1" href="#demands-and-requests"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  This one is my favorite.
  Because a lot of people (in my experience often times managers) <strong>demand</strong> something but disguise it as a <strong>request</strong>.
  I'll show you what I mean.
</p>
<blockquote>
  <p>Can you deliver this feature by next Friday?</p>
</blockquote>
<p>
  What do you think?
  Is this a request or a demand?
  The statement is phrased like a request.
  Why?
  Because it leaves the option to say "No".
  If I don't think I can deliver that particular feature by next Friday I need to say "No" to this question.
  When the person who asked the question then gets angry they actually made a demand.
  The way they should have phrased this is:
</p>
<blockquote>
  <p>Deliver this feature by next Friday.</p>
</blockquote>
<p>You could still say "No" but you would know from the start that if you do this will become a bigger discussion.</p>
<p>
  In our day-to-day communication, we need to be careful to not issue demands as requests.
  Even more so we should learn to not be disappointed when people reject our requests.
  Every time you formulate something as a request ask yourself "Am I OK with when this request is rejected?".
  If the answer to this question is <em>no</em> then you need to think about whether you actually demand that something is being done.
  When this is the case you need to make sure that you are <a href="#say-what-you-need">clear about your needs</a> and <a href="#describing-without-judging">not judgemental</a>.
</p>
<p>
  I reflected a lot about how I talk to people and I've found myself requesting things when I was actually demanding them.
  NVC helped me understand the issues with this approach.
  It's a tool I can use every day to make my life and the life of my co-workers less stressful.
</p>
<hr>
<p>
  Did this article help you reflect on how you communicate every day?
  Have you also not been clear about your needs and sometimes judged others when you should have described a situation?
  Do you already use nonviolent communication?
  I'm curious to hear about your experiences.
  Send a tweet to <a href="https://www.twitter.com/philgiese">@philgiese</a> on Twitter.
</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[ Interview review: Paths between two points ]]></title>
      <description><![CDATA[ I've quit my current job and am going through the interview process for a couple of companies. Since I'm applying for a technical role I have to take the… ]]></description>
      <link>https://www.philgiese.com/post/interview-review-paths-between-two-points</link>
      <guid isPermaLink="false">https://www.philgiese.com/post/interview-review-paths-between-two-points</guid>
      <dc:creator>Philipp Giese</dc:creator>
      <pubDate>Mon, 14 Sep 2020 00:00:00 GMT</pubDate>
      <category>coding-challenge</category>
      <category>hiring</category>
      <category>interviews</category>
      <content:encoded><![CDATA[
<p>
  I've quit my current job and am going through the interview process for a couple of companies.
  Since I'm applying for a technical role I have to take the occasional technical interview.
  Having done a lot of these myself (as an interviewer) I was looking forward to how other people will do that.
</p>
<p>
  Let's look at one of the interviews in more detail.
  I'm going to explain what I like and what I didn't enjoy as much.
</p>
<h2 id="tldr">TL;DR<a aria-hidden="true" tabindex="-1" href="#tldr"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Full disclosure: my result was that I'm <strong>not</strong> a lead developer because the interviewer was not convinced that I had understood the problem and wasn't even sure that I understood the solution in the end.
  I had a good laugh when the responsible HR person broke the news (because I'm pretty high up my arse).
  So this post might be a bit biased towards shining a good light on me.
  I'll try to point out where I believe I made mistakes as well as the other way round.
</p>
<p>Please tweet <a href="https://twitter.com/philgiese">@philgiese</a> with your feedback.</p>
<h2 id="the-challenge">The challenge<a aria-hidden="true" tabindex="-1" href="#the-challenge"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  The task I got was to create an algorithm that counts the number of paths between two points on a grid.
  I do have to admit that my enthusiasm immediately went out of the window.
  My best guess is that I will never have to do anything even remotely related to this challenge when I work for that company.
  Why test me with that task?
</p>
<p>
  <img src="/posts/interview-review-paths-between-two-points/challenge.png" alt="Illustration of the challenge">
</p>
<p>
  To reduce the scope of the problem there is a rule that you can only move to the right or to the top.
  This means that <code>A</code> can never be higher up or farther to the right than <code>B</code>.
  I was happy to hear this so that I didn't have to think about these scenarios anymore.
</p>
<p>A couple of examples were then added to clarify what the test was looking for.</p>
<p>
  <img src="/posts/interview-review-paths-between-two-points/number-of-paths.png" alt="Examples of paths">
</p>
<p>
  Admittedly, I have improved these examples here a bit.
  The ones I was looking at had no color coding.
  Also, the six paths example was missing.
  Here, the interviewer asked me "Can you see the six paths?".
  Obviously, I could not <strong>see</strong> the paths because they weren't there.
  I started drawing lines with my finger on my screen and then proclaimed "Yes, I can see six paths.".
</p>
<p>I'll add these interruptions any time I think the flow of the interview could have been better.</p>
<p>
  This was the first occurrence when I wished for an online whiteboard like <a href="https://miro.com/">Miro</a>.
  We started using it at work and I can't imagine a remote-life without it anymore.
</p>
<p>
  I thought about getting a pen and paper but as my interviewers wouldn't be able to see what I doodle in front of me I ditched the idea.
  For now, I was left with my imagination.
  Unfortunately, this also means that my interviewers were left with <strong>my</strong> imagination which may have been a problem going forward.
</p>
<h2 id="starting-to-code">Starting to code<a aria-hidden="true" tabindex="-1" href="#starting-to-code"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  After I declared that I had understood the problem I could start to code.
  We used <a href="https://syncfiddle.net/">syncfiddle</a> for that.
  I had never used this tool before.
</p>
<p>
  My first question was "Where can I write tests?" because that's how I approach problems.
  Sadly, the tool doesn't support this but my interviewer pointed me to a couple of <code>console.log()</code> statements that would serve as my tests.
  The first <code>console.log()</code> was <code>A(0;0)</code> and <code>B(1;1)</code>.
</p>
<p>
  Admittedly, I was happy so at least have <em>some</em> sort of editor I can code in.
  But this one isn't great.
  Some issues I had while coding:
</p>
<ul>
  <li>No test-runner (still, my biggest issue)</li>
  <li>All "tests" were equality checks (i.e. <code>console.log(numberOfPaths(A, B) === 6))</code>) which <a href="/post/tests-that-help-you-find-defects-faster#no-proper-use-of-assertions">isn't helpful</a> because this doesn't show you how far off your solution is</li>
  <li>No proper autocompletion (a couple of times I had syntax errors because I was missing a closing parenthesis)</li>
  <li>Wrong comment syntax (I used <code>CMD + /</code> to toggle comments for a line or a block and it used the wrong syntax which screwed my code)</li>
</ul>
<p>
  If they would have asked me before the interview whether I use VSCode with LiveShare we could have used a proper editor.
  That way I would have been in an environment I'm used to, where I know the shortcuts, and where I could have added a <code>spec</code>-file.
  Also, we could have seen each other's cursers which would have made it much easier to talk about specific parts of the code.
</p>
<p>
  Before I started to code I said "I'm pretty sure this is going to be a recursive function in the end, but I'd like to start simple nonetheless.".
  I do this because <a href="https://en.wikipedia.org/wiki/Test-driven_development">TDD</a> wants you to write the least amount of code to fix a test.
  So, I went ahead and wrote the following code.
</p>
<pre class="language-js"><code class="language-js code-highlight"><span class="code-line"><span class="token keyword">function</span> <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token parameter"><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword">let</span> stepsX <span class="token operator">=</span> <span class="token number">0</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span><span class="token punctuation">;</span> i <span class="token operator">&#x3C;</span> <span class="token constant">B</span><span class="token punctuation">.</span><span class="token property-access">x</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    stepsX<span class="token operator">++</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword">let</span> stepsY <span class="token operator">=</span> <span class="token number">0</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span><span class="token punctuation">;</span> i <span class="token operator">&#x3C;</span> <span class="token constant">B</span><span class="token punctuation">.</span><span class="token property-access">y</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    stepsY<span class="token operator">++</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">return</span> stepsX <span class="token operator">+</span> stepsY
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  With that code, the first "test" went green.
  I was happy.
  My interviewer was not.
  He told me that this algorithm does compute the number of steps and not the number of paths.
  That is true and also the reason why I called the variables <strong>steps</strong> and not <strong>paths</strong>.
  I was fully aware that this algorithm is not correct (and stated this before I wrote it) but I always want to start simple and then become more complex over time.
  That's how <strong>I</strong> approach problems and I thought that the interview was about that.
</p>
<p>
  Anyway, I realized that I might need to show more of my algorithmic skills.
  I had the intuition that he wanted me to write the recursive version right away.
  With recursion, you need to make sure that you have some notion of "did I reach the end yet?" in your algorithm.
  Also known as the abortion criteria.
  Otherwise, no matter what you'll do you'll end up with a <a href="https://en.wikipedia.org/wiki/Stack_overflow#Infinite_recursion">stack overflow error</a>.
  I removed the code I had written so far and implemented the following two methods.
</p>
<pre class="language-js"><code class="language-js code-highlight"><span class="code-line"><span class="token keyword">function</span> <span class="token function">canMoveX</span><span class="token punctuation">(</span><span class="token parameter"><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span> <span class="token operator">&#x3C;</span> <span class="token constant">B</span><span class="token punctuation">.</span><span class="token property-access">x</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">function</span> <span class="token function">canMoveY</span><span class="token punctuation">(</span><span class="token parameter"><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token operator">&#x3C;</span> <span class="token constant">B</span><span class="token punctuation">.</span><span class="token property-access">y</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  Interruption.
  "What are you doing there? Please explain what you're up to."
  OK, I might have been too silent when I removed my old code and added these two methods.
  I explained what I was going to write a recursive algorithm and that I think that I will need these two helper methods.
  Then I stubbed out the following code.
</p>
<pre class="language-js"><code class="language-js code-highlight"><span class="code-line"><span class="token keyword">function</span> <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token parameter"><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">canMoveX</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span> <span class="token operator">&#x26;&#x26;</span> <span class="token operator">!</span><span class="token function">canMoveY</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token comment">// done, arrived at B</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">canMoveX</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token comment">// arrived at right border</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">canMoveY</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token comment">// arrived at top border</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token comment">// split path</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  I explained that these are the conditions I'm thinking of.
  When we can't move anymore we know that we've reached <code>B</code>.
  If we can only move into one direction we hit a border.
  That also means no <em>new</em> paths can appear given the rules we defined.
</p>
<p>
  I probably made a big mistake right then and there.
  For me, part of the solution was to count how often a new path would split away along the way.
  As it turned out at the end of the interview that was not the mental model of the interviewer.
  This might have prevented a couple of misunderstandings along the way.
</p>
<p>Given that I wanted to <em>count</em> splits along the way I wrote the following (wrong) code.</p>
<pre class="language-js"><code class="language-js code-highlight"><span class="code-line"><span class="token keyword">function</span> <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token parameter"><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">,</span> paths <span class="token operator">=</span> <span class="token number">0</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">canMoveX</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span> <span class="token operator">&#x26;&#x26;</span> <span class="token operator">!</span><span class="token function">canMoveY</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token keyword control-flow">return</span> paths
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">canMoveX</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token keyword control-flow">return</span> <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">,</span> paths<span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">canMoveY</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token keyword control-flow">return</span> <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">,</span> paths<span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token punctuation">(</span>
</span><span class="code-line">    <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">,</span> paths <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">+</span>
</span><span class="code-line">    <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">,</span> paths <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  At this point, I should add that the mental model of the interviewer was "count how often we arrive at <code>B</code>".
  That doesn't play nicely with incrementing a number when you reach a split position.
  He also asked me why I was incrementing a variable when there is a split to which I replied that I thought the task was to count the number of paths.
  Given that we looked at the problem from two different angles and that from his point of view I was heading in the wrong direction I can understand that he wanted me to re-iterate the problem.
  We even looked at the initial diagram (at the top of this post) again and he wanted me to state the problem again.
  I must admit, that I was put off a little by that.
  Because I didn't think that I was stuck.
  My "tests" we're failing but that was OK.
  I did not assume to crank out the correct algorithm.
  When I looked at my conditionals I felt confident that they were correct.
  The resulting number was simply way too large which meant there must be something wrong when I incremented my counter.
</p>
<p>
  Then something happened that I did not expect.
  He changed my code.
  Now it looked like this:
</p>
<pre class="language-js"><code class="language-js code-highlight"><span class="code-line"><span class="token keyword">function</span> <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token parameter"><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">,</span> paths <span class="token operator">=</span> <span class="token number">0</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">canMoveX</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span> <span class="token operator">&#x26;&#x26;</span> <span class="token operator">!</span><span class="token function">canMoveY</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line highlight-line">    <span class="token keyword control-flow">return</span> <span class="token number">1</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">canMoveX</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token keyword control-flow">return</span> <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">,</span> paths<span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">canMoveY</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token keyword control-flow">return</span> <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">,</span> paths<span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token punctuation">(</span>
</span><span class="code-line">    <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">,</span> paths <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">+</span>
</span><span class="code-line">    <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">,</span> paths <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  Now all tests were "green".
  However, my line of thought was gone.
  Why?
  Because this solution only makes sense in the "count how often we arrive at <code>B</code>" model and not the "increase counter whenever we split a path" one.
</p>
<p>
  In retrospect, it feels like the interviewer might have been convinced that I'm going nowhere.
  He might have thought that by changing my code he's going to help me.
  However, I felt this was extremely rude.
  Whenever I'm pairing or interviewing someone I would <strong>always</strong> ask whether I'm allowed to type something before I do it.
  Before that, I would highlight a piece of code (which didn't work in the editor we were using) to focus the attention of my pair.
</p>
<p>
  The error I made was trying to carry the number of paths forward through the recursion.
  A change that would fit better would be that one:
</p>
<pre class="language-js"><code class="language-js code-highlight"><span class="code-line"><span class="token keyword">function</span> <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token parameter"><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">canMoveX</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span> <span class="token operator">&#x26;&#x26;</span> <span class="token operator">!</span><span class="token function">canMoveY</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line highlight-line">    <span class="token keyword control-flow">return</span> <span class="token number">0</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">canMoveX</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line highlight-line">    <span class="token keyword control-flow">return</span> <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">canMoveY</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line highlight-line">    <span class="token keyword control-flow">return</span> <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token punctuation">(</span>
</span><span class="code-line highlight-line">    <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span> <span class="token operator">+</span>
</span><span class="code-line highlight-line">    <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span> <span class="token operator">+</span>
</span><span class="code-line highlight-line">    <span class="token number">1</span>
</span><span class="code-line">  <span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  Yes, this code is still not entirely correct (it's off by one) but would have gotten me closer to the solution.
  Of course, I can only guess that the interviewer couldn't follow.
  And ultimately its probably my fault for not being clear about my approach earlier on.
  What I would have wished for though would have been that the interviewer not simply point out the mistakes but asked me to re-iterate my approach.
  After all, this interview is all new information and work conditions for me and not for him.
</p>
<p>
  I'm also not saying that my approach is better than his.
  It's definitively more complicated.
  But hey, make it work, then make it pretty.
</p>
<p>For completeness, here's the code following my model that would ultimately work.</p>
<pre class="language-js"><code class="language-js code-highlight"><span class="code-line"><span class="token keyword">function</span> <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token parameter"><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">,</span> initial <span class="token operator">=</span> <span class="token boolean">true</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">canMoveX</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span> <span class="token operator">&#x26;&#x26;</span> <span class="token operator">!</span><span class="token function">canMoveY</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token keyword control-flow">return</span> <span class="token number">0</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">canMoveX</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token keyword control-flow">return</span> <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">canMoveY</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token keyword control-flow">return</span> <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token punctuation">(</span>
</span><span class="code-line">    <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token operator">+</span>
</span><span class="code-line">    <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token operator">+</span>
</span><span class="code-line">    <span class="token comment">// when you start at A you need to record two new paths</span>
</span><span class="code-line">    <span class="token comment">// after that there will always be only one new</span>
</span><span class="code-line">    <span class="token comment">// path when you encounter a split</span>
</span><span class="code-line">    <span class="token punctuation">(</span>initial <span class="token operator">?</span> <span class="token number">2</span> <span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  I haven't published the post yet but I keep thinking about it.
  I've come up with another solution that even better fits my mental model.
  Clear proof that 20 minutes doesn't tell you anything about a candidate.
</p>
<pre class="language-js"><code class="language-js code-highlight"><span class="code-line"><span class="token keyword">function</span> <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token parameter"><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">,</span> newPaths <span class="token operator">=</span> <span class="token number">1</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">canMoveX</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token operator">!</span><span class="token function">canMoveY</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token keyword control-flow">return</span> newPaths
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token punctuation">(</span>
</span><span class="code-line">    <span class="token comment">// all paths we have found so far</span>
</span><span class="code-line">    newPaths <span class="token operator">+</span>
</span><span class="code-line">    <span class="token comment">// a split means we found one new path</span>
</span><span class="code-line">    <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">+</span>
</span><span class="code-line">    <span class="token comment">// because we're already on an existing one</span>
</span><span class="code-line">    <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<h2 id="improving-the-solution">Improving the solution<a aria-hidden="true" tabindex="-1" href="#improving-the-solution"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  As the last step, I was asked whether I could improve my solution.
  Since I was still wrapping my head around "my" solution that really was <strong>his</strong> solution I asked what kind of improvement he was looking for?
  He pointed out that, for instance, the code <code>numberOfPaths({ x: A.x + 1, y: A.y }, B)</code> appears twice.
  Here's where I made another mistake.
  I took this as a hint that I could extract some common code.
  TL;DR that didn't work out.
  I tried some weird things that would never have worked.
  Maybe this was what caused my interviewer to think that I never understood the problem to start with.
  Then, again, he adjusted my (or at this point our) code without asking me first.
</p>
<pre class="language-js"><code class="language-js code-highlight"><span class="code-line"><span class="token keyword">function</span> <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token parameter"><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">canMoveX</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span> <span class="token operator">&#x26;&#x26;</span> <span class="token operator">!</span><span class="token function">canMoveY</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token keyword control-flow">return</span> <span class="token number">1</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">canMoveX</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line highlight-line">    <span class="token keyword control-flow">return</span> <span class="token number">0</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">canMoveY</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line highlight-line">    <span class="token keyword control-flow">return</span> <span class="token number">0</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token punctuation">(</span>
</span><span class="code-line">    <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span> <span class="token operator">+</span>
</span><span class="code-line">    <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  My reaction?
  I said "Uh?" followed by "OK...".
  The thing is, that code is not correct and when he did the change my developer spider senses tingled with exactly that feeling.
  To this day I'm not sure whether he wanted me to tell him that he broke the code right then and there.
  Since it felt like he was showing me the solution I didn't respond with anything.
  That's again something I probably shouldn't have done.
</p>
<p>
  Fun fact, five minutes <strong>after</strong> the interview I think I realized what he wanted me to do.
  The moment you've hit a border you can't find any new paths.
  So, what you can do to simplify this script is to merge the <code>if</code>-statements.
</p>
<pre class="language-js"><code class="language-js code-highlight"><span class="code-line"><span class="token keyword">function</span> <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token parameter"><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line highlight-line">  <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">canMoveX</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token operator">!</span><span class="token function">canMoveY</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token keyword control-flow">return</span> <span class="token number">1</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token punctuation">(</span>
</span><span class="code-line">    <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span> <span class="token operator">+</span>
</span><span class="code-line">    <span class="token function">numberOfPaths</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">x</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">.</span><span class="token property-access">y</span> <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  I felt a bit mislead by the statement about code duplication.
  Even though the question is a bit loaded he could have asked "Do you need all if-statements?".
  Then I could explain the logic back and probably have gotten the idea I had after the interview right in the interview.
  Ultimately, I felt a bit tricked into the wrong line of thinking.
</p>
<h2 id="conclusion">Conclusion<a aria-hidden="true" tabindex="-1" href="#conclusion"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>I've pointed out already what I would have changed so let me start this by saying what I liked.</p>
<ul>
  <li>The problem was not just explained but I had something to look at and some examples to help me get started.</li>
  <li>The shared coding session while not perfect was better than me, for instance, sharing my screen</li>
  <li>When I had some syntax errors my interviewer corrected them for me so that I can move along quicker</li>
</ul>
<p>Now, to what I didn't like.</p>
<p>
  In general, I don't like this particular kind of test.
  This algorithm is either correct or incorrect.
  Therefore, it is hard to <em>make progress</em> and once you're just a little stuck you essentially fail the whole task.
  I've personally always chosen exercises where you can achieve 80% and leave with a good feeling.
</p>
<p>
  While this interview was supposed to be about learning how <strong>I</strong> solve problems I got the feeling that it was about whether my approach matches <strong>his</strong>.
  To be fair, I might have caused this by not being vocal enough about what I'm going to do.
</p>
<p>
  I never felt like the other people acknowledged that this is a stressful situation for me.
  What I sometimes do is to ask "do you need a minute to think?" so that I know the other person isn't stuck but just can't formulate his idea with words right now.
</p>
<p>
  What really bothered me is that even though I told my interviewer that the code I'm going to write is not final and incorrect but that I want to start small he afterward pointed out exactly that.
  Also, when he edited parts of my solution without asking for permission first.
  The only effect this has is that he confused me because we were coming from different directions.
</p>
<hr>
<h2 id="update-2020-09-16">Update 2020-09-16<a aria-hidden="true" tabindex="-1" href="#update-2020-09-16"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  After I've published this blog post my colleagues also read it.
  Obviously, they immediately started to think about <strong>other</strong> ways to solve this puzzle.
  If they put their solutions somewhere online I'm going to add links to them.
  I must admit that I enjoy this a lot!
  That feeling when you see a problem and you can't stop thinking about it until you've also tinkered with it for some time.
</p>
<ul>
  <li>Federico Ghedina (<a href="https://github.com/fedeghe">fedeghe</a>) came up with <a href="https://github.com/fedeghe/javascript-patterns/blob/master/others/challenges/grind_path/index.js">a solution</a> that uses <a href="https://en.wikipedia.org/wiki/Pascal%27s_triangle">Pascal's triangle</a> to compute the paths</li>
</ul>
<p>Awesome solution because it works <strong>without</strong> recursion which means that it might run for quite some time but it will never result in a stack overflow error.</p>
<hr>
<p>
  What are your experiences with interviews?
  Do you agree with me?
  What would you have done differently?
  Both from my position and the one of the interviewer?
  What kind of task do you use when you conduct technical interviews?
</p>
<p>Do you have <strong>other</strong> and even <strong>better</strong> solutions for this problem?</p>
<p>Reach out to <a href="https://twitter.com/philgiese">@philgiese</a> on twitter with your thoughts!</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[ The religion of test-driven development ]]></title>
      <description><![CDATA[ I recently talked to another developer and mentioned that I use TDD. The other person then asked me whether I'm also one of that religious TDD followers? I had… ]]></description>
      <link>https://www.philgiese.com/post/the-religion-of-test-driven-development</link>
      <guid isPermaLink="false">https://www.philgiese.com/post/the-religion-of-test-driven-development</guid>
      <dc:creator>Philipp Giese</dc:creator>
      <pubDate>Mon, 07 Sep 2020 00:00:00 GMT</pubDate>
      <category>process</category>
      <category>tdd</category>
      <category>testing</category>
      <content:encoded><![CDATA[
<p>
  I recently talked to another developer and mentioned that I use <a href="https://en.wikipedia.org/wiki/Test-driven_development">TDD</a>.
  The other person then asked me whether I'm also one of that <em>religious TDD followers</em>?
  I had never thought about this.
  Do people think I'm preaching to them when I encourage them to use TDD?
  Are they only doing it to not hurt my feelings because they think I'm a <strong>believer</strong>?
  Did I create an atmosphere where TDD is a dogma that cannot be questioned?
</p>
<p>Let's talk about TDD, why it's <strong>not a religion</strong>, and why I think it's so much more than a practice to write code.</p>
<h2 id="tldr">TL;DR<a aria-hidden="true" tabindex="-1" href="#tldr"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  If you're treating TDD like a religion you should probably reconsider your life choices.
  Because following something based on dogma won't do you any good.
  This article focuses on:
</p>
<ul>
  <li><a href="#why-tdd-is-no-religion">why TDD is <strong>not</strong> a religion</a>,</li>
  <li><a href="#why-i-write-tests-first">why I, personally, like to work with TDD</a>, and</li>
  <li><a href="#tdd-is-much-more-than-writing-tests">that TDD is really not only about testing</a></li>
</ul>
<h2 id="why-tdd-is-no-religion">Why TDD is no religion<a aria-hidden="true" tabindex="-1" href="#why-tdd-is-no-religion"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Just because.
  Because you shouldn't blindly follow any practice to write code.
  If you think you need to preach anything work-related <strong>please stop</strong>.
  Life is too short to get into fights about whether yours or someone else approach is better.
  You're probably both wrong.
  At least to some degree.
  There simply is no perfect, one-fits-all solution to anything out there.
</p>
<p>
  Keep your mind open.
  Assume that no one gets up in the morning to do a bad job.
  Be mindful and your stress level will decrease a lot.
</p>
<h2 id="why-i-write-tests-first">Why I write tests first<a aria-hidden="true" tabindex="-1" href="#why-i-write-tests-first"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  If you don't like my reasons then you might want to read what <a href="https://en.wikipedia.org/wiki/Kent_Beck">Kent Beck</a> has to say on the matter.
  This section is purely my <strong>personal</strong> opinion.
  If you have strong feelings about any of the claims I make I encourage you to reach out to me (find out how in the last paragraph).
  I'm more than interested to hear your thoughts.
</p>
<h3 id="create-apis-from-the-perspective-of-the-consumer">Create APIs from the perspective of the consumer<a aria-hidden="true" tabindex="-1" href="#create-apis-from-the-perspective-of-the-consumer"><<span></span>></<span></span>></a></h3>
<p>
  When you start with nothing you can free yourself from thinking about the details.
  I know that the test will be failing in the beginning.
  Even more so, I want the test to fail initially.
  When I create an API that does not exist yet I can dream up anything I want.
  By doing this I can make sure that the <a href="https://medium.com/swlh/what-is-dx-developer-experience-401a0e44a9d9">DX</a> is great.
  Because when you start from the other side you often end up with APIs that leak details about your implementation.
  However, when there is no implementation yet you cannot leak anything.
  This can help you to build minimal APIs that are easier to consume.
</p>
<h3 id="keep-me-from-doing-too-much">Keep me from doing too much<a aria-hidden="true" tabindex="-1" href="#keep-me-from-doing-too-much"><<span></span>></<span></span>></a></h3>
<p>
  When I start on a new and exciting topic I can get ahead of myself.
  If I directly start coding and already have a couple of use cases in my head I can end up in a situation where there is a lot of code and the borders between the use cases start to get blurry.
  Sometimes they even <a href="/post/what-is-cohesion-and-why-should-you-care">start to influence each other</a>.
  Tests help me to stick to one use case because I can <a href="/post/tests-that-help-you-find-defects-faster">follow some simple rules</a>.
  When I write a test first I know that when the test goes from red to green I'm done.
  If I think that I'm not done yet this means that I need to add another test case.
  Tests help me split a large task into small units of work.
</p>
<h3 id="make-sure-the-test-points-to-the-correct-problem">Make sure the test points to the correct problem<a aria-hidden="true" tabindex="-1" href="#make-sure-the-test-points-to-the-correct-problem"><<span></span>></<span></span>></a></h3>
<p>
  This is one, if not the most important reason.
  When I write the test first I'm forced to see it fail.
  I then need to verify that it fails for the correct reason.
  While doing this I not only make sure that the test targets the correct problem but also that the error message is descriptive enough so that others in the future <a href="/post/tests-that-help-you-find-defects-faster#no-proper-use-of-assertions">have enough context</a> should their changes break the test.
</p>
<p>
  You might lose all that when you write your tests after you added the implementation.
  I've seen it too often that developers tend to write tests that replay what they have implemented.
  That does not prove anything.
  Even worse, these kinds of tests fail for any number of reasons that have nothing to do with what they should verify.
</p>
<h3 id="help-future-me-pick-up-the-work-tomorrow">Help future me pick up the work tomorrow<a aria-hidden="true" tabindex="-1" href="#help-future-me-pick-up-the-work-tomorrow"><<span></span>></<span></span>></a></h3>
<p>Context switches suck.</p>
<p>
  Even when I continue with the exact same task the next morning I need some time to figure out where I left off and what I need to do next.
  What helps me a lot is to end the day with a failing test.
  This way past me sets a pointer for future me for where to pick up the work.
  I can get right into coding again and make that test green.
  After that first test, I'm usually back on track.
</p>
<h3 id="give-me-serotonin-rushes-every-couple-of-minutes">Give me serotonin rushes every couple of minutes<a aria-hidden="true" tabindex="-1" href="#give-me-serotonin-rushes-every-couple-of-minutes"><<span></span>></<span></span>></a></h3>
<p>
  Each time I finish something I'm happy.
  Ending a day with the feeling that I haven't accomplished anything is super frustrating.
  When I code the whole day but can't be sure that what I've done actually works then this makes me sad.
  But when I TDD myself through the day I have that feeling of accomplishment every couple of minutes.
  Even better, I can be sure that everything I've done so far works as expected.
</p>
<p>
  This feeling of <strong>getting sh*t done</strong> and the serotonin rush that follows is probably also the cause why I got addicted to TDD.
  Right now it's more like a drug (in the most positive way) than anything else.
</p>
<h2 id="tdd-is-much-more-than-writing-tests">TDD is much more than writing tests<a aria-hidden="true" tabindex="-1" href="#tdd-is-much-more-than-writing-tests"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Here's the kicker.
  For me, the biggest advantage of TDD is not the tests.
  I see TDD as a great <a href="https://www.interaction-design.org/literature/book/the-glossary-of-human-computer-interaction/forcing-functions">forcing function</a> to help developers <a href="/post/the-productivity-paradox#team-productivity--individual-productivity">solve the right problems</a>.
</p>
<p>
  When a developer sits down starts with a test she needs to understand the problem first.
  I would claim that it's close to impossible to write an <a href="https://en.wikipedia.org/wiki/Assertion_(software_development)">assertion</a> when you don't know the problem you're trying to solve.
  At least, it will become <strong>much</strong> harder to that.
  If our developer realizes that she lacks some information this happens before she starts building the new functionality.
</p>
<p>
  I'd like to point out that the most important aspect here is that all this happens <strong>at the start</strong> of the task.
  This means:
</p>
<ul>
  <li>She hasn't spend days writing code she might need to delete later</li>
  <li>She is not frustrated because she has not invested much time yet</li>
  <li>The person who helps her will not need to understand any implementation details</li>
</ul>
<p>
  Not having a possibly wrong implementation frees you from a whole set of issues as well.
  Without code there you will not have to rework anything.
  Also, you can't get attached to anything you've already built and try to justify keeping it in regardless.
</p>
<p>
  If you figure out that the problem is not entirely clear then you can clarify it.
  That's also great because there cannot be blame at this point.
  Why?
  Because when the resources you work with aren't enough for you to figure out the problem then it cannot be your fault.
  At some point, someone has probably made some assumptions and you merely discovered these shortcuts.
  By asking for clarification you are the hero in this story because you are now making sure that you're working on the right thing.
</p>
<p>
  My personal experience working like this is that it improves the atmosphere a lot.
  It's easy to get mad at someone for spending days of work but not solving the actual problem.
  I have caught myself asking <em>Why didn't you ask me earlier?</em>.
  But then I also realized that the person didn't realize that he was going in the wrong direction.
  With TDD in place, people stop to ask for help and start to ask for <strong>clarification</strong>.
  That's much nicer.
  Because then the person who asks doesn't try to undo a mistake but actively seeks out clarification do avoid doing that.
  In my experience, this leads to solely positive reactions.
</p>
<p>
  To end this post on an even more meta-level I'd like to propose a name change.
  I believe that by working with TDD we will end up with something that I would call CDD or <strong>communication</strong> driven development.
  Because this is what I believe is what helps development teams the most.
  To talk to each other and to do this as early and as often as possible.
  We talk a lot about feedback loops.
  But I think people, especially developers tend to think of feedback as something that comes from customers or managers and that means more work.
  Making sure you're working on the right problem is another form of feedback that is cheaper to get and will already help us a great deal.
</p>
<p>
  What is your experience with TDD?
  Do you use it for your company?
  If yes, would you agree with my observations or not?
  If no, does this article encourage you to try it out?
  Tweet <a href="https://twitter.com/philgiese">@philgiese</a> with your ideas and questions.
</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[ What is cohesion and why should you care? ]]></title>
      <description><![CDATA[ Cohesion means you make sure that the parts that belong together are close to each other. 💥 Bam! Shortest blog post ever! ]]></description>
      <link>https://www.philgiese.com/post/what-is-cohesion-and-why-should-you-care</link>
      <guid isPermaLink="false">https://www.philgiese.com/post/what-is-cohesion-and-why-should-you-care</guid>
      <dc:creator>Philipp Giese</dc:creator>
      <pubDate>Mon, 31 Aug 2020 00:00:00 GMT</pubDate>
      <category>architecture</category>
      <category>software-design</category>
      <content:encoded><![CDATA[
<p>
  Cohesion means you make sure that the parts that belong together are close to each other.
  💥 Bam!
  Shortest blog post ever!
</p>
<p>
  On a more serious note let's talk about why this is important.
  If you would have asked me ten years ago I probably would have known about principles like <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a> but not about cohesion and its evil twin coupling.
  I asked my team.
  Everyone knew and could explain the DRY principle.
  Some had heard about cohesion but no one could come up with a good explanation.
  Why is the one principle easier to learn and understand than the other?
  I think principles like DRY are easier to apply because they come with a set of distinct rules.
  If you find the same code block multiple times then you're code probably isn't DRY.
  In contrast, cohesion does not have such a set of rules you can follow.
  You rather need something we call <a href="https://en.wikipedia.org/wiki/Fingerspitzengef%C3%BChl">"Fingerspitzengefühl"</a> in Germany.
</p>
<h2 id="tldr">TL;DR<a aria-hidden="true" tabindex="-1" href="#tldr"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  This is a tough article and I recommend to read it top-to-bottom.
  But as always here's the list of key takeaways.
  To achieve high cohesion you need to:
</p>
<ul>
  <li><a href="#re-use-what-can-be-re-used-but-not-more">understand the difference between re-use and re-purpose</a>,</li>
  <li><a href="#afferent-and-efferent-coupling">be aware of the two kinds of coupling that exist</a>, and</li>
  <li><a href="#impact-on-software-design">know about the influence this has on your application design</a></li>
</ul>
<h2 id="re-use-what-can-be-re-used-but-not-more">Re-use what can be re-used but not more<a aria-hidden="true" tabindex="-1" href="#re-use-what-can-be-re-used-but-not-more"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  I've mentioned the DRY principle before.
  That's because I believe that especially less experienced developers can be tricked into bad application design decisions while trying to not duplicate code.
</p>
<p>
  Let's assume you're building an application where users have a profile.
  That's why you implemented a <code>UserProfile</code> component.
</p>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token keyword">function</span> <span class="token function"><span class="token maybe-class-name">UserProfile</span></span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> user <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span>div</span><span class="token punctuation">></span></span><span class="token punctuation">{</span>user<span class="token punctuation">.</span><span class="token property-access">fullName</span><span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span>div</span><span class="token punctuation">></span></span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  One day you get a ticket that your customer support department needs a new feature to block certain users.
  To give support some context when they perform this action (so they do not block the wrong users) you put the button into the <code>UserProfile</code> component.
  After all, you have already built that component and you want to keep your application DRY.
</p>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token keyword module">import</span> <span class="token imports"><span class="token maybe-class-name">DisableUser</span></span> <span class="token keyword module">from</span> <span class="token string">"./DisableUser"</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">function</span> <span class="token function"><span class="token maybe-class-name">UserProfile</span></span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> user <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token punctuation">(</span>
</span><span class="code-line">    <span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      </span><span class="token punctuation">{</span>user<span class="token punctuation">.</span><span class="token property-access">fullName</span><span class="token punctuation">}</span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span><span class="token class-name">DisableUser</span></span> <span class="token attr-name">user</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>user<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span>div</span><span class="token punctuation">></span></span>
</span><span class="code-line">  <span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  But now everyone sees this button even though solely the people from support should.
  Coincidentally, another developer already implemented a <code>useIsSupportTeamMember</code> hook that tells you whether the current user is from your support team.
  Great, let's use the hook!
</p>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token keyword module">import</span> <span class="token imports"><span class="token maybe-class-name">DisableUser</span></span> <span class="token keyword module">from</span> <span class="token string">"./DisableUser"</span>
</span><span class="code-line"><span class="token keyword module">import</span> <span class="token imports"><span class="token punctuation">{</span> useIsSupportTeamMember <span class="token punctuation">}</span></span> <span class="token keyword module">from</span> <span class="token string">"./hooks"</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">function</span> <span class="token function"><span class="token maybe-class-name">UserProfile</span></span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> user <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword">const</span> isSupport <span class="token operator">=</span> <span class="token function">useIsSupportTeamMember</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token punctuation">(</span>
</span><span class="code-line">    <span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      </span><span class="token punctuation">{</span>user<span class="token punctuation">.</span><span class="token property-access">fullName</span><span class="token punctuation">}</span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      </span><span class="token punctuation">{</span>isSupport <span class="token operator">&#x26;&#x26;</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span><span class="token class-name">DisableUser</span></span> <span class="token attr-name">user</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>user<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">}</span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span>div</span><span class="token punctuation">></span></span>
</span><span class="code-line">  <span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  While what we have done might be fine for this use case we can get into trouble if we keep on adding features like this.
  Next, product management asks for a feature to control <a href="https://martinfowler.com/articles/feature-toggles.html">feature toggles</a>.
  Then, marketing asks for a feature to get tracking information about a particular user.
  Now, the component looks like this.
</p>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token keyword module">import</span> <span class="token imports"><span class="token maybe-class-name">DisableUser</span></span> <span class="token keyword module">from</span> <span class="token string">"./DisableUser"</span>
</span><span class="code-line"><span class="token keyword module">import</span> <span class="token imports"><span class="token maybe-class-name">ManageFeatureToggles</span></span> <span class="token keyword module">from</span> <span class="token string">"./ManageFeatureToggles"</span>
</span><span class="code-line"><span class="token keyword module">import</span> <span class="token imports"><span class="token maybe-class-name">ManageTracking</span></span> <span class="token keyword module">from</span> <span class="token string">"./ManageTracking"</span>
</span><span class="code-line"><span class="token keyword module">import</span> <span class="token imports"><span class="token punctuation">{</span>
</span></span><span class="code-line"><span class="token imports">  useIsSupportTeamMember<span class="token punctuation">,</span>
</span></span><span class="code-line"><span class="token imports">  useIsMarketingTeamMember<span class="token punctuation">,</span>
</span></span><span class="code-line"><span class="token imports">  useIsProductTeamMember<span class="token punctuation">,</span>
</span></span><span class="code-line"><span class="token imports"><span class="token punctuation">}</span></span> <span class="token keyword module">from</span> <span class="token string">"./hooks"</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">function</span> <span class="token function"><span class="token maybe-class-name">UserProfile</span></span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> user <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword">const</span> isSupport <span class="token operator">=</span> <span class="token function">useIsSupportTeamMember</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token keyword">const</span> isMarketing <span class="token operator">=</span> <span class="token function">useIsMarketingTeamMember</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token keyword">const</span> isProduct <span class="token operator">=</span> <span class="token function">useIsProductTeamMember</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token punctuation">(</span>
</span><span class="code-line">    <span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      </span><span class="token punctuation">{</span>user<span class="token punctuation">.</span><span class="token property-access">fullName</span><span class="token punctuation">}</span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      </span><span class="token punctuation">{</span>isSupport <span class="token operator">&#x26;&#x26;</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span><span class="token class-name">DisableUser</span></span> <span class="token attr-name">user</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>user<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">}</span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      </span><span class="token punctuation">{</span>isMarketing <span class="token operator">&#x26;&#x26;</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span><span class="token class-name">ManageTracking</span></span> <span class="token attr-name">user</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>user<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">}</span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      </span><span class="token punctuation">{</span>isProduct <span class="token operator">&#x26;&#x26;</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span><span class="token class-name">ManageFeatureToggles</span></span> <span class="token attr-name">user</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>user<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">}</span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span>div</span><span class="token punctuation">></span></span>
</span><span class="code-line">  <span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  The tricky part is that the code above isn't necessarily bad.
  However, I would claim that while we intended to re-use the <code>UserProfile</code> component we ended up re-purposing it.
  Why?
  We took four different use cases for a "user profile" and assumed that the overlap in functionality is large enough to build everything into one <code>UserProfile</code> component.
  This "master" component now contains code for our end-users, support, product management, and marketing.
  Since there is little overlap between the use cases most of the code of the component is never executed when we render it.
</p>
<p>
  Initially, this might not cause you trouble.
  But when requirements change and, for instance, marketing wants more features that don't relate to a user anymore it becomes harder to squeeze them into the existing code.
  That's when things tend to get ugly and people start to talk about "historic reasons" for certain design decisions.
</p>
<p>
  While you might have heard about <a href="https://en.wikipedia.org/wiki/Coupling_(computer_programming)">coupling</a> before I'm guessing that you haven't heard of afferent and efferent coupling.
  As I'm the author and I do believe it is worth talking about them we're going to have <a href="https://www.youtube.com/playlist?list=PLJaq64dKJZoqsh7PGGUi-SARV4wUz_lVa">a closer look</a> in the next section.
</p>
<h2 id="afferent-and-efferent-coupling">Afferent and efferent coupling<a aria-hidden="true" tabindex="-1" href="#afferent-and-efferent-coupling"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  A-What?
  Another tool you can use to check whether your software design goes in the right direction is to check for afferent and efferent coupling.
  Afferent coupling describes how many components will be <em>affected</em> by a change.
  Efferent coupling then tells us about how many other components have an <em>effect</em> on the component we're looking at.
  A trick to remember this is to look at the first letter of the words.
  Afferent starts with an <strong>a</strong> like affected and efferent with an <strong>e</strong> like effect.
</p>
<p>
  <img src="/posts/what-is-cohesion-and-why-should-you-care/more-coupling.png" alt="Higher afferent coupling">
</p>
<p>
  The picture above illustrates our current design.
  Notice that the switches we've put into our business logic do not matter here.
  Since any component can potentially show up for each group the connection needs to be there.
  This means that, for instance, the <code>ManageFeatureToggles</code> component has an afferent coupling value of 4 (because its used inside the <code>UserProfile</code> component but also indirectly in <code>ProductAdmin</code>, <code>SupportAdmin</code>, and <code>MarketingAdmin</code>).
  If we make a change in that component we can potentially affect four others.
</p>
<p>
  Also, the <code>UserProfile</code> has an efferent coupling value of 3 since it uses three components (<code>ManageFeatureToggles</code>, <code>ManageTracking</code>, and <code>DisableUser</code>).
  A change in any of the three components could have an effect on the user profile itself.
</p>
<p>
  Again, none of these values are inherently good or bad.
  But they give us something that we can compare against.
  Let's look at a different way to structure the code.
  This time we're going to build dedicated components for each kind of user profile.
</p>
<p>
  <img src="/posts/what-is-cohesion-and-why-should-you-care/more-composition.png" alt="Favor composition">
</p>
<p>
  In this design, the <code>ProductProfile</code> has an afferent and efferent coupling value of 1.
  If we anticipate more changes to the product profile then this design might be more favorable.
  Why?
  Because changes are local to the product use case and cannot influence other parts of our application.
  We have also introduced a new <code>UserDetails</code> component.
  This component contains the code that we actually intended to re-use.
  I would argue that extracting the user details into a small component is the better way to structure our code in this scenario.
  The new component is small and has no switches which means that all the code (the user information) adds value in every use case where it is rendered.
  <code>UserDetails</code> has an afferent coupling value of 6 which isn't bad because we've designed this component to be re-used.
</p>
<p>
  <strong>Update 2020-09-01</strong>: It got pointed out to me that it might be helpful to include the changed code for the specific profile components as well.
  Here we go.
  What you will end up with are more but smaller components without conditionals in them.
</p>
<h3 id="product-profile">Product profile<a aria-hidden="true" tabindex="-1" href="#product-profile"><<span></span>></<span></span>></a></h3>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token keyword module">import</span> <span class="token imports"><span class="token maybe-class-name">ManageFeatureToggles</span></span> <span class="token keyword module">from</span> <span class="token string">"./ManageFeatureToggles"</span>
</span><span class="code-line"><span class="token keyword module">import</span> <span class="token imports"><span class="token maybe-class-name">UserDetails</span></span> <span class="token keyword module">from</span> <span class="token string">"./UserDetails"</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">function</span> <span class="token function"><span class="token maybe-class-name">ProductProfile</span></span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> user <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token punctuation">(</span>
</span><span class="code-line">    <span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span></span><span class="token punctuation">></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span><span class="token class-name">UserDetails</span></span> <span class="token attr-name">user</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>user<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span><span class="token class-name">ManageFeatureToggles</span></span> <span class="token attr-name">user</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>user<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span></span><span class="token punctuation">></span></span>
</span><span class="code-line">  <span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<h3 id="support-profile">Support profile<a aria-hidden="true" tabindex="-1" href="#support-profile"><<span></span>></<span></span>></a></h3>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token keyword module">import</span> <span class="token imports"><span class="token maybe-class-name">DisableUser</span></span> <span class="token keyword module">from</span> <span class="token string">"./DisableUser"</span>
</span><span class="code-line"><span class="token keyword module">import</span> <span class="token imports"><span class="token maybe-class-name">UserDetails</span></span> <span class="token keyword module">from</span> <span class="token string">"./UserDetails"</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">function</span> <span class="token function"><span class="token maybe-class-name">SupportProfile</span></span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> user <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token punctuation">(</span>
</span><span class="code-line">    <span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span></span><span class="token punctuation">></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span><span class="token class-name">UserDetails</span></span> <span class="token attr-name">user</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>user<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span><span class="token class-name">DisableUser</span></span> <span class="token attr-name">user</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>user<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span></span><span class="token punctuation">></span></span>
</span><span class="code-line">  <span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<h3 id="marketing-profile">Marketing profile<a aria-hidden="true" tabindex="-1" href="#marketing-profile"><<span></span>></<span></span>></a></h3>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token keyword module">import</span> <span class="token imports"><span class="token maybe-class-name">ManageTracking</span></span> <span class="token keyword module">from</span> <span class="token string">"./ManageTracking"</span>
</span><span class="code-line"><span class="token keyword module">import</span> <span class="token imports"><span class="token maybe-class-name">UserDetails</span></span> <span class="token keyword module">from</span> <span class="token string">"./UserDetails"</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">function</span> <span class="token function"><span class="token maybe-class-name">MarketingProfile</span></span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> user <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token punctuation">(</span>
</span><span class="code-line">    <span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span></span><span class="token punctuation">></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span><span class="token class-name">UserDetails</span></span> <span class="token attr-name">user</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>user<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span><span class="token class-name">ManageTracking</span></span> <span class="token attr-name">user</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>user<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text">
</span></span><span class="code-line"><span class="token plain-text">    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span></span><span class="token punctuation">></span></span>
</span><span class="code-line">  <span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  What does this have to do with <em>cohesion</em>?
  In the first design changes to one use case (e.g. product) would have an effect on other use cases (e.g. marketing).
  This was reflected in high afferent coupling values on components where we would have expected low values.
  Since these use cases should not overlap but the components are connected I would argue that we did not achieve cohesion because two components that do not share a use case might influence each other.
</p>
<p>
  The second design approach is different.
  If we wanted to add another component to the product profile we could implement that without affecting, for instance, any marketing component.
</p>
<p>
  <img src="/posts/what-is-cohesion-and-why-should-you-care/new-feature.png" alt="Favor composition">
</p>
<p>
  This means that you can achieve cohesion by making sure that components that serve a specific use case have an afferent coupling value which represents this.
  If you have three components that handle product use-cases but one of those has an afferent coupling value of 10 then this is a smell that you have not achieved cohesion.
</p>
<h2 id="impact-on-software-design">Impact on software design<a aria-hidden="true" tabindex="-1" href="#impact-on-software-design"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  In my experience, the most important thing is to be aware of the concepts I've described above.
  There are no good and bad values for afferent and efferent coupling per se.
  For instance, a <code>Button</code> component will probably have an enormous afferent coupling value but that is totally fine.
  What is important is to compare the value with the use case you are trying to solve.
  Is the component <strong>meant</strong> to be re-used?
  Then go for it.
  But make sure that the component covers only one specific use case.
  A button should handle clicks and a label.
  You probably don't want to add functionality to do a video call to it because the use case you are currently working on demands it.
  Especially at the beginning of your career, this can be hard because this requires you to always keep the bigger picture in mind.
  This is a skill no one will ever master.
  I still make these kinds of mistakes all the time.
  While you can point at some part of your application in hindsight and proclaim "This is where we did it wrong" this can be close to impossible when there are other problems to figure out or a deadline is around the corner.
  My best advice is to stay aware of the issues and constantly challenge your design.
</p>
<h3 id="design-to-compose">Design to compose<a aria-hidden="true" tabindex="-1" href="#design-to-compose"><<span></span>></<span></span>></a></h3>
<p>
  A benefit of keeping use cases separate and making sure that the coupling values represent what we want our components to do will lead to a more composable application design.
  This is great because it lets you plug together functionality without worrying too much about the reach of your actions.
  Subsequently, bugs will tend to stay more local.
  While a bug in a button might still make that button not clickable it won't corrupt your video conferencing.
  I refer to these as <strong>bugs that make sense</strong>.
  The bugs stick to their respective domain and don't lead to a <a href="https://www.youtube.com/watch?v=VoP1E9J4jpg">whack-a-mole</a> kind of situation.
</p>
<p>
  Another big benefit is that high cohesion makes your software easier to maintain.
  If you discontinue a part of your application you can be sure that you might have to fix the occasional bug but you will not need to adjust the legacy code each time you add a new feature.
</p>
<p>
  Even though this means that we need to spend a little more time thinking about our software design it can save ourselves time and trouble in the future.
  And that's why you should care about cohesion.
</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[ The productivity paradox ]]></title>
      <description><![CDATA[ Here are two sentences that I sometimes hear from developers. ]]></description>
      <link>https://www.philgiese.com/post/the-productivity-paradox</link>
      <guid isPermaLink="false">https://www.philgiese.com/post/the-productivity-paradox</guid>
      <dc:creator>Philipp Giese</dc:creator>
      <pubDate>Mon, 03 Aug 2020 00:00:00 GMT</pubDate>
      <category>process</category>
      <category>productivity</category>
      <category>goal-setting</category>
      <category>kanban</category>
      <category>leadership</category>
      <content:encoded><![CDATA[
<p>Here are two sentences that I sometimes hear from developers.</p>
<ol>
  <li>"We are always starting new features but we never finish what we have already started", and</li>
  <li>"Because of the <a href="https://en.wikipedia.org/wiki/Work_in_process">WIP</a> <a href="https://kanbanzone.com/resources/kanban/wip-limits/">limit</a> I feel so unproductive. I can't start work on the next important feature."</li>
</ol>
<p>
  Right now it might seem obvious that these statements contradict each other.
  But during day-to-day work, this might not be as obvious as it seems.
  When we adhere to WIP limits we make sure that we finish tasks before we start new ones.
  This solves complaint (1) but also generates complaint (2).
  If a developer cannot start another topic right after she finishes what she worked on then this can make her feel unproductive.
</p>
<h2 id="tldr">TL;DR<a aria-hidden="true" tabindex="-1" href="#tldr"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  In a world of deadlines and never-ending backlogs of tasks, it's easy to think you're being productive when you're merely busy.
  What is important to understand is that:
</p>
<ul>
  <li><a href="#busy-%E2%89%A0-productive">Being busy neither means that you're doing the right thing nor that you're doing it right</a>,</li>
  <li><a href="#team-productivity--individual-productivity">The goals you set for the team must not contradict the goals you set for individuals</a>, and</li>
  <li><a href="#the-cost-of-overutilization">That making sure people don't have something to do all the time will get more tasks done faster</a></li>
</ul>
<h2 id="busy--productive">Busy ≠ Productive<a aria-hidden="true" tabindex="-1" href="#busy--productive"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  A common mistake people make is to think that being busy is the same as being productive.
  I can relate to that because I have fallen into that trap as well in the past.
  Crunching through work for hours and hours can make me really happy.
  It gets problematic though when none of the work we do relates to a goal that we or our team aims to achieve.
  If all that you are doing is keeping your hands busy typing then what good does that do?
</p>
<p>
  Being productive means doing something meaningful.
  This isn't related to how complex a task is or how much time it will consume.
  You can be productive working on a task for a week but you can also be productive when that task is done within an hour.
  The important part is that you make sure that every action you take will get you closer to the goal you want to achieve.
</p>
<h3 id="you-cannot-be-productive-without-setting-goals">You cannot be productive without setting goals<a aria-hidden="true" tabindex="-1" href="#you-cannot-be-productive-without-setting-goals"><<span></span>></<span></span>></a></h3>
<p>When you don't know where you are going, how will you make sure you arrive at the right place?</p>
<p>
  I understand that defining a clear goal can be a hard task.
  Why?
  Because the goal <a href="/post/how-to-solve-problems">might not turn out to be what we initially thought it would be</a>.
  Since we're all human we tend to not like to do the things that force us out of our comfort zone.
  We can achieve this by not setting goals.
  If there is no goal then we can claim we've reached it at any point.
  While this might make us feel good about ourselves we need to understand that it won't help us in the long run.
</p>
<h3 id="different-kinds-of-goals">Different kinds of goals<a aria-hidden="true" tabindex="-1" href="#different-kinds-of-goals"><<span></span>></<span></span>></a></h3>
<p>
  If you think about your last day at work, what would you consider goals?
  Working on a <a href="https://en.wikipedia.org/wiki/User_story">user story</a>?
  Doing a <a href="https://en.wikipedia.org/wiki/Code_refactoring">refactoring</a>?
  Ticking off the action item from the last <a href="https://www.scrum.org/resources/what-is-a-sprint-retrospective">retrospective</a>?
  Implementing one <a href="https://en.wikipedia.org/wiki/Test-driven_development">test case</a>?
</p>
<p>
  You might have never thought about these items as goals.
  Maybe you have even wondered why they exist in the first place?
  We're doing this exercise of slicing problems into smaller pieces to have items we can work on.
  <a href="https://youtu.be/K2WQkZwpRIs?t=128">Frozen II</a> featured a whole song dedicated to this topic!
  That is, for instance, why a user story needs to have acceptance criteria.
  Without them, how would we know when the story is done (i.e. the goal is achieved)?
</p>
<p>
  One of the smallest goals I could think of is a test case.
  That is probably also why I like <a href="https://en.wikipedia.org/wiki/Test-driven_development">TDD</a> so much.
  Whenever a test goes from red to green I know that I've achieved this particular goal.
  If I've written and implemented all the tests that make up a user story I've achieved the next larger goal.
</p>
<p>
  When we work like this we focus most of our energy on tasks that are essential.
  This means we're wasting as little time as possible on tasks that do not help us achieve a goal.
  And this means we are <strong>productive</strong>!
</p>
<p>
  I encourage you to use this argument any time someone claims that writing tests make you slower.
  That's a fallacy for another post though.
</p>
<h2 id="team-productivity--individual-productivity">Team productivity / Individual productivity<a aria-hidden="true" tabindex="-1" href="#team-productivity--individual-productivity"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  If your organization correlates promotions with personal goals then you might be in trouble.
  Because personal goals do not always align with what a product or the business needs to achieve.
  In this respect, developers might work against any change to your development process that prioritizes the team over the individual.
  While I can understand that managers need some way to evaluate developers there need to be betters ways.
</p>
<p>
  This is not an unsolvable problem.
  What is important is that you are aware that you might be motivating people to do the thing you don't want them to do.
  How can you fix this?
</p>
<h3 id="individual-goals-need-to-be-in-alignment-with-team-goals">Individual goals need to be in alignment with team goals<a aria-hidden="true" tabindex="-1" href="#individual-goals-need-to-be-in-alignment-with-team-goals"><<span></span>></<span></span>></a></h3>
<p>
  I believe what is missing in a lot of scenarios are clear goals for the team as a whole.
  Team goals must be about more than story counts, cycle times, or the number of bugs.
  They should directly connect the work of the team with the value it creates for the customer.
  Don't get me wrong.
  Counting stories and bugs might help to <em>measure</em> the success of a certain goal but they should <strong>not</strong> <em>be</em> the goal.
  In the end, what does it mean to achieve super-fast cycle times with no bugs if nothing of what you have built helps your customers?
</p>
<p>
  <a href="https://felipecastro.com/en/okr/what-is-okr/">OKRs</a> might be one way to achieve a hierarchy of goals while also aligning them with each other.
  You'll need to choose what works best for your team.
  The important exercise is to be aware of the goals and make them visible.
  Because after you have done that it becomes easier to see when a goal you set for a person contradicts a team goal.
</p>
<h3 id="provide-people-with-the-space-to-work-on-individual-goals">Provide people with the space to work on individual goals<a aria-hidden="true" tabindex="-1" href="#provide-people-with-the-space-to-work-on-individual-goals"><<span></span>></<span></span>></a></h3>
<p>
  Now that we have acknowledged that there are different kinds of goals we need to make sure that there is room to achieve them.
  If your development process is optimized to solely contribute to team goals then you're sooner or later going to run into problems when people work on their personal goals.
  Some agile methods have introduced the concept of <a href="https://leadingagileteams.com/2015/09/01/making-time-for-personal-development-gold-cards/">Gold Cards</a> for this purpose.
  Developers can use them to opt-out of day-to-day work and work on a personal topic instead.
  My personal experience tells me they are rubbish, though.
</p>
<p>
  When your development process aims at keeping everyone busy all the time it can be hard for a developer to use one of her gold cards.
  I've noticed that this is sometimes caused by a feeling of "letting the team down".
  Because when there is so much to do, aren't I selfish if I'd use a gold card?
</p>
<p>If this happens it might be a sign of <strong>overutilization</strong> which I'll explain in the next section.</p>
<h2 id="the-cost-of-overutilization">The cost of overutilization<a aria-hidden="true" tabindex="-1" href="#the-cost-of-overutilization"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  The last two sections were mainly about the point (1).
  The feeling of not being able to finish a feature can be resolved by creating and communicating clear goals that the whole team agrees upon.
  While there might still be some frustration it can help the developer understand why the team is acting in a certain way.
</p>
<p>
  Now, we're going to talk about all the work you should <strong>not</strong> do.
  If I would be an evil manager I would claim that "A team only performs well when everyone works on something all the time."
  <a href="https://www.youtube.com/watch?v=CostXs2p6r0">This YouTube video</a> does a great job demonstrating why this is not true.
  To avoid people being <em>busy</em> all the time <a href="https://en.wikipedia.org/wiki/Kanban">Kanban</a> introduced WIP limits.
</p>
<p>
  However, if not everyone is busy then some people will have nothing to do from time to time.
  This can make them <strong>think</strong> that they are unproductive because they <a href="#busy-%E2%89%A0-productive">confuse being busy with being productive</a>.
  The book <a href="https://www.goodreads.com/book/show/17255186-the-phoenix-project">The Phoenix Project</a> provides an explanation that I find useful<sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref aria-describedby="footnote-label">1</a></sup>.
</p>
<p>
  Imagine a developer that works on planned work 50% of her time.
  This means there is a ratio of 50/50 between the time where she is busy and the time where she has nothing to do.
  We are going to use this as our baseline of 1 (because 50 divided by 50 is 1).
  If we assume that she is busy 90% of her time then the ratio changes to 90/10.
  What does this mean?
  This means that if something unexpected happens (e.g. a critical bug on production) it will take her 9 times as long to work on that task.
  In other words, by keeping everyone busy all the time we're leaving no room for <em>the unexpected</em>.
  When we don't expect the unexpected then every bug, security issue, or other kinds of incidents will disrupt the team's productivity.
  The extra cost of context switches will then make the scheduled tasks also take longer.
  I think we can agree that this is not a situation we would like to be in.
</p>
<h3 id="wip-limits">WIP limits<a aria-hidden="true" tabindex="-1" href="#wip-limits"><<span></span>></<span></span>></a></h3>
<p>
  I've mentioned WIP limits a couple of times in this article.
  They are a tool you can use to prevent the team from being overutilized.
  In my team, when we set WIP limits we tend to pick a number that makes us feel a little uncomfortable.
  We do this because raising the limit is easier than reducing it.
  We also make sure that we make this a topic in the next retrospective to check whether the WIP limit works or is harmful.
  So far, we have never raised a WIP limit.
</p>
<p>
  At this point, you have made sure that your team can react to unplanned activities without disrupting the overall flow.
  But you've also created a void.
  Free time is something that can feel weird in the beginning.
  It might even lead to some frustration as shown in the statement (2).
  That is why I would recommend that you and your team come up with a list of activities developers can take up when there is nothing to do.
</p>
<h3 id="slack-time-as-a-forcing-function">Slack time as a forcing function<a aria-hidden="true" tabindex="-1" href="#slack-time-as-a-forcing-function"><<span></span>></<span></span>></a></h3>
<p>
  One thing I've learned is to give developers some example options of what they could do when the WIP limit prevents them from starting something new.
  They could:
</p>
<ul>
  <li><a href="https://en.wikipedia.org/wiki/Pair_programming">Pair</a> program with a peer to get their work finished faster,</li>
  <li>Do a refactoring that wasn't planned but would be nice to have, or</li>
  <li>Write a blog post (guess who's doing this right now)</li>
</ul>
<p>
  The important part is that any of the other activities, while they are nice, aren't critical.
  When a critical bug happens then a developer can exit a pairing session, pause that refactoring, or stop blogging at any time without harm.
  By not being busy all the time we gain <strong>flexibility</strong> (dare I say agility).
  This might seem like a <em>super power</em> from the outside.
  Hey, this team is working so <del>hard</del> smart that they can react to bugs and requests at any given time and they still deliver on their deadlines.
</p>
<hr>
<p>
  Even though this might sound awesome in theory you need to make this visible to every single developer.
  Because in the end there will be situations where the best thing to do is to watch a <a href="https://www.youtube.com/watch?v=dQw4w9WgXcQ">video</a> on YouTube.
  This can be frustrating for some developers.
  When they bring that frustration up, hear them out, show them the numbers, and never be too tired to explain that <a href="https://www.youtube.com/watch?v=v1mE_lyVKRQ">"the needs of the many outweigh the needs of the few, or the one"</a>.
</p>
<p>Doing less as an individual so that the team can achieve more is what I call <strong>the productivity paradox</strong>.</p>
<section data-footnotes class="footnotes">
  <h2 class="sr-only" id="footnote-label">Footnotes<a aria-hidden="true" tabindex="-1" href="#footnote-label"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
  <ol>
    <li id="user-content-fn-1">
      <p>If you want to learn more about this then I recommend reading <a href="https://www.goodreads.com/book/show/26083308-the-devops-handbook">The DevOps Handbook</a>. <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩</a></p>
    </li>
  </ol>
</section>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[ How to solve problems instead of symptoms ]]></title>
      <description><![CDATA[ If I had to pick one skill that I believe can impress less experienced developers the most then I would go with my ability to figure out the root cause of a… ]]></description>
      <link>https://www.philgiese.com/post/how-to-solve-problems</link>
      <guid isPermaLink="false">https://www.philgiese.com/post/how-to-solve-problems</guid>
      <dc:creator>Philipp Giese</dc:creator>
      <pubDate>Mon, 27 Jul 2020 00:00:00 GMT</pubDate>
      <category>process</category>
      <category>problem-solving</category>
      <category>bugs</category>
      <content:encoded><![CDATA[
<p>
  If I had to pick one skill that I believe can impress less experienced developers the most then I would go with my ability to figure out the root cause of a problem.
  At first, people thought that I would know all code in our codebase by heart and actually <strong>know</strong> what was going on.
  But my ability to do this even when I have never seen or worked with the code that breaks disproved that theory.
  If my memory is not the driving factor behind this skill, then what is?
</p>
<h2 id="tldr">TL;DR<a aria-hidden="true" tabindex="-1" href="#tldr"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>I can figure out problems faster than others because I</p>
<ul>
  <li><a href="#can-you-reproduce-this">make sure that I can consistently reproduce a problem before I start looking for the source</a>,</li>
  <li><a href="#the-error-isnt-where-the-code-breaks">know that the place where the problem surfaces is not necessarily where the problem should be fixed</a>, and</li>
  <li><a href="#dont-guess-experiment">do not guess but form hypotheses and try to disprove them constantly</a></li>
</ul>
<h2 id="can-you-reproduce-this">Can you reproduce this?<a aria-hidden="true" tabindex="-1" href="#can-you-reproduce-this"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  "Can you show me your reproduction steps?" will most likely be my first question if you would ask me to help you to figure out a problem.
  Why?
  If you can't consistently reproduce a problem then there is a chance you don't understand it enough yet.
  And if you don't understand what causes the problem then it becomes much harder to isolate the root cause or to come up with a fix.
</p>
<p>With reproduction steps, you are making sure that</p>
<ul>
  <li>you know enough about the context of a problem to replicate it</li>
  <li>reviewers have the means to verify whether your fix works</li>
  <li>you already have a rough idea about what a test case might look like</li>
  <li>which components are part of the problem and which definitively aren't</li>
</ul>
<p>
  It might seem cumbersome but every minute you spend on understanding the problem before you start fixing it is well spent.
  When you don't go through this exercise then it becomes harder to verify whether the actions you're taking will have an impact or not.
</p>
<h2 id="the-error-isnt-where-the-code-breaks">The error isn't where the code breaks<a aria-hidden="true" tabindex="-1" href="#the-error-isnt-where-the-code-breaks"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  The next trap developers sometimes run into is "fixing" the problem where the code breaks.
  This is sometimes also referred to as "fixing a symptom" and not "fixing the root cause".
  Let's look at an example.
</p>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token keyword">function</span> <span class="token function">fullName</span><span class="token punctuation">(</span><span class="token parameter">user</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>user<span class="token punctuation">.</span><span class="token property-access">firstName</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>user<span class="token punctuation">.</span><span class="token property-access">lastName</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token function">fullName</span><span class="token punctuation">(</span><span class="token keyword null nil">null</span><span class="token punctuation">)</span>
</span></code></pre>
<p>
  This code will throw an error because <code>null</code> does not have the properties <code>firstName</code> and <code>lastName</code>.
  I would even claim that almost everyone would jump to the conclusion that <code>fullName</code> should not be called with <code>null</code> but solely with valid <code>user</code> objects<sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref aria-describedby="footnote-label">1</a></sup>.
</p>
<p>
  Real-world applications often aren't as simple as this code snippet.
  When applications grow more complex it can be harder to spot the <em>obvious</em> errors as we can do here.
  If we extend the example a little bit and add a component that makes use of the <code>fullName</code> function it already becomes more tricky.
</p>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token keyword module">import</span> <span class="token imports"><span class="token punctuation">{</span> fullName <span class="token punctuation">}</span></span> <span class="token keyword module">from</span> <span class="token string">"./userUtils"</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">function</span> <span class="token function"><span class="token maybe-class-name">UserProfile</span></span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> id <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword">const</span> <span class="token punctuation">[</span><span class="token punctuation">,</span> user<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useFetchUser</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span></span><span class="token punctuation">></span></span><span class="token plain-text">Hello </span><span class="token punctuation">{</span><span class="token function">fullName</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span></span><span class="token punctuation">></span></span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  By adding more complexity to our application we need to take a closer look to determine which part isn't behaving in the correct way.
  My assumption is that this is what can put less experienced developers off.
  The error you see in your browser will still happen inside the <code>fullName</code> method.
  A fix that I've seen a lot in these situations would be to change the code to not throw any more in this particular situation.
</p>
<pre class="language-js"><code class="language-js code-highlight"><span class="code-line"><span class="token keyword">function</span> <span class="token function">fullName</span><span class="token punctuation">(</span><span class="token parameter">user</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>user <span class="token operator">==</span> <span class="token keyword null nil">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token keyword control-flow">return</span> <span class="token string">""</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>user<span class="token punctuation">.</span><span class="token property-access">firstName</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>user<span class="token punctuation">.</span><span class="token property-access">lastName</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  Admittedly, the application won't break anymore.
  What's the issue then?
  With this solution we haven't <em>fixed</em> the issue, we have <strong>hidden</strong> the issue.
  The problem is still there, it only does not surface at this place anymore.
</p>
<h3 id="how-can-we-find-the-correct-spot-for-the-fix">How can we find the correct spot for the fix?<a aria-hidden="true" tabindex="-1" href="#how-can-we-find-the-correct-spot-for-the-fix"><<span></span>></<span></span>></a></h3>
<p>
  I would argue that this is where proper reproduction steps help you a lot.
  For this particular bug the repro steps could be:
</p>
<ul>
  <li>Open the application</li>
  <li>Simulate a network outage (set browser to <a href="https://developers.google.com/web/ilt/pwa/tools-for-pwa-developers#chrome_4">"Offline"</a> in the <a href="https://developers.google.com/web/tools/chrome-devtools">developer tools</a>)</li>
  <li>Open the user profile</li>
</ul>
<p><strong>Expected</strong>: The user profile tells me it cannot load.</p>
<p><strong>Observed</strong>: The page crashes.</p>
<p>
  Why does this help?
  Because it gives us <strong>context</strong>!
  We know where the error surfaces (i.e. in the <code>fullName</code> method) and when it happens (when there is no internet connection).
  When we're debugging the code looking for the problem we can ignore code paths that have either nothing to do with network connections or do not include the <code>fullName</code> method.
  This could reduce the number of possible code paths that might contain the problem a lot.
</p>
<p>Do you now spot something when you have another look at the component I showed you earlier?</p>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token keyword module">import</span> <span class="token imports"><span class="token punctuation">{</span> fullName <span class="token punctuation">}</span></span> <span class="token keyword module">from</span> <span class="token string">"./userUtils"</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">function</span> <span class="token function"><span class="token maybe-class-name">UserProfile</span></span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> id <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword">const</span> <span class="token punctuation">[</span><span class="token punctuation">,</span> user<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useFetchUser</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span></span><span class="token punctuation">></span></span><span class="token plain-text">Hello </span><span class="token punctuation">{</span><span class="token function">fullName</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span></span><span class="token punctuation">></span></span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  Did you notice that the <code>useFetchUser</code> <a href="https://reactjs.org/docs/hooks-intro.html">hook</a> returns a <a href="https://medium.com/@ntgard/tuples-in-javascript-cd33321e5277">tuple</a> and that we're ignoring the first part of it?
  Since <code>useFetchUser</code> sounds a lot like network interaction and we know that has something to do with our problem I would dig deeper into that method.
</p>
<pre class="language-js"><code class="language-js code-highlight"><span class="code-line"><span class="token comment">// Note: this is not a real hook and you can't implement it this way</span>
</span><span class="code-line"><span class="token comment">// but to make this example not more complicated let's assume the</span>
</span><span class="code-line"><span class="token comment">// below code would synchronously fetch a user in a way that works</span>
</span><span class="code-line"><span class="token comment">// nicely with react</span>
</span><span class="code-line"><span class="token keyword">function</span> <span class="token function">useFetchUser</span><span class="token punctuation">(</span><span class="token parameter">id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">try</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token keyword">const</span> user <span class="token operator">=</span> <span class="token function">syncFetch</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/user/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>id<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">    <span class="token keyword control-flow">return</span> <span class="token punctuation">[</span><span class="token keyword null nil">null</span><span class="token punctuation">,</span> user<span class="token punctuation">]</span>
</span><span class="code-line">  <span class="token punctuation">}</span> <span class="token keyword control-flow">catch</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token keyword control-flow">return</span> <span class="token punctuation">[</span>error<span class="token punctuation">,</span> <span class="token keyword null nil">null</span><span class="token punctuation">]</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  As it turns out the part of the tuple that our code ignores indicates whether we could fetch the user or not (i.e. whether an error happened while we tried or not).
  We've found the actual problem!
  What was missing is not a <code>null</code> check in the <code>fullName</code> method but proper error handling in the <code>UserProfile</code> component.
</p>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token keyword module">import</span> <span class="token imports"><span class="token punctuation">{</span> fullName <span class="token punctuation">}</span></span> <span class="token keyword module">from</span> <span class="token string">"./userUtils"</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">function</span> <span class="token function"><span class="token maybe-class-name">UserProfile</span></span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> id <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword">const</span> <span class="token punctuation">[</span>error<span class="token punctuation">,</span> user<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useFetchUser</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token keyword control-flow">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span></span><span class="token punctuation">></span></span><span class="token plain-text">Could not load the user!</span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span></span><span class="token punctuation">></span></span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span></span><span class="token punctuation">></span></span><span class="token plain-text">Hello </span><span class="token punctuation">{</span><span class="token function">fullName</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;/</span></span><span class="token punctuation">></span></span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  My advice is to always think about how sensible the <a href="https://en.wikipedia.org/wiki/Guard_(computer_science)">guards</a> are that you add to your components or methods.
  In this example, I would have asked "How much sense does it make that the <code>fullName</code> method handles <code>null</code> as an input?".
  If there is a logical reason for that then this is totally fine.
  Your fix might be in the right place!
  But if it does not make too much sense then you might want to take a step back and revisit whether you might be fixing a symptom and not the problem itself.
  Tag along the path from what the user sees to where the code broke and ask the same question at every level.
  Repeat until you've found the place that contains the code path that breaks and which handles the part of the behavior that you know from the reproduction steps.
</p>
<h3 id="the-5-whys">The 5 Whys<a aria-hidden="true" tabindex="-1" href="#the-5-whys"><<span></span>></<span></span>></a></h3>
<p>
  I almost forgot to include this method because once you get used to doing this it becomes muscle memory.
  The <a href="https://en.wikipedia.org/wiki/Five_whys">5 whys</a> is a method of literally asking "Why?" five times in a row.
  This may sound silly but it helps to get to the bottom of a problem in a lot of cases.
  In our example this could look like:
</p>
<ul>
  <li><strong>Why does <code>fullName</code> break?</strong>: Because <code>user</code> is <code>null</code>.</li>
  <li><strong>Why is <code>user</code> <code>null</code>?</strong>: Because it is passed as a <code>null</code> reference from <code>UserProfile</code>.</li>
  <li><strong>Why does <code>UserProfile</code> pass it as a <code>null</code> reference?</strong>: Because network errors aren't handled properly.</li>
</ul>
<p>
  In this case, the third why let us to where the problem is.
  This method, by the way, does not only work for finding problems in code.
</p>
<h2 id="dont-guess-experiment">Don't guess, experiment<a aria-hidden="true" tabindex="-1" href="#dont-guess-experiment"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  A thing that I don't like about posts like this one is the oversimplification.
  No application looks like the example I've shown to you in the previous section.
  Even though the advice I'm giving you might sound easy to apply in your daily work it might be much harder.
</p>
<p>We're now going to have a look at how you can test whether you are on the right path to finding the solution or not.</p>
<p>
  If you would call me to your desk I would probably ask you "What have you tried so far?".
  I'll follow up with a "What did you learn?".
</p>
<p>
  The first question should be relatively easy to answer.
  You probably tried a lot of things.
  Comment a piece of code here.
  Change an <code>if</code>-statement there.
</p>
<p>
  But if you can answer the second question only with "None of what I tried fixes the problem" then you've merely been guessing around and this is not likely to get you any closer to a solution.
  Guessing is the <a href="https://en.wikipedia.org/wiki/Brute-force_search">brute-force method</a> to problem-solving<sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref aria-describedby="footnote-label">2</a></sup>.
  If you try long enough you will, eventually, find a solution that works.
  However, if you want to become better (and faster) at problem-solving then you need to learn how to experiment.
</p>
<p>
  I can't claim that I invented this technique.
  This is how scientists work all day<sup><a href="#user-content-fn-3" id="user-content-fnref-3" data-footnote-ref aria-describedby="footnote-label">3</a></sup>.
  The two main ingredients for a good experiment are:
</p>
<ul>
  <li>a <a href="https://www.thoughtco.com/elements-of-a-good-hypothesis-609096">hypothesis</a> and</li>
  <li>an experiment to <strong>disprove</strong> the hypothesis</li>
</ul>
<p>
  It must be possible to disprove any hypothesis you come up with because otherwise, you'll never know whether it's false.
  Notice how this is not aimed at finding the right hypothesis but getting rid of the false ones.
</p>
<p>
  Imagine we got a bug report that states that user avatars are not rendered with the correct colors.
  You have found the <code>Avatar</code> component and see that it uses another component called <code>ColorfulBox</code>.
  I would suggest that before you start digging into the internals of the <code>ColorfulBox</code> component (which might take considerable time) you run an experiment.
</p>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token keyword module">import</span> <span class="token imports"><span class="token punctuation">{</span> <span class="token maybe-class-name">ColorfulBox</span> <span class="token punctuation">}</span></span> <span class="token keyword module">from</span> <span class="token string">"design-system"</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">function</span> <span class="token function"><span class="token maybe-class-name">Avatar</span></span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> user <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword control-flow">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span><span class="token class-name">ColorfulBox</span></span> <span class="token attr-name">color</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>user<span class="token punctuation">.</span><span class="token property-access">color</span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<blockquote>
  <p>Hypothesis: The <code>ColorfulBox</code> component has no flaw. If I change the <code>color</code> prop to <code>red</code> I expect to see a red box.</p>
</blockquote>
<p>
  This is a good hypothesis because it helps us to eliminate a possible source of the problem.
  It can also be disproven.
  If we set the <code>color</code> prop to <code>red</code> and the box does not change its color then we know we need to keep digging.
  But if it does then we can look for the problem elsewhere.
</p>
<p>
  Experiments help you to get into a structured way of working.
  You can use them to narrow down the problem space without digging through thousands of lines of code.
  I always tell developers that they don't need to understand <strong>all</strong> possible code paths when they try to fix a bug.
  They solely need to identify and understand the <strong>one</strong> path that is affected.
</p>
<section data-footnotes class="footnotes">
  <h2 class="sr-only" id="footnote-label">Footnotes<a aria-hidden="true" tabindex="-1" href="#footnote-label"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
  <ol>
    <li id="user-content-fn-1">
      <p>To catch these kinds of bugs you probably want to use <a href="https://flow.org/">Flow</a> or <a href="https://www.typescriptlang.org/">Typescript</a>. I've chosen this example nonetheless so that I did not have to create a more complex example. <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩</a></p>
    </li>
    <li id="user-content-fn-2">
      <p>I sometimes joke about the <a href="http://wiki.c2.com/?FeynmanAlgorithm">Feynman Algorithm</a> for problem-solving. Don't take me too seriously on that one. <a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to reference 2" class="data-footnote-backref">↩</a></p>
    </li>
    <li id="user-content-fn-3">
      <p>It got pointed out to me that not all scientists work like that all day and that there are all sorts of tricks you can do to make your results fit a hypothesis. If you're speaking German <a href="https://www.youtube.com/watch?v=DHyRaUeHcGY&#x26;t=367s">this video</a> explains it nicely. <a href="#user-content-fnref-3" data-footnote-backref="" aria-label="Back to reference 3" class="data-footnote-backref">↩</a></p>
    </li>
  </ol>
</section>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[ Using GitHub actions and Vercel for end-to-end tests ]]></title>
      <description><![CDATA[ End-to-end (E2E) tests are the tip of the test pyramid. They are supposedly the hardest to write and take the longest to run. But they are also valuable as… ]]></description>
      <link>https://www.philgiese.com/post/e2e-with-vercel</link>
      <guid isPermaLink="false">https://www.philgiese.com/post/e2e-with-vercel</guid>
      <dc:creator>Philipp Giese</dc:creator>
      <pubDate>Tue, 21 Jul 2020 00:00:00 GMT</pubDate>
      <category>testing</category>
      <category>process</category>
      <category>vercel</category>
      <category>e2e</category>
      <category>cypress</category>
      <content:encoded><![CDATA[
<p>
  <a href="https://www.katalon.com/resources-center/blog/end-to-end-e2e-testing/">End-to-end</a> (E2E) tests are the tip of the <a href="https://martinfowler.com/articles/practical-test-pyramid.html">test pyramid</a>.
  They are supposedly the hardest to write and take the longest to run.
  But they are also valuable as they are the tests that "use" your app as your users do.
</p>
<p>
  When we first started to use E2E tests at <a href="https://www.signavio.com/">Signavio</a>, we were able to run them after changes got merged to our <code>master</code> branch but not on <a href="https://www.atlassian.com/de/git/tutorials/comparing-workflows/feature-branch-workflow">feature branches</a>.
  That is problematic because it had already made it to our mainline and possibly to production when they uncovered a defect.
  Another obstacle to not run them on each <a href="https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests">PR</a> was that spinning up an environment was not an easy task and would take considerable time.
  Since each minute the pipeline runs prolongs the feedback loop for the individual developer, we had a problem.
</p>
<p>
  When <a href="http://github.com/">GitHub</a> launched <a href="https://github.com/features/actions">actions</a> we discovered that actions can run when a <a href="https://docs.github.com/en/actions/reference/events-that-trigger-workflows#deployment">deployment</a> happens.
  By then, we already had set up <a href="http://vercel.com/">Vercel</a> to deploy our client on each PR.
  I asked myself whether I could connect the Vercel deployments with our E2E tests.
</p>
<h2 id="tldr">TL;DR<a aria-hidden="true" tabindex="-1" href="#tldr"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  No, shortlist this time.
  Sorry! Suppose you are solely interested in connecting <a href="https://www.cypress.io/">cypress</a> to a Vercel deployment.
  In that case, you can skip ahead to the <a href="#creating-the-workflow">Creating the workflow</a> section.
  If this is the first action you write, then I would recommend the full article.
  If you don't have time for that, definitively read <a href="#caveats">Caveats</a>.
  That might save you some time.
</p>
<h2 id="vercel-deployments">Vercel deployments<a aria-hidden="true" tabindex="-1" href="#vercel-deployments"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Setting up your project in Vercel is (and I don't say this lightly) easy if you're working with solutions like <a href="https://github.com/facebook/create-react-app">create react app</a> or static site generators like <a href="http://gatsbyjs.org/">Gatsby</a>.
  Vercel can import and run your project without you needing to do any custom configuration.
  But even if you didn't bootstrap your page like that, the configuration <a href="https://vercel.com/docs/configuration#project/builds">is straightforward</a>.
</p>
<p>Another reason I'm pointing at Vercel is that they already integrate with GitHub and register themselves as a deployment which is essential for the next step.</p>
<h2 id="github-actions">GitHub actions<a aria-hidden="true" tabindex="-1" href="#github-actions"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  GitHub actions are a powerful tool.
  But I also find them a bit hard to get started with.
  I struggled a lot with wording and how to achieve a simple goal.
  This article is in no form a complete guide to writing good actions.
  It's merely a description of what I needed to do to get the job done.
</p>
<p>
  Let's write an action! Wrong.
  The first thing I had to learn was that what I needed to do is add a <strong>workflow</strong>.
  I got fooled by the "Actions" tab on GitHub and assumed it would list actions.
  But what you will see there are workflows.
</p>
<p>
  An action is one <strong>step</strong> in a workflow.
  A workflow composes actions so that you can achieve a more complex goal.
  You also need the workflow to express when you want these actions to run.
  Workflows are co-located with the code inside one repository.
  For GitHub to run a workflow, you need to create a <a href="https://en.wikipedia.org/wiki/YAML"><code>YAML</code></a> file inside the <code>.github/workflows/</code> folder.
</p>
<pre class="language-yaml"><code class="language-yaml code-highlight"><span class="code-line"><span class="token key atrule">name</span><span class="token punctuation">:</span> E2E tests
</span><span class="code-line"><span class="token key atrule">on</span><span class="token punctuation">:</span> <span class="token punctuation">[</span>deployment_status<span class="token punctuation">]</span>
</span></code></pre>
<p>
  Why does this say <code>deployment_status</code> and not <code>deployment</code>?Because we wanted to improve the <em>developer</em> experience.
  To give our developers fast feedback on their PRs, we set a custom status.
  For that, we need some more information about the deployments.
</p>
<p>
  Suppose you are not interested in building a custom action.
  In that case, you can skip ahead to <a href="#creating-the-workflow">Creating the workflow</a>.
</p>
<p>
  As we will need to work with the GitHub API to set a status on a PR, we will now create a custom action for that.
  GitHub offers <a href="https://docs.github.com/en/actions/creating-actions/about-actions#types-of-actions">two ways to define actions</a> - JavaScript and <a href="https://www.docker.com/">Docker</a>.
  In this example, we will create the action using Docker since this is how I know to do it.
  We will also use the <a href="https://github.com/actions/toolkit"><code>actions-toolkit</code></a> to make building custom actions easier.
</p>
<h3 id="an-action-to-set-a-pr-status">An action to set a PR status<a aria-hidden="true" tabindex="-1" href="#an-action-to-set-a-pr-status"><<span></span>></<span></span>></a></h3>
<p>
  Since we do not intend to release this action for other developers, we can put all code into a <code>.github/actions/set-pr-status</code> folder inside our repository.
  This folder will contain three files.
</p>
<ul>
  <li>a <code>package.json</code> because we want to use the <code>actions-toolkit</code> package,</li>
  <li>a <code>DOCKERFILE</code> that describes the container to run our code, and</li>
  <li>an <code>action.js</code> file that contains the code of our action</li>
</ul>
<p>
  Let's start with the <code>package.json.</code>
  Since this will not be a package you want to release on <a href="https://www.npmjs.com/">NPM</a>, we can keep it short.
</p>
<pre class="language-json"><code class="language-json code-highlight"><span class="code-line"><span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"set-pr-status"</span><span class="token punctuation">,</span>
</span><span class="code-line">  <span class="token property">"private"</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
</span><span class="code-line">  <span class="token property">"main"</span><span class="token operator">:</span> <span class="token string">"action.js"</span><span class="token punctuation">,</span>
</span><span class="code-line">  <span class="token property">"dependencies"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token property">"actions-toolkit"</span><span class="token operator">:</span> <span class="token string">"5.0.0"</span>
</span><span class="code-line">  <span class="token punctuation">}</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>
  Next, we need to set up the container for our action.
  If you have never worked with Docker before, this might look a bit confusing.
  An advantage of Docker is that other people have done the heavy lifting for us already and provided base images for containers (i.e., execution environments) that we can re-use.
  In our case, what we need to do is:
</p>
<ul>
  <li>use a base <code>node</code> image (because we want to execute JavaScript),</li>
  <li>copy all files we need into the container,</li>
  <li>install the dependencies, and</li>
  <li><a href="https://youtu.be/kYtGl1dX5qI?t=14">run the action</a></li>
</ul>
<pre class="language-dockerfile"><code class="language-Dockerfile code-highlight"><span class="code-line"><span class="token instruction"><span class="token keyword">FROM</span> node:slim</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token comment"># The * after package is there also to copy the</span>
</span><span class="code-line"><span class="token comment"># package-lock.json that should is created when</span>
</span><span class="code-line"><span class="token comment"># you run `npm install.`</span>
</span><span class="code-line"><span class="token instruction"><span class="token keyword">COPY</span> package*.json ./</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token instruction"><span class="token keyword">RUN</span> npm ci</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token instruction"><span class="token keyword">COPY</span> action.js /action.js</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token instruction"><span class="token keyword">ENTRYPOINT</span> [<span class="token string">"node"</span>, <span class="token string">"/action.js"</span>]</span>
</span></code></pre>
<p>
  We have defined the dependencies and made sure that an environment can run our action.
  Since we want to set a different PR status based on the workflow, the action needs two <a href="https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#inputs">inputs</a>.
</p>
<ol>
  <li>The kind of status we want to set (<code>pending</code>, <code>success</code>, or <code>failure</code>)</li>
  <li>A description that gives our developers some context</li>
</ol>
<pre class="language-js"><code class="language-js code-highlight"><span class="code-line"><span class="token keyword">const</span> <span class="token punctuation">{</span> <span class="token maybe-class-name">Toolkit</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"actions-toolkit"</span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">const</span> tools <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Toolkit</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token comment">// You could also hard-code these as this</span>
</span><span class="code-line"><span class="token comment">// action is bound to one repo but this makes</span>
</span><span class="code-line"><span class="token comment">// copy-pasting this code easier</span>
</span><span class="code-line"><span class="token keyword">const</span> <span class="token punctuation">{</span> owner<span class="token punctuation">,</span> repo <span class="token punctuation">}</span> <span class="token operator">=</span> tools<span class="token punctuation">.</span><span class="token property-access">context</span><span class="token punctuation">.</span><span class="token property-access">repo</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token comment">// The SHA of the commit that triggered this action.</span>
</span><span class="code-line"><span class="token comment">// Makes sure this status is associated with the</span>
</span><span class="code-line"><span class="token comment">// correct commit.</span>
</span><span class="code-line"><span class="token keyword">const</span> <span class="token punctuation">{</span> sha <span class="token punctuation">}</span> <span class="token operator">=</span> tools<span class="token punctuation">.</span><span class="token property-access">context</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token comment">// These are inputs that we define. You can extend those</span>
</span><span class="code-line"><span class="token comment">// or change their names if you like</span>
</span><span class="code-line"><span class="token keyword">const</span> <span class="token punctuation">{</span> state<span class="token punctuation">,</span> description <span class="token punctuation">}</span> <span class="token operator">=</span> tools<span class="token punctuation">.</span><span class="token property-access">inputs</span>
</span><span class="code-line">
</span><span class="code-line">tools<span class="token punctuation">.</span><span class="token property-access">github</span><span class="token punctuation">.</span><span class="token property-access">repos</span>
</span><span class="code-line">  <span class="token punctuation">.</span><span class="token method function property-access">createStatus</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
</span><span class="code-line">    owner<span class="token punctuation">,</span>
</span><span class="code-line">    repo<span class="token punctuation">,</span>
</span><span class="code-line">    sha<span class="token punctuation">,</span>
</span><span class="code-line">    state<span class="token punctuation">,</span>
</span><span class="code-line">    description<span class="token punctuation">,</span>
</span><span class="code-line">    <span class="token literal-property property">target_url</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">https://www.github.com/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>owner<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>repo<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">/commit/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>sha<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">/checks</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span>
</span><span class="code-line">  <span class="token punctuation">}</span><span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token punctuation">.</span><span class="token method function property-access">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
</span><span class="code-line">    tools<span class="token punctuation">.</span><span class="token property-access">exit</span><span class="token punctuation">.</span><span class="token method function property-access">success</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token punctuation">}</span><span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token punctuation">.</span><span class="token keyword control-flow">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
</span><span class="code-line">    tools<span class="token punctuation">.</span><span class="token property-access">log</span><span class="token punctuation">.</span><span class="token method function property-access">fatal</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span>
</span><span class="code-line">    tools<span class="token punctuation">.</span><span class="token property-access">exit</span><span class="token punctuation">.</span><span class="token method function property-access">failure</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token punctuation">}</span><span class="token punctuation">)</span>
</span></code></pre>
<p>
  You might have noticed that we don't need to do any authentication with GitHub.
  The <code>actions-toolkit</code> library takes care of this for us as long as it finds a <code>GITHUB_TOKEN</code> environment variable with a valid token—more on this in the next section.
</p>
<h2 id="creating-the-workflow">Creating the workflow<a aria-hidden="true" tabindex="-1" href="#creating-the-workflow"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  The primary goal of our workflow is to run our E2E tests.
  If you have skipped the section about adding a custom action, you can skip ahead to <a href="#pointing-the-test-runner-at-the-deployment">Pointing the test runner at the deployment</a>
</p>
<p>
  But it must also make sure that the correct states are shown in the PR.
  Here's what we want to achieve.
</p>
<ul>
  <li>Show a <em>pending</em> state while the deployment isn't ready or the tests are still running</li>
  <li>Show a <em>success</em> state when the tests have finished without errors</li>
  <li>Show a <em>failure</em> state when the tests failed</li>
</ul>
<p>Let's start with setting the state to <code>pending</code>.</p>
<h3 id="registering-a-new-status-check">Registering a new status check<a aria-hidden="true" tabindex="-1" href="#registering-a-new-status-check"><<span></span>></<span></span>></a></h3>
<p>
  We have defined our workflow to run whenever there is a <code>deployment_status</code> event.
  However, we solely want to set the PR status to pending as long as the deployment is also pending.
  Good thing <a href="https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobs">jobs</a> inside a workflow can be <a href="https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idif">conditional</a>.
</p>
<pre class="language-yaml"><code class="language-yaml code-highlight"><span class="code-line"><span class="token key atrule">jobs</span><span class="token punctuation">:</span>
</span><span class="code-line">  <span class="token key atrule">set_pending</span><span class="token punctuation">:</span>
</span><span class="code-line">    <span class="token key atrule">name</span><span class="token punctuation">:</span> Register pending E2E tests state
</span><span class="code-line">    <span class="token comment"># This is the place where we define this job to only</span>
</span><span class="code-line">    <span class="token comment"># run when the deployment state is still "pending".</span>
</span><span class="code-line">    <span class="token key atrule">if</span><span class="token punctuation">:</span> github.event.deployment_status.state == 'pending'
</span><span class="code-line">    <span class="token key atrule">runs-on</span><span class="token punctuation">:</span> ubuntu<span class="token punctuation">-</span>latest
</span><span class="code-line">
</span><span class="code-line">    <span class="token key atrule">steps</span><span class="token punctuation">:</span>
</span><span class="code-line">      <span class="token comment"># This checks out the code of this repository.</span>
</span><span class="code-line">      <span class="token comment"># We need this because this is where our action</span>
</span><span class="code-line">      <span class="token comment"># lives.</span>
</span><span class="code-line">      <span class="token punctuation">-</span> <span class="token key atrule">uses</span><span class="token punctuation">:</span> actions/checkout@v1
</span><span class="code-line">
</span><span class="code-line">      <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Set status to "pending."
</span><span class="code-line">        <span class="token key atrule">uses</span><span class="token punctuation">:</span> ./.github/actions/set<span class="token punctuation">-</span>pr<span class="token punctuation">-</span>status
</span><span class="code-line">        <span class="token key atrule">env</span><span class="token punctuation">:</span>
</span><span class="code-line">          <span class="token comment"># You don't need to configure any secrets for this</span>
</span><span class="code-line">          <span class="token comment"># to work. GitHub injects the GITHUB_TOKEN automatically.</span>
</span><span class="code-line">          <span class="token comment"># We need it in this step so that our action</span>
</span><span class="code-line">          <span class="token comment"># can talk to the GitHub API.</span>
</span><span class="code-line">          <span class="token key atrule">GITHUB_TOKEN</span><span class="token punctuation">:</span> $<span class="token punctuation">{</span><span class="token punctuation">{</span> secrets.GITHUB_TOKEN <span class="token punctuation">}</span><span class="token punctuation">}</span>
</span><span class="code-line">        <span class="token key atrule">with</span><span class="token punctuation">:</span>
</span><span class="code-line">          <span class="token comment"># This is where we define the inputs</span>
</span><span class="code-line">          <span class="token comment"># for this action.</span>
</span><span class="code-line">          <span class="token key atrule">state</span><span class="token punctuation">:</span> pending
</span><span class="code-line">          <span class="token key atrule">description</span><span class="token punctuation">:</span> Waiting for E2E results
</span></code></pre>
<p>If we now open up a PR, we'll see a new status that reports on the status of our E2E tests.</p>
<h3 id="pointing-the-test-runner-at-the-deployment">Pointing the test runner at the deployment<a aria-hidden="true" tabindex="-1" href="#pointing-the-test-runner-at-the-deployment"><<span></span>></<span></span>></a></h3>
<p>
  We're using <code>cypress</code> to run E2E tests.
  In this scenario, we're using the <a href="https://docs.cypress.io/guides/references/configuration.html#Global"><code>baseUrl</code> configuration</a> to point <code>cypress</code> to the location of the Vercel deployment.
  We also make sure that this job only runs when the deployment was successful.
</p>
<pre class="language-yaml"><code class="language-yaml code-highlight"><span class="code-line"><span class="token key atrule">jobs</span><span class="token punctuation">:</span>
</span><span class="code-line">  <span class="token key atrule">run_e2e_tests</span><span class="token punctuation">:</span>
</span><span class="code-line">    <span class="token key atrule">name</span><span class="token punctuation">:</span> Run E2E tests
</span><span class="code-line">    <span class="token comment"># This statement makes sure that this job is only</span>
</span><span class="code-line">    <span class="token comment"># executed when the deployment to Vercel was</span>
</span><span class="code-line">    <span class="token comment"># successful</span>
</span><span class="code-line">    <span class="token key atrule">if</span><span class="token punctuation">:</span> github.event.deployment_status.state == 'success'
</span><span class="code-line">    <span class="token key atrule">runs-on</span><span class="token punctuation">:</span> ubuntu<span class="token punctuation">-</span>latest
</span><span class="code-line">    <span class="token comment"># Thank you cypress for providing a container</span>
</span><span class="code-line">    <span class="token comment"># that works out-of-the-box</span>
</span><span class="code-line">    <span class="token key atrule">container</span><span class="token punctuation">:</span> cypress/browsers<span class="token punctuation">:</span>node11.13.0<span class="token punctuation">-</span>chrome73
</span><span class="code-line">    <span class="token key atrule">env</span><span class="token punctuation">:</span>
</span><span class="code-line">      <span class="token key atrule">TERM</span><span class="token punctuation">:</span> xterm
</span><span class="code-line">
</span><span class="code-line">    <span class="token key atrule">steps</span><span class="token punctuation">:</span>
</span><span class="code-line">      <span class="token punctuation">-</span> <span class="token key atrule">uses</span><span class="token punctuation">:</span> actions/checkout@v1
</span><span class="code-line">
</span><span class="code-line">      <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Run E2E tests
</span><span class="code-line">        <span class="token key atrule">run</span><span class="token punctuation">:</span> cypress <span class="token punctuation">-</span><span class="token punctuation">-</span>config baseUrl=$<span class="token punctuation">{</span><span class="token punctuation">{</span> github.event.deployment_status.target_url <span class="token punctuation">}</span><span class="token punctuation">}</span>
</span></code></pre>
<h3 id="reporting-the-result-of-the-tests-back">Reporting the result of the tests back<a aria-hidden="true" tabindex="-1" href="#reporting-the-result-of-the-tests-back"><<span></span>></<span></span>></a></h3>
<p>
  The last thing we need to do is to set the status to <code>success</code> when the tests passed and to <code>failure</code> when they did not pass.
  We can use the exit code of <code>cypress</code> for that.
  When a test does not succeed, <code>cypress</code> will exit with a non-zero <a href="https://en.wikipedia.org/wiki/Exit_status">exit code</a> and mark the job as a failure.
</p>
<pre class="language-yaml"><code class="language-yaml code-highlight"><span class="code-line"><span class="token key atrule">jobs</span><span class="token punctuation">:</span>
</span><span class="code-line">  <span class="token key atrule">run_e2e_tests</span><span class="token punctuation">:</span>
</span><span class="code-line">  <span class="token comment"># See above for the complete definition of this job</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token key atrule">steps</span><span class="token punctuation">:</span>
</span><span class="code-line">    <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Set status to "success"
</span><span class="code-line">      <span class="token comment"># The "if" underneath makes sure that this step</span>
</span><span class="code-line">      <span class="token comment"># runs solely when the step before was successful</span>
</span><span class="code-line">      <span class="token key atrule">if</span><span class="token punctuation">:</span> success()
</span><span class="code-line">      <span class="token key atrule">uses</span><span class="token punctuation">:</span> ./.github/actions/set<span class="token punctuation">-</span>pr<span class="token punctuation">-</span>status
</span><span class="code-line">      <span class="token key atrule">env</span><span class="token punctuation">:</span>
</span><span class="code-line">        <span class="token key atrule">GITHUB_TOKEN</span><span class="token punctuation">:</span> $<span class="token punctuation">{</span><span class="token punctuation">{</span> secrets.GITHUB_TOKEN <span class="token punctuation">}</span><span class="token punctuation">}</span>
</span><span class="code-line">      <span class="token key atrule">with</span><span class="token punctuation">:</span>
</span><span class="code-line">        <span class="token key atrule">state</span><span class="token punctuation">:</span> success
</span><span class="code-line">        <span class="token key atrule">description</span><span class="token punctuation">:</span> All tests passed
</span><span class="code-line">
</span><span class="code-line">    <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Set status to "failure"
</span><span class="code-line">      <span class="token comment"># The "if" underneath makes sure that this step</span>
</span><span class="code-line">      <span class="token comment"># runs solely when the step before was *not* successful</span>
</span><span class="code-line">      <span class="token key atrule">if</span><span class="token punctuation">:</span> failure()
</span><span class="code-line">      <span class="token key atrule">uses</span><span class="token punctuation">:</span> ./.github/actions/set<span class="token punctuation">-</span>pr<span class="token punctuation">-</span>status
</span><span class="code-line">      <span class="token key atrule">env</span><span class="token punctuation">:</span>
</span><span class="code-line">        <span class="token key atrule">GITHUB_TOKEN</span><span class="token punctuation">:</span> $<span class="token punctuation">{</span><span class="token punctuation">{</span> secrets.GITHUB_TOKEN <span class="token punctuation">}</span><span class="token punctuation">}</span>
</span><span class="code-line">      <span class="token key atrule">with</span><span class="token punctuation">:</span>
</span><span class="code-line">        <span class="token key atrule">state</span><span class="token punctuation">:</span> failure
</span><span class="code-line">        <span class="token key atrule">description</span><span class="token punctuation">:</span> Some tests failed
</span></code></pre>
<p>That's it! We have created a custom action that we can use to set a status check on a PR and a workflow that will run our end-to-end tests when a deployment is ready.</p>
<h2 id="caveats">Caveats<a aria-hidden="true" tabindex="-1" href="#caveats"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  I like to mention one thing that probably cost me an hour right at the start.
  Because I was thinking in the context of a PR I always looked for the deployment action in the "Checks" tab of a single PR.
  But that is not how this works.
  Since deployments are not necessarily coupled to a PR, GitHub lists them in the "Actions" tab for the whole repository.
  I hope this piece of information saves you some time!
</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[ Tests that help you find defects faster ]]></title>
      <description><![CDATA[ This is one of the most important lessons I try to teach less experienced developers. Next to making sure that your code works now, it's also essential to make… ]]></description>
      <link>https://www.philgiese.com/post/tests-that-help-you-find-defects-faster</link>
      <guid isPermaLink="false">https://www.philgiese.com/post/tests-that-help-you-find-defects-faster</guid>
      <dc:creator>Philipp Giese</dc:creator>
      <pubDate>Mon, 13 Jul 2020 00:00:00 GMT</pubDate>
      <category>testing</category>
      <category>assertions</category>
      <category>bugs</category>
      <category>tdd</category>
      <content:encoded><![CDATA[
<p>
  This is one of the most important lessons I try to teach less experienced developers.
  Next to making sure that your code works <strong>now</strong>, it's also essential to make sure that developers can fix defects in the future.
  The first step to achieving this is to write tests.
  Preferably, you are writing the tests <a href="https://en.wikipedia.org/wiki/Test-driven_development">before you write the code</a>.
  But even if you have done that, your tests might still be inaccessible to other developers or make it hard for them to figure out what broke.
  Here's my list of properties that make tests go from good to great.
</p>
<h2 id="tldr">TL;DR<a aria-hidden="true" tabindex="-1" href="#tldr"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>If you don't want to read the whole article, here is the list. Click on each entry to find out the details.</p>
<ul>
  <li><a href="#mixed-concerns-in-tests">Each test should test one thing and one thing only</a></li>
  <li><a href="#extraneous-data-in-tests">The test should do this with precisely the data it needs, nothing more</a></li>
  <li><a href="#bloated-test-hooks">There should be no connection between tests</a></li>
  <li><a href="#no-proper-use-of-assertions">When the test fails, the error message should provide context to finding the problem</a></li>
</ul>
<h2 id="mixed-concerns-in-tests">Mixed concerns in tests<a aria-hidden="true" tabindex="-1" href="#mixed-concerns-in-tests"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  A <a href="https://en.wikipedia.org/wiki/Concern_(computer_science)">concern</a> in software engineering is the <em>what</em> in "What does this code do?".
  If your code reads from the command line and writes to a database, you are handling <em>at least</em> two concerns.
  When you are testing your code, it's important to test one concern at a time.
  When a test fails, you have a much clearer picture of what aspect of your code isn't working correctly anymore.
  If your tests are handling two or more concerns simultaneously, you have to do some extra work before you can even start looking at what is wrong.
  You need to:
</p>
<ul>
  <li>figure out the number of concerns the test handles,</li>
  <li>how they relate to each other, and</li>
  <li>which one causes the trouble.</li>
</ul>
<p>All this extra work takes time which might be critical depending on the defect.</p>
<p>
  I follow a simple rule of thumb.
  Whenever I write the word "and" in a test description, I write two tests instead.
  Let's look at an example.
</p>
<pre class="language-js"><code class="language-js code-highlight"><span class="code-line"><span class="token function">describe</span><span class="token punctuation">(</span><span class="token string">"Database manager"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token function">it</span><span class="token punctuation">(</span><span class="token string">"should support reading and writing to the database"</span><span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span><span class="token punctuation">)</span>
</span></code></pre>
<p>
  This might be a great test that fails when something with the database connection is wrong.
  But could you tell which part has a problem?
  It could be the part of the application that reads the data, but it could also be the part that writes it.
  Even worse, it could be both.
  We can get out of this situation by splitting this test into two.
</p>
<pre class="language-js"><code class="language-js code-highlight"><span class="code-line"><span class="token function">describe</span><span class="token punctuation">(</span><span class="token string">"Database manager"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token function">it</span><span class="token punctuation">(</span><span class="token string">"should support reading from the database."</span><span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token function">it</span><span class="token punctuation">(</span><span class="token string">"should support writing to the database."</span><span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span><span class="token punctuation">)</span>
</span></code></pre>
<p>
  Now when the first test fails, we know something is wrong with the code that reads data.
  Respectively, we know that when the second test fails, the code that reads from the database has a flaw.
</p>
<p>
  For me, not combining tests is hard when I'm starting on a new feature, and all the different use cases I need to test pop into my head.
  In these situations, I use <a href="https://jestjs.io/docs/en/api#testtodoname">to-do tests</a> (I mainly work with <a href="https://jestjs.io/en/"><code>jest</code></a>).
  To-dos help me track what I still need to implement without bloating the existing tests that I have already written.
</p>
<h2 id="extraneous-data-in-tests">Extraneous data in tests<a aria-hidden="true" tabindex="-1" href="#extraneous-data-in-tests"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  I like my tests best when they are concise.
  For me, this means that every line of code inside a test has a purpose.
  For instance, imagine a test like the following.
</p>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token function">it</span><span class="token punctuation">(</span><span class="token string">"should communicate the value when a user changes the input."</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword">const</span> onChange <span class="token operator">=</span> jest<span class="token punctuation">.</span><span class="token method function property-access">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token keyword">const</span> onKeyDown <span class="token operator">=</span> jest<span class="token punctuation">.</span><span class="token method function property-access">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token keyword">const</span> value <span class="token operator">=</span> <span class="token string">"test value"</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token function">render</span><span class="token punctuation">(</span>
</span><span class="code-line">    <span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span><span class="token class-name">Component</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>initialValue<span class="token punctuation">"</span></span> <span class="token attr-name">onChange</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>onChange<span class="token punctuation">}</span></span> <span class="token attr-name">onKeyDown</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>onKeyDown<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span>
</span><span class="code-line">  <span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  fireEvent<span class="token punctuation">.</span><span class="token method function property-access">click</span><span class="token punctuation">(</span>screen<span class="token punctuation">.</span><span class="token method function property-access">getByRole</span><span class="token punctuation">(</span><span class="token string">"textbox"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
</span><span class="code-line">  fireEvent<span class="token punctuation">.</span><span class="token method function property-access">change</span><span class="token punctuation">(</span>screen<span class="token punctuation">.</span><span class="token method function property-access">getByRole</span><span class="token punctuation">(</span><span class="token string">"textbox"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">target</span><span class="token operator">:</span> <span class="token punctuation">{</span> value <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
</span><span class="code-line">  fireEvent<span class="token punctuation">.</span><span class="token method function property-access">blur</span><span class="token punctuation">(</span>screen<span class="token punctuation">.</span><span class="token method function property-access">getByRole</span><span class="token punctuation">(</span><span class="token string">"textbox"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token function">expect</span><span class="token punctuation">(</span>onChange<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">toHaveBeenCalledWith</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span><span class="token punctuation">)</span>
</span></code></pre>
<p>Now, answer the following questions:</p>
<ul>
  <li>Why do we need to set an <code>onKeyDown</code> handler?</li>
  <li>Is it essential first to click and also blur the <code>input</code>?</li>
  <li>Does this component require an initial <code>value</code> to work correctly?</li>
</ul>
<p>
  Probably you can't answer any question with "yes" or "no."
  At least not without looking into other tests or into the code that we test.
</p>
<p>
  If your test needs to perform some non-trivial actions, you might want to extract them into another function with a descriptive name.
  For instance, if clicking and blurring are important to change the input, then you could create a <code>simulateChange</code> helper.
</p>
<pre class="language-js"><code class="language-js code-highlight"><span class="code-line"><span class="token keyword">function</span> <span class="token function">simulateChange</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</span><span class="code-line">  fireEvent<span class="token punctuation">.</span><span class="token method function property-access">click</span><span class="token punctuation">(</span>screen<span class="token punctuation">.</span><span class="token method function property-access">getByRole</span><span class="token punctuation">(</span><span class="token string">"textbox"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
</span><span class="code-line">  fireEvent<span class="token punctuation">.</span><span class="token method function property-access">change</span><span class="token punctuation">(</span>screen<span class="token punctuation">.</span><span class="token method function property-access">getByRole</span><span class="token punctuation">(</span><span class="token string">"textbox"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">target</span><span class="token operator">:</span> <span class="token punctuation">{</span> value <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
</span><span class="code-line">  fireEvent<span class="token punctuation">.</span><span class="token method function property-access">blur</span><span class="token punctuation">(</span>screen<span class="token punctuation">.</span><span class="token method function property-access">getByRole</span><span class="token punctuation">(</span><span class="token string">"textbox"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span></code></pre>
<p>This makes the test easier to read and clarifies that a change consists of multiple steps.</p>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token function">it</span><span class="token punctuation">(</span><span class="token string">"should communicate the value when a user changes the input."</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword">const</span> onChange <span class="token operator">=</span> jest<span class="token punctuation">.</span><span class="token method function property-access">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token keyword">const</span> onKeyDown <span class="token operator">=</span> jest<span class="token punctuation">.</span><span class="token method function property-access">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token keyword">const</span> value <span class="token operator">=</span> <span class="token string">"test value"</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token function">render</span><span class="token punctuation">(</span>
</span><span class="code-line">    <span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span><span class="token class-name">Component</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>initialValue<span class="token punctuation">"</span></span> <span class="token attr-name">onChange</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>onChange<span class="token punctuation">}</span></span> <span class="token attr-name">onKeyDown</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>onKeyDown<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span>
</span><span class="code-line">  <span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token function">simulateChange</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token function">expect</span><span class="token punctuation">(</span>onChange<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">toHaveBeenCalledWith</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span><span class="token punctuation">)</span>
</span></code></pre>
<p>
  We still have parts of our test that are not self-explanatory.
  For instance, the <code>onKeyDown</code> handler is a <a href="https://jestjs.io/docs/en/mock-functions">mock function</a>, but there is no assertion for it.
  We should probably add a comment if we need to assign the <code>value</code> prop and the <code>onKeyDown</code> handler for the test to work.
  But if neither is essential for that test to work, then we can remove them.
</p>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token function">it</span><span class="token punctuation">(</span><span class="token string">"should communicate the value when a user changes the input."</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword">const</span> onChange <span class="token operator">=</span> jest<span class="token punctuation">.</span><span class="token method function property-access">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</span><span class="code-line">  <span class="token keyword">const</span> value <span class="token operator">=</span> <span class="token string">"test value"</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token function">render</span><span class="token punctuation">(</span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span><span class="token class-name">Component</span></span> <span class="token attr-name">onChange</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>onChange<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token function">simulateChange</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token function">expect</span><span class="token punctuation">(</span>onChange<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">toHaveBeenCalledWith</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span><span class="token punctuation">)</span>
</span></code></pre>
<p>We now have reduced the test to what is essential and made sure that future readers have less trouble understanding it.</p>
<h2 id="bloated-test-hooks">Bloated test hooks<a aria-hidden="true" tabindex="-1" href="#bloated-test-hooks"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Some developers know that <a href="https://en.wikipedia.org/wiki/Test-driven_development#Practices_to_avoid,_or_%22anti-patterns%22">interdependent tests</a> aren't desirable.
  In practice, this means that when you change one test, another one might fail.
  "Bloated test hooks" are my special version of this.
</p>
<p>
  Tests can become interdependent when one test relies on the fact that another test has run before.
  The same applies if tests rely on a shared setup.
</p>
<p><a href="https://twitter.com/mfeathers/status/1281384915842371590">https://twitter.com/mfeathers/status/1281384915842371590</a></p>
<p>You can run into this situation in the <a href="https://reactjs.org/"><code>react</code></a> world when you have a common <code>render</code> mechanism that's shared between tests. Let's look at the following example of a test that ensures that an <code>onClick</code> handler is called when a user clicks a button.</p>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token keyword">let</span> onClick <span class="token operator">=</span> jest<span class="token punctuation">.</span><span class="token method function property-access">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token function">beforeEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token function">render</span><span class="token punctuation">(</span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span><span class="token class-name">Button</span></span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>onClick<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token function">it</span><span class="token punctuation">(</span><span class="token string">"should communicate when the button was clicked"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
</span><span class="code-line">  fireEvent<span class="token punctuation">.</span><span class="token method function property-access">click</span><span class="token punctuation">(</span>screen<span class="token punctuation">.</span><span class="token method function property-access">getByRole</span><span class="token punctuation">(</span><span class="token string">"button"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token function">expect</span><span class="token punctuation">(</span>onClick<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">toHaveBeenCalled</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span><span class="token punctuation">)</span>
</span></code></pre>
<p>
  This test runs fine.
  The developer might have chosen to put the <code>onClick</code> handler outside the scope of the test because she wanted to avoid <a href="#extraneous-data-in-tests"><em>extraneous data</em></a> in the test itself.
  I observe this behavior when developers try to keep their tests <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a>.
  We need to free ourselves from being strictly DRY in test cases.
  Some repetition is good when it's needed for the individual use case.
</p>
<p>Imagine we wanted to add another use case that asserts that disabled buttons cannot be clicked.</p>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token function">it</span><span class="token punctuation">(</span><span class="token string">"should not be possible to click disabled buttons."</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token function">render</span><span class="token punctuation">(</span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span><span class="token class-name">Button</span></span> <span class="token attr-name">disabled</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>onClick<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  fireEvent<span class="token punctuation">.</span><span class="token method function property-access">click</span><span class="token punctuation">(</span>screen<span class="token punctuation">.</span><span class="token method function property-access">getByRole</span><span class="token punctuation">(</span><span class="token string">"button"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token function">expect</span><span class="token punctuation">(</span>onClick<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token property-access">not</span><span class="token punctuation">.</span><span class="token method function property-access">toHaveBeenCalled</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span><span class="token punctuation">)</span>
</span></code></pre>
<p>
  What do you think will happen?
  Will the test fail or succeed?
  We can't be sure.
  If the test happens to run <strong>before</strong> the other test, then it will probably succeed.
  But if the test runs <strong>after</strong> the first one, then it will break.
  We've introduced interdependence between the tests by extracting the <code>onClick</code> handler mock.
</p>
<p>
  To resolve the connection between the two tests, we need to move everything that is important for a test case into the test itself.
  In both tests, we are asserting whether the <code>onClick</code> handler was called or not.
  Even though it seems like we're repeating ourselves, it's much better to move that setup into each test case to make it evident that this is important for that particular test to achieve its goal.
</p>
<pre class="language-jsx"><code class="language-jsx code-highlight"><span class="code-line"><span class="token function">it</span><span class="token punctuation">(</span><span class="token string">"should communicate when the button was clicked"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword">const</span> onClick <span class="token operator">=</span> jest<span class="token punctuation">.</span><span class="token method function property-access">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token function">render</span><span class="token punctuation">(</span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span><span class="token class-name">Button</span></span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>onClick<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  fireEvent<span class="token punctuation">.</span><span class="token method function property-access">click</span><span class="token punctuation">(</span>screen<span class="token punctuation">.</span><span class="token method function property-access">getByRole</span><span class="token punctuation">(</span><span class="token string">"button"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token function">expect</span><span class="token punctuation">(</span>onClick<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">toHaveBeenCalled</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token function">it</span><span class="token punctuation">(</span><span class="token string">"should not be possible to click disabled buttons."</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
</span><span class="code-line">  <span class="token keyword">const</span> onClick <span class="token operator">=</span> jest<span class="token punctuation">.</span><span class="token method function property-access">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token function">render</span><span class="token punctuation">(</span><span class="token tag"><span class="token tag"><span class="token punctuation">&#x3C;</span><span class="token class-name">Button</span></span> <span class="token attr-name">disabled</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>onClick<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  fireEvent<span class="token punctuation">.</span><span class="token method function property-access">click</span><span class="token punctuation">(</span>screen<span class="token punctuation">.</span><span class="token method function property-access">getByRole</span><span class="token punctuation">(</span><span class="token string">"button"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">  <span class="token function">expect</span><span class="token punctuation">(</span>onClick<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token property-access">not</span><span class="token punctuation">.</span><span class="token method function property-access">toHaveBeenCalled</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</span><span class="code-line"><span class="token punctuation">}</span><span class="token punctuation">)</span>
</span></code></pre>
<p>
  With this change, every test case is slightly larger but also encapsulates all the code it needs.
  We could now also move the rendering part into each test.
</p>
<p>
  But some developers prefer to keep rendering the component outside of the specs.
  Go with what you think feels best but does not hinder you from writing well-encapsulated specs.
</p>
<h2 id="no-proper-use-of-assertions">No proper use of assertions<a aria-hidden="true" tabindex="-1" href="#no-proper-use-of-assertions"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  When you are not working with TDD, this is the easiest one to get wrong without noticing it.
  It all comes down to the fact that we can express 99% of assertions as an equality check.
  Let's look at some examples.
</p>
<pre class="language-js"><code class="language-js code-highlight"><span class="code-line"><span class="token function">expect</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span><span class="token property-access">name</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">toEqual</span><span class="token punctuation">(</span><span class="token string">"John"</span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token function">expect</span><span class="token punctuation">(</span>screen<span class="token punctuation">.</span><span class="token method function property-access">getByRole</span><span class="token punctuation">(</span><span class="token string">"button"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token property-access">disabled</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">toEqual</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token function">expect</span><span class="token punctuation">(</span>error<span class="token punctuation">.</span><span class="token method function property-access">indexOf</span><span class="token punctuation">(</span><span class="token string">"A custom error message"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token property-access">not</span><span class="token punctuation">.</span><span class="token method function property-access">toEqual</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span>
</span></code></pre>
<p>
  None of the above assertions are incorrect.
  They might also represent the mental model of the developer when she wrote the spec.
  What's the problem then?
  Let's look at what you might see in your console when these tests fail.
</p>
<pre class="language-js"><code class="language-js code-highlight"><span class="code-line"><span class="token function">expect</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span><span class="token property-access">name</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">toEqual</span><span class="token punctuation">(</span><span class="token string">"John"</span><span class="token punctuation">)</span>
</span><span class="code-line"><span class="token comment">// > Expected "Jane" to equal "John"</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token function">expect</span><span class="token punctuation">(</span>screen<span class="token punctuation">.</span><span class="token method function property-access">getByRole</span><span class="token punctuation">(</span><span class="token string">"button"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token property-access">disabled</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">toEqual</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span>
</span><span class="code-line"><span class="token comment">// > Expected "false" to equal "true"</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token function">expect</span><span class="token punctuation">(</span>error<span class="token punctuation">.</span><span class="token method function property-access">indexOf</span><span class="token punctuation">(</span><span class="token string">"A custom error message"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token property-access">not</span><span class="token punctuation">.</span><span class="token method function property-access">toEqual</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span>
</span><span class="code-line"><span class="token comment">// > Expected "-1" not to equal "-1"</span>
</span></code></pre>
<p>
  When I look at that output, I definitively also need to look at the respective test to figure out what's wrong.
  But I'm not particularly eager to do that.
  I'm probably working on something specific, and one of my changes made that test fail.
  Wouldn't it be great if the test failure could give me more detail?
  Then I might realize what my mistake is without the need to switch context and read the code of the test that failed.
</p>
<p>
  The good news is that every testing framework I know has more specific assertions.
  We "just" need to use them.
  I would rewrite the tests a follows (using <a href="https://jestjs.io/docs/en/expect#tohavepropertykeypath-value">jest</a> and <a href="https://github.com/FormidableLabs/enzyme-matchers/tree/master/packages/jest-enzyme#readme">jest-enzyme</a> assertions).
</p>
<pre class="language-js"><code class="language-js code-highlight"><span class="code-line"><span class="token function">expect</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">toHaveProperty</span><span class="token punctuation">(</span><span class="token string">"name"</span><span class="token punctuation">,</span> <span class="token string">"John"</span><span class="token punctuation">)</span>
</span><span class="code-line"><span class="token comment">// > Expected property "name" to have value "John", but got "Jane"</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token function">expect</span><span class="token punctuation">(</span>screen<span class="token punctuation">.</span><span class="token method function property-access">getByRole</span><span class="token punctuation">(</span><span class="token string">"button"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">toBeDisabled</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</span><span class="code-line"><span class="token comment">// > Expected prop "disabled" to be "true", but got "false"</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token function">expect</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">toContainText</span><span class="token punctuation">(</span><span class="token string">"A custom error message"</span><span class="token punctuation">)</span>
</span><span class="code-line"><span class="token comment">// > Expected "Generic error" to contain "A custom error message", but it didn't</span>
</span></code></pre>
<p>
  The advantage of this approach is that the failing tests now give you some context about why they fail.
  For instance, you now know that when <code>John</code> did not equal <code>Jane</code>, that had something to do with a <code>name</code> property.
  Or that when <code>true</code> wasn't <code>false</code>, this was about the <code>disabled</code> prop of a component.
  Even though these are small pieces of information they might save you a lot of time over the course of your career.
</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[ Automated releases with semantic-release ]]></title>
      <description><![CDATA[ During the last year I've become more involved in building the design system we use at Signavio. While doing so rolling out changes to the company turned out… ]]></description>
      <link>https://www.philgiese.com/post/automated-releases-with-semantic-release</link>
      <guid isPermaLink="false">https://www.philgiese.com/post/automated-releases-with-semantic-release</guid>
      <dc:creator>Philipp Giese</dc:creator>
      <pubDate>Mon, 06 Jul 2020 00:00:00 GMT</pubDate>
      <category>process</category>
      <category>tooling</category>
      <category>releases</category>
      <content:encoded><![CDATA[
<p>
  During the last year I've become more involved in building the design system we use at <a href="https://www.signavio.com">Signavio</a>.
  While doing so rolling out changes to the company turned out to be a major challenge.
  We had been doing it for some time but we somehow managed to get certain parts wrong all the time.
  Sometimes we released breaking changes with minor updates or forgot to write proper release notes.
  A developer who did not contribute to the design system on a regular basis could make mistakes way too easy.
  Initially, we thought that what we were missing was proper documentation but it turned out no one reads the docs anyway.
</p>
<p>
  When we rebooted the design system I took it upon myself to try to solve at least some of these issues.
  We had been using a tool called <a href="https://semantic-release.gitbook.io/semantic-release/"><code>sematic-release</code></a> on <a href="https://github.com/signavio/react-mentions">another project</a> already (so I had at least some experience) and decided to use it here as well.
  I made a small list of requirements that I would like the solution to support.
  It should:
</p>
<ul>
  <li>force developers to think about the implications of their work while they were doing it</li>
  <li>automate most of the process to remove the possibility of human error</li>
  <li>be nice enough that even managers see the value</li>
</ul>
<h2 id="semantic-versioning">Semantic versioning<a aria-hidden="true" tabindex="-1" href="#semantic-versioning"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Much to the surprise of some developers the numbers we put behind our releases actually have well defined meaning.
  Well, that means at least if you follow semantic versioning, or <a href="https://semver.org/">SemVer</a>.
</p>
<p>
  A version number follows the <code>major.minor.patch</code> schema.
  If you increase the <code>patch</code> number you've, for instance, fixed a bug.
  You definitively have not added some new functionality.
  Because then you would have increased the <code>minor</code> version.
  Generally speaking increases to the <code>patch</code> or <code>minor</code> numbers represent non-breaking changes.
  This is helpful to determine whether your software is compatible with an update.
  Let's say you're running on version <code>1.0.2</code> and there is an update incoming with the version <code>1.3.2</code>.
  As this means that the changes are either new functionality or bug fixes, you can upgrade without breaking your existing code.
  This isn't the case when the <code>major</code> version increases.
  If this happens it indicates a <strong>breaking change</strong>.
  The biggest question you now have to answer is "What is the breaking change?" and "Does it affect me?".
</p>
<p>
  We see that the version number plays an important role in figuring out whether an update is safe or not.
  If we want to know <em>what</em> changed then the version number isn't enough.
  We need to see a changelog or release notes.
</p>
<p>
  If we assume that developers understand what they're doing while they are doing it we can leverage this fact.
  <code>semantic-release</code> creates release notes based on the commit history of a repository.
  In order for this to work developers need to adhere to a format called <a href="https://www.conventionalcommits.org/en/">semantic commit messages</a>.
  A regular commit includes information about <em>what</em> has changed.
  A semantic commit also adds <em>context</em> to that information.
  For instance the commit message
</p>
<pre class="language-git"><code class="language-git code-highlight"><span class="code-line">button did not accept onClick handler
</span></code></pre>
<p>becomes</p>
<pre class="language-git"><code class="language-git code-highlight"><span class="code-line">fix: button did not accept onClick handler
</span></code></pre>
<p>
  This is a small change but now <code>semantic-release</code> is able to figure out that this commit contains a bug fix and can use the commit message as the description for what the developer fixed.
  Admittedly, this requires some effort by developers but tools like <a href="https://github.com/commitizen/cz-cli"><code>commitizen</code></a> help to make the transition less painful.
  We also introduced <a href="https://github.com/typicode/husky"><code>husky</code></a> so that there is a <a href="https://githooks.com/">precommit hook</a> that makes sure every commit follows this pattern.
</p>
<h2 id="benefits-of-this-approach">Benefits of this approach<a aria-hidden="true" tabindex="-1" href="#benefits-of-this-approach"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  Every time you automate something the immediate benefit is that you reduce the chance of human error.
  Restricting yourself to a certain way to phrase commit messages yields some immediate improvements (e.g. automated release notes) but is also a forcing function that influences how people work.
  Automating away a task that people did not want to do was a great incentive to write better commit messages.
  And if you get into the habit of slicing your work into smaller pieces then this also improves the work on other projects.
</p>
<h3 id="no-manual-releases">No manual releases<a aria-hidden="true" tabindex="-1" href="#no-manual-releases"><<span></span>></<span></span>></a></h3>
<p>
  The most obvious benefit, of course, is that you'll never have to write <code>npm publish</code> again.
  Even better no one has to do that anymore so you've prevented people from making this mistake.
</p>
<h3 id="structured-release-notes">Structured release notes<a aria-hidden="true" tabindex="-1" href="#structured-release-notes"><<span></span>></<span></span>></a></h3>
<p>
  From now on your release notes will all follow the same structure.
  If you're like me then this already will make you happy.
  You get separate lists for features and bug fixes and breaking changes <strong>always</strong> stick out.
</p>
<h3 id="automatic-notifications-for-developers">Automatic notifications for developers<a aria-hidden="true" tabindex="-1" href="#automatic-notifications-for-developers"><<span></span>></<span></span>></a></h3>
<p>
  When <code>semantic-release</code> releases a new version it also automatically adds a comment and a label to PRs and issues that make up the release.
  Now developers know when their changes are live and which version includes them.
  This makes communication much easier.
  By also tagging PRs and issues you always know which issues are still unresolved and which ones have been fixed and released.
  That manager of yours who always wants the latest status report?
  Send him a link to a prefiltered list on <a href="https://github.com/">GitHub</a>.
</p>
<h3 id="way-better-commit-messages">Way better commit messages<a aria-hidden="true" tabindex="-1" href="#way-better-commit-messages"><<span></span>></<span></span>></a></h3>
<p>
  If you thought writing some meaningful comments is hard, you haven't looked at commit messages.
  Even though developers will complain in the beginning, the commit messages in the repository will get noticeably better.
  You can support this by posting a preview of the release notes into each PR.
</p>
<h2 id="release-channels">Release channels<a aria-hidden="true" tabindex="-1" href="#release-channels"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  By default <code>semantic-release</code> will use <code>master</code> as the main release channel.
  This means that whenever someone pushes new commits to <code>master</code> <code>semantic-release</code> analyzes them and creates a new release if necessary.
</p>
<p>
  If you like to learn more about <a href="https://semantic-release.gitbook.io/semantic-release/usage/configuration#branches">all the options</a> then have a look at the docs.
  For instance, we are using a <code>beta</code> branch to create prereleases of certain upcoming major updates.
  This helps developers as they get beta versions that they can take for a test drive and report errors back to you.
  Also, this creates defined spots in your repository that will have these kinds of changes.
  Whenever someone wants to know whether there is a big thing upcoming they can look for prereleases or commits on the respective beta branches.
</p>
<h2 id="what-this-means-for-your-git-workflow">What this means for your git workflow<a aria-hidden="true" tabindex="-1" href="#what-this-means-for-your-git-workflow"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>
  That hugely depends on what your git workflow <em>is</em>.
  For the sake of this example lets assume that you're using feature branches.
  Since <code>semantic-release</code> gets all information from the individual commits you will get into trouble when you're squashing commits.
  That's because <code>semantic-release</code> solely considers the header (i.e. the first line) of your commit message.
  The body of your commit message should contain information about breaking changes.
  When you feel like you have more to say about a change than fits in one line you should consider making it two smaller changes.
  This means that <code>semantic-release</code> works best when you always rebase branches on the latest version of <code>master</code> and then use a rebase merge.
  Personally, I had to get used to this because I liked how squash commits encapsulate a thing in one commit.
  In theory you can still use squash commits if you restrain yourself to do one thing in a PR.
  Then you can make the commit message of the squash commit express what you did.
  In our use case that did not align with how people wanted to work.
  We then ended up with release notes that didn't contain all changes or PRs that did not result in a release because someone didn't pay enough attention to what the final commit message would look like.
</p>
<h2 id="caveats">Caveats<a aria-hidden="true" tabindex="-1" href="#caveats"><<svg class="h-5 w-5" xmlns="http://www class="w3 org/2000/svg&#x22; fill=&#x22;none&#x22; viewBox=&#x22;0 0 24 24&#x22; stroke-width=&#x22;1 5&#x22; stroke=&#x22;currentColor&#x22; class=&#x22;w-6 h-6&#x22;>
              <path stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; d=&#x22;M13 19 8 688a4 5 4 5 0 011 242 7 244l-4 5 4 5a4 5 4 5 0 01-6 364-6 364l1 757-1 757m13 35- 622l1 757-1 757a4 5 4 5 0 00-6 364-6 364l-4 5 4 5a4 5 4 5 0 001 242 7 244&#x22; />
            </svg>"></<svg class="h-5 w-5" xmlns="http://www></a></h2>
<p>Even though I might have made it sound like <code>semantic-release</code> is the solution to all your problems (and it solved a lot of ours) there are some caveats to consider.</p>
<h3 id="history-rewrites-of-release-branches">History rewrites of release branches<a aria-hidden="true" tabindex="-1" href="#history-rewrites-of-release-branches"><<span></span>></<span></span>></a></h3>
<p>
  When I was dealing with both our <code>master</code> and <code>beta</code> branches at some point I wanted to update <code>beta</code>.
  Out of habit I decided to rebase <code>beta</code> on the latest version of <code>master</code>.
  In hindsight that was a mistake.
  The issue is that <code>semantic-release</code> now could not associate the previous releases on <code>beta</code> with the commits that it saw.
  That meant it tried to <strong>start over</strong> with the prereleases.
  Of course, this wasn't possible because the release it then tried to create already existed.
</p>
<p><strong>TL;DR</strong> do not rewrite history of release branches!</p>
<h3 id="release-previews">Release previews<a aria-hidden="true" tabindex="-1" href="#release-previews"><<span></span>></<span></span>></a></h3>
<p>
  <code>semantic-release</code> offers a <a href="https://semantic-release.gitbook.io/semantic-release/usage/configuration#dryrun">dry-run</a> option.
  This one sounds pretty much like the thing you want to do to preview what the next release would be.
  At least this was what I thought.
  Even though I was able to get it to work it turns out that the output of that command <em>resembles</em> the final release notes but isn't identical to what you will see on GitHub.
  You will need to be careful what you present as a preview to not give your developers a false impression of what is about to happen.
</p>
<h3 id="package-version-fixed-to-000-development">Package version fixed to <code>0.0.0-development</code><a aria-hidden="true" tabindex="-1" href="#package-version-fixed-to-000-development"><<span></span>></<span></span>></a></h3>
<p>
  To discourage developers even further from fiddling with the package version you need to set it to <code>0.0.0-development</code> in your <code>package.json</code>.
  That's fine because <code>semantic-release</code> will take care of that for you.
  It turns out that this can be <strong>confusing</strong> for developers who don't know what's going on.
  Make sure you either on-board people properly or add a large enough hint to the <code>README</code> of the respective repository.
</p>
<h3 id="no-monorepo-support">No monorepo support<a aria-hidden="true" tabindex="-1" href="#no-monorepo-support"><<span></span>></<span></span>></a></h3>
<p>
  <code>semantic-release</code> does not support monorepos.
  You can find an exhaustive explanation <a href="https://github.com/semantic-release/semantic-release/issues/193">on GitHub</a>.
  The gist is that it can not determine which package to release first.
</p>
<p>
  Imagine a package structure <code>A > B > C</code> which means that package <code>A</code> depends on package <code>B</code> which depends on package <code>C</code>.
  In this scenario <code>semantic-release</code> would need to release package <code>C</code> first, then update the <code>package.json</code> of <code>B</code> and release package <code>B</code>.
  Then it can update the <code>package.json</code> of package <code>A</code> and release this one as well.
  This makes the whole process of what needs to happen much more complicated.
</p>
]]></content:encoded>
    </item>
  </channel>
</rss>