<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.2.2">Jekyll</generator><link href="https://chocolatedrivendevelopment.com/feed/by_tag/code.xml" rel="self" type="application/atom+xml" /><link href="https://chocolatedrivendevelopment.com/" rel="alternate" type="text/html" /><updated>2025-08-04T06:59:12+00:00</updated><id>https://chocolatedrivendevelopment.com/feed/by_tag/code.xml</id><title type="html">Chocolate Driven Development</title><subtitle>The blog Chocolate Driven Development contains things to help in making your software creation better for the business, as well as for the developers.</subtitle><entry><title type="html">Dependency graphs as a design tool</title><link href="https://chocolatedrivendevelopment.com/2024/02/13/dependency-graphs/" rel="alternate" type="text/html" title="Dependency graphs as a design tool" /><published>2024-02-13T00:00:00+00:00</published><updated>2024-02-13T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2024/02/13/dependency-graphs</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2024/02/13/dependency-graphs/"><![CDATA[<p>In languages without automatic memory management,
you need to keep track of the references to memory you allocate.
One way to model that is a graph with no circular paths. 
It becomes a kind of ownership system for the code structures.
That will also show in what files you need to import for your code.
(You should be able to (manually) sort your files,
so that the imports in each file are only of files that come before it.)
That will then also be a guide of who gets to talk to whom.</p>

<p><a href="https://en.wikipedia.org/wiki/Law_of_Demeter">Law of Demeter</a>, 
“don’t talk to strangers”, is also easier to remember, 
in a language that forces you to null-check a lot.
It is riskier to talk to your neighbours neighbours if they might have been deallocated.
Following the Law of Demeter aims at loosely coupled architecture,
and code that is easier to change.
Loosely coupled architecture can also be viewed as deliberately coupled architecture. 
To craft those relationship graphs we can reuse the methods for managing memory.</p>

<p>It is good that not all languages require you to allocate memory by hand.
The skills required to design a system that does not leak memory,
might have other usages though. 
Try that the next time you find yourself in a codebase where access to objects 
are expected to work from all over the place.
Code where changing one signature ripples through the entire system.</p>

<p>Questions to ask:</p>
<ul>
  <li>If one object had to both create and destroy this object, who would do that?</li>
  <li>What objects depend on this object existing?</li>
  <li>What objects does this object depend on, that others also need?</li>
</ul>

<p>Keeping a tidy object graph helps with memory management,
but also with separating concerns and easy to change code.</p>

<h3 id="bonus">BONUS:</h3>
<p>Interfaces can be used to avoid import loops in patterns like observer-observable.
And it also creates an abstraction layer for the design (if done properly).</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="code" /><category term="quality" /><summary type="html"><![CDATA[How is Law of Demeter related to reference counting? It manages how parts of a software system is connected. Few languages today manage memory manually. But we can still use the same ways of thinking, to support a loosely coupled architecture.]]></summary></entry><entry><title type="html">TDD in the context of writing code to be read</title><link href="https://chocolatedrivendevelopment.com/2024/01/18/tdd-as-a-code-reading-tool/" rel="alternate" type="text/html" title="TDD in the context of writing code to be read" /><published>2024-01-18T00:00:00+00:00</published><updated>2024-01-18T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2024/01/18/tdd-as-a-code-reading-tool</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2024/01/18/tdd-as-a-code-reading-tool/"><![CDATA[<p>In their <a href="https://www.ai.lu.se/2023-12-20">work on code reviews</a> Lo Heander identifies two opposite forces.
We need <strong>understanding</strong>, seeing the code as a part of the system,
and that requires a lot of context.
But we also need <strong>clarity</strong>, 
being able to separate the part of the code that is under review,
and that is better done with less context.</p>

<p>Unit tests define the collaborators and the purpose of a piece of code.
When reading code with unit tests, we can read the tests first,
and focus on how the unit interacts with the system.
The review of the computational code, 
like the body of a function, can then focus on the implementation.</p>

<p>Putting this in the framework created by Heander,
we solve the conflict between clarity and understanding by separation of concerns.
Each test provides context for purpose and interaction for that unit.
At that time we are not interested in the implementation, just the interfaces, 
and can remove that part of the cognitive noise.
When we have enough understanding of the purpose of the code we can move 
to the implementation. 
That should then be a pretty small unit, with well defined collaborators, 
that we are already familiar with from the test.
We have the external context in place and can focus on implementation details.</p>

<p>Separating concerns like that lightens the cognitive load,
and might be a part of solving the conflict between clarity and understanding.</p>

<p>Test driving you code in small units,
does not only help with cognitive load in the moment,
but also helps everyone that will read that piece of code in the future.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="quality" /><category term="agile" /><category term="code" /><summary type="html"><![CDATA[Unit tests define the collaborators and the purpose of a piece of code. When reading code with unit tests, we can read the tests first, and focus on how the unit interacts with the system. Then reading the computational code is only about the implementation of that unit. Separating concerns like that lightens the cognitive load.]]></summary></entry><entry><title type="html">Publish first, review later</title><link href="https://chocolatedrivendevelopment.com/2023/11/23/review/" rel="alternate" type="text/html" title="Publish first, review later" /><published>2023-11-23T00:00:00+00:00</published><updated>2024-02-16T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2023/11/23/review</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2023/11/23/review/"><![CDATA[<p>Code that is waiting for review is useless to the customer.
It also risks growing old, or blocking other work that needs to be done. 
On top of that, it is demotivating for developers to see their code collect dust.</p>

<p>If the code is created by an open source community,
or something else that is done outside of the ordinary work,
things are different.
For a team working with the code in a professional setting,
asynchronous code reviews should be something to avoid.</p>

<h2 id="the-purpose-of-a-code-review">The purpose of a code review</h2>

<p>A traditional code review has two major purposes. 
The first is to make sure that the code behave as intended.
There are alternative ways to achieve this.
You can work in pairs or an ensemble. 
A test first approach, with a good knowledge in test coverage design,
might also help with this.</p>

<p>The second purpose is to maintain code quality over time. 
This is impossible for a team that lack refactoring skills,
regardless of how well code is reviewed.
Perhaps it works for a product in an environment that never changes,
but then code quality will also be less important.
So the team will need to know how to change production code in a safe and effective way.
With that knowledge, you can review code that is important, instead of code that is new.</p>

<p>The important code is the areas in the production code where a lot of changes happen.
You can then, as a team, look at the code and find ways to change it, so that it is easier to work with.
That will improve the software design skills of the entire team.</p>

<h2 id="ease-them-out">Ease them out</h2>
<p>To become a high achieving software team you will need the same skills that make 
asynchronous code reviews unnecessary.
So try to ease them out if you can.
If you don’t feel safe to let code go into production without a review step,
make sure to only focus on functionality (or what regulations demand).
Have a linter in place that checks things like formatting as a pre-commit hook. 
If the code quality is so low that it hurts to put the code in production,
that developer should not work alone. 
It is harder to teach software skills through a written review than in person.</p>

<p>Save the review energy for the high stake parts of the system, 
and go through it as a team.
Then you make sure that the knowledge from the entire team is used,
and shared, 
and that everyone is onboard with the results.</p>

<p>When the code never has to wait for <em>someone else</em> to get into production, 
then you can create value really fast.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="code" /><category term="agile" /><category term="devops" /><summary type="html"><![CDATA[Code needs something to make sure it works as intended. Using asynchronous code reviews for that will slow the team down. Reviewing code as a group is a good tool for knowledge sharing, but do it on production code.]]></summary></entry><entry><title type="html">Wunderbaum testing</title><link href="https://chocolatedrivendevelopment.com/2023/11/23/wunderbaum/" rel="alternate" type="text/html" title="Wunderbaum testing" /><published>2023-11-23T00:00:00+00:00</published><updated>2024-02-16T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2023/11/23/wunderbaum</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2023/11/23/wunderbaum/"><![CDATA[<p>Good unit tests help you design code that is easy to use.
They do that by being a little tedious to write.
Remember, <a href="/2022/10/30/playground/">the test is where the code learns to play nice with others.</a></p>

<p>So if the code under test requires a lot of magic to be verified, 
it will not be straightforward to use in the codebase.</p>

<blockquote>
  <p>A rule of thumb is to favour testing frameworks that are so simple that 
you could easily just have written the code yourself. 
A testing framework is a convenience. 
It should not make it possible to test things that you could not test before.</p>
</blockquote>

<p>When you need to construct the test data, 
write your test doubles and create every other dependency needed, 
pure laziness will create code that is modular and easy for others to use.
This is the <em>design pressure</em> from the tests.</p>

<p><a href="/2022/11/04/upside-down/">If you let a framework entangle your code, unit testing gets hard really fast.</a>
A Wunderbaum testing framework will mock and stub your controllers and databases,
instead of helping you keep the domain logic separate and testable.
It removes the design pressure, one of the reasons to write tests first.</p>

<p>Sometimes you end up with a codebase that needs to get under test before it can be fixed.
Often that can be done through approval testing or end-to-end testing,
just to have some sense of safety.
In that process you might also find Wunderbaum testing frameworks helpful, 
since the code stinks so much you need all the perfume you can get.</p>

<p>But when the code just has some odour, try to avoid things that hide the smell.
If your code is hard to test with a slim testing framework,
you probably have code that is too interdependent, or not modular enough.</p>

<p>Keep your code nose fresh and think of design pressure as a friend.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="quality" /><category term="code" /><category term="agile" /><summary type="html"><![CDATA[Some testing frameworks are so powerful that they take away all the design pressure. They have a place in a codebase that stinks so much you can't work in it without some perfume. In all other cases they disturb your nose for well designed code.]]></summary></entry><entry><title type="html">The question trick</title><link href="https://chocolatedrivendevelopment.com/2023/11/16/question-trick/" rel="alternate" type="text/html" title="The question trick" /><published>2023-11-16T00:00:00+00:00</published><updated>2023-11-16T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2023/11/16/question-trick</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2023/11/16/question-trick/"><![CDATA[<p>When giving feedback on complex material and finding something unexpected,
there are almost always two alternative explanations.</p>

<p>The one to first come to mind is often <em>This is wrong!</em>.
The other one, easy to miss, is a parallel path of 
<em>I am missing important information</em>.</p>

<p>Before I know what the case is, 
I try to act as if the cat is both dead and alive at the same time.
Both options are true and false.
It keeps the door open for different scenarios, 
and have respect for the competence in the person receiving feedback.</p>

<p>Take a code review as an example, 
where I encounter some asynchronicity.
that looks like it would cause a race condition.</p>

<p>Lets look at the alternative conversations.</p>

<ol>
  <li><strong>I am correct and don’t ask questions</strong>
    <blockquote>
      <p>- <em>Race condition, fix it!</em>.</p>

      <p>- <em>Oh, thank you for spotting. I knew I had to fix it, but forgot.</em></p>
    </blockquote>
  </li>
  <li><strong>I am correct and phrase it as a question</strong>
    <blockquote>
      <p>- <em>This looks like something that could cause a race condition.
Or is there anything I am missing?</em></p>

      <p>- <em>Oh, thank you for spotting. I knew I had to fix it, but forgot.</em></p>
    </blockquote>
  </li>
  <li><strong>I am wrong and don’t ask questions</strong>
    <blockquote>
      <p>- <em>Race condition, fix it!</em>.</p>

      <p>- <em>This part of the data is immutable now.
You must have worked with the other team the week we changed that.
Good I got to tell you!</em></p>
    </blockquote>
  </li>
  <li><strong>I am wrong and phrase it as a question</strong>
    <blockquote>
      <p>- <em>This looks like something that could cause a race condition. 
 Or is there anything I am missing?</em></p>

      <p>- <em>This part of the data is immutable now.
You must have worked with the other team the week we changed that.
Good I got to tell you!</em></p>
    </blockquote>
  </li>
</ol>

<p>The tone shifts a lot depending on how the first sentence is phrased.
And the difference is clearest when the reviewer is wrong.</p>

<p>There is a risk of not sounding sincere in the question, 
then it won’t work. 
People who are underestimated might seem ignorant rather than humble.
That has to be taken into account.</p>

<p>The next time you give feedback, 
phrase it so that the conversation can flow also when you are wrong.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="empathy" /><category term="quality" /><category term="code" /><summary type="html"><![CDATA[Use questions when delivering constructive criticism on something complex. Questions leave room for the possibility that you are wrong.]]></summary></entry><entry><title type="html">The dynamite double</title><link href="https://chocolatedrivendevelopment.com/2023/09/27/dynamite-double/" rel="alternate" type="text/html" title="The dynamite double" /><published>2023-09-27T00:00:00+00:00</published><updated>2023-09-27T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2023/09/27/dynamite-double</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2023/09/27/dynamite-double/"><![CDATA[<p>Side effects should be isolated, kept in code that is separate from domain 
logic, and have no conditionals in them. 
They are the adapters in the “ports and adapters”-pattern.</p>

<p>To test code interacting with the ports, we need test doubles to use as the adapters.</p>

<p>As an example we have pseudo code for a system that sometimes start a siren.
The code actually starting the siren is wrapped in a simple class 
implementing the port-protocol <code class="language-plaintext highlighter-rouge">Siren</code>.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>protocol Siren {
    void turnOn()
}
</code></pre></div></div>
<p>The code starting the siren gets it as a parameter,
together with the boolean <code class="language-plaintext highlighter-rouge">emergency</code>.</p>

<p>I really don’t want the siren to go off when there is not 
an emergency.</p>

<p>So to make sure that the function does not even try to start the siren,
we use a Dynamite Double. 
It is a test double that fails the test if the code tries to call its functions.
Touch it and it explodes.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>class DynamiteDoubleSiren implements Siren {

    void turnOn(){
        make.test.fail.horribly
    }
}
</code></pre></div></div>

<p>Instead of using a test double that records if,
and how, it has been called,
I feel safer if the “no action”-alternative is tested with 
a dynamite double.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="quality" /><category term="code" /><summary type="html"><![CDATA[When you want your test to make sure that the code does not even try to call a collaborator with side effects, use a dynamite double, that explodes when touched.]]></summary></entry><entry><title type="html">Workshop data types</title><link href="https://chocolatedrivendevelopment.com/2023/09/26/retro-interface/" rel="alternate" type="text/html" title="Workshop data types" /><published>2023-09-26T00:00:00+00:00</published><updated>2024-02-16T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2023/09/26/retro-interface</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2023/09/26/retro-interface/"><![CDATA[<blockquote>
  <p>TLDR;
One way to construct a workshop
is to think of it as a series of data transformations.<br />
Each step has to filter or transform the input in a way that it matches the
input of the next exercise, until we have reached the requested result.
This helps in controlling the format, and quality, of the results,
without controlling its content.</p>

  <p>The last part of this text contains an example featuring a retrospective.
Below that, the post ends in flowchart illustrations.</p>
</blockquote>

<p>Planning a workshop or a retrospective is a lot like software architecture.</p>

<p>Most software is about collecting, transforming and presenting data.
To help us mentally model data we have type systems.
A lot of languages have types, otherwise they are there, just implicit. 
We can introduce the same tools when designing a workshop.
That perspective can bring value even to experienced facilitators.
We never want to control the content of the output,
but we want to be able to control its format, i.e. the data type.</p>

<h3 id="basic-structure">Basic structure</h3>
<p>In <a href="/references/retrospectives.html">Agile retrospectives</a> the five parts 
of a retro is suggested to be <em>set the stage</em>, <em>gather data</em>, <em>generate insights</em>,
<em>decide what to do</em> and <em>close the retrospective</em>. 
If you plan another workshop you can use the same steps or define your own structure.
Start with considering what data needs to flow between each step.</p>

<h3 id="plan-each-step">Plan each step</h3>
<p>Now we find exercises that fit the input and the output of each step.
Sometimes one exercise is not enough to go from the input to the output of 
each part. 
Then we need to find two exercises,
where the second one transform the output of the first
to the output of the entire block.</p>

<p>Often it is a pair of one exercise that create more data,
and another that filter it down again. 
If you have plenty of time you can chain more exercises together the same way.</p>

<h2 id="practical-advice">Practical advice</h2>
<h3 id="artifacts">Artifacts</h3>
<p>Plan for the artifacts carrying the data between each step.
It can be sticky notes that move from one board to another,
or text that is copied from a digital board to a text chat for a breakout room.
Focus on how they connect the exercises.</p>

<h3 id="level-of-detail">Level of detail</h3>
<p>You can direct the workshop by being more or less specific in your types.
The amount of items moving from one exercise to another can be fixed,
or flexible, depending on what comes up.
If you filter things down to one item you get focus.
If you allow the team to choose more than one there is more work in making sure to get a result in the end.
The output “something that blocks me in my work” is wider than “something
that make me code slower”.
That way you can give the entire workshop a direction.</p>

<h3 id="cut-it-short">Cut it short</h3>
<p>You can also use this to cut parts of a workshop if you are short on time.
Have alternative, faster, ways to go from one state in the data to another,
if you have to.</p>

<h2 id="an-example-retrospective">An example retrospective</h2>
<p>The rest of this post is a concrete example using a sample retrospective as illustration.
Explaining each exercise is out of scope of this text, they are just placeholders.
The types of data going between the exercises are also part of the example.
A lot of retrospectives will have similar data types, but they don’t have to.</p>

<h3 id="set-the-stage">Set the stage</h3>
<p>This <em>setting the stage</em> is a part of a regular retrospective
with an established team.
So the input data can be transformed into 
the output with a <em>round robin</em> of a simple question like
“What did you have for breakfast?”. 
If it is <em>setting the stage</em> for a retrospective regarding a gigantic delivery that crashed horribly,
or for the first retrospective for a newly formed team,
you might need multiple exercises.</p>

<h3 id="gather-data">Gather data</h3>
<p>For our <em>gather data</em>-step we add two exercises.
The first step is the <em>Sailboat exercise</em> that outputs things that drive the team,
and things that hinders it.
The hindering part is input into another exercise that sort things by impact on the team,
and how much influence the team has over it.
Our “high impact - high influence”-quadrant become input to <em>generate insights</em>.</p>

<p>Data that goes from the first to the second exercise could be:</p>
<ul>
  <li>Not enough chocolate</li>
  <li>Road outside is loud</li>
  <li>Code is messy</li>
  <li>It is winter</li>
  <li>Ugly plants</li>
  <li>stand-up boring</li>
</ul>

<p>The team places the <em>boring stand-up</em> in the top right corner, 
so that it is the input for the next step.
(The messy code had high impact, but felt a bit out of their control at the time.)</p>

<h3 id="generate-insight">Generate insight</h3>
<p>Here we want to take circumstances that impede the team, that they also have impact over, 
and turn that into something concrete that can be countered.</p>

<p>A middle step of deeper understanding for the things can help. 
The <em>5 why</em>-exercise take circumstances and try to explain them.
That can then be input to a <em>force field analysis</em> to find what drives,
and what prevents that thing.</p>

<p>The <em>5 why</em> find that the boring stand-up is caused by people always saying the same things.</p>

<p>The force field analysis shows that the boring stand-ups are worse when:</p>
<ul>
  <li>the development is moving too slow</li>
  <li>people being too general in their descriptions of their work</li>
  <li>people not helping each other when stuck</li>
</ul>

<p>Factors that make stand-ups feel more valuable are:</p>
<ul>
  <li>smaller sizes of tasks</li>
  <li>they end up in conversations afterward</li>
</ul>

<h3 id="decide-what-to-do">Decide what to do</h3>
<p>When deciding what to do we need suggestions and than filter them down.
So the first activity, <em>1,2,4,all</em>, generate suggestions,
and <em>vote with dots</em> then pick the best to try.</p>

<p>The team generates suggestions:</p>
<ol>
  <li>Not do stand-ups.</li>
  <li>Try to aim for half day sizes for all tasks.</li>
  <li>Always have a voluntary “problem solving”-meeting after the stand-up.</li>
  <li>Have stand-ups twice a day.</li>
  <li>Not be allowed to say the same thing today as you said yesterday.</li>
  <li>Always do pair programming.</li>
</ol>

<p>Voting with dots had a tie between 3, 5 and 6. 
The team decided to merge them and the experiment to run was:
“If someone work on the same thing for more than a day,
they either have to get help in a separate meeting afterwards, 
or pair-program until the task is done.”</p>

<h3 id="close-the-retrospective">Close the retrospective</h3>
<p>In this step we offload things that the team experienced during the retro,
to return them to the rest of the day with closed loops.
We also gather feedback for the next retro.
<em>Liked, learned, lacked and longed for</em> is an exercise that do that.</p>

<h2 id="illustrations">Illustrations</h2>
<p>This is the overview of the retrospective.
<img src="/assets/images/retro1.svg" alt="A flowchart showing the five steps and dataflow" title="A sample retrospective" /></p>

<p>And this is the same, but with the exercises included.
<img src="/assets/images/retro.svg" alt="A flowchart including the inner activities." title="A sample retrospective" /></p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="retros" /><category term="code" /><summary type="html"><![CDATA[One way to construct a workshop is to think of it as a series of data transformations. Each step has to filter or transform the input in a way that it matches the input of the next exercise, until we have reached the requested result. This helps in controlling the format, and quality, of the results, without controlling its content.]]></summary></entry><entry><title type="html">Defining domain boundaries</title><link href="https://chocolatedrivendevelopment.com/2023/09/25/definition/" rel="alternate" type="text/html" title="Defining domain boundaries" /><published>2023-09-25T00:00:00+00:00</published><updated>2023-09-25T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2023/09/25/definition</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2023/09/25/definition/"><![CDATA[<p>In mathematics the <em>domain</em> is the input values 
that a function can map to the <em>codomain</em> of output values.
Both the <em>domain</em> and the <em>codomain</em> are part of the functions definition.</p>

<p>Software development is not always as strict, but the mathematical mindset can 
help us in writing predictable code.</p>

<p>In Test Driven Development (TDD) we let the tests and the code grow together, 
creating one failing test at the time and making it pass.</p>

<p>Deliberately deciding what input values are valid for a function is a part of TDD.
We then also define the behaviour if the function can be used outside of its definition.
(In some languages this is done through the definition of signatures and types.)</p>

<p>TDD is a thinking tool more than a way to write test.</p>

<p>Let it help you define your domain and its boundaries.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="code" /><category term="quality" /><summary type="html"><![CDATA[In mathematics the definition of a function contains the set of valid input values, the domain. Test Driven Development can help us adapt that mindset and implement the boundaries of our domain in code.]]></summary></entry><entry><title type="html">The point of estimates</title><link href="https://chocolatedrivendevelopment.com/2023/09/19/size/" rel="alternate" type="text/html" title="The point of estimates" /><published>2023-09-19T00:00:00+00:00</published><updated>2023-09-19T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2023/09/19/size</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2023/09/19/size/"><![CDATA[<p>Imagine you have a jar full of beads. 
Your job is to guess (estimate) how many beads there are,
so you ask your team of bead experts.
They hand the jar around and give widely different estimates.
In the discussion that unfolds you learn about the density of different bead materials,
the distribution of sizes in different bead mixes and the sound beads make in a jar.</p>

<p>When you open the jar you will know much more of what to expect than just the amount of beads,
but “how many beads?” was the only question needed to start the conversation.</p>

<p>Estimates in software is not about scheduling tasks or defining velocity.
“How big is this task?” is a shortcut to a discussion on scope, 
technical limitations and prerequisites.</p>

<p>We need to understand our options when prioritizing.
The scope might be interpreted in different ways.
Members of the team have relevant knowledge unique to them that 
changes the understanding of work required.
All of this will show in an estimate of size.</p>

<p>Instead of taking all the beads out of the jar to sort them,
we just ask how many they are.
Then we keep the information it generates and throw out the estimate.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="agile" /><category term="product" /><category term="code" /><summary type="html"><![CDATA[Estimation is a place for quick assessments that everyone agree on the scope. It is also a way to discover technical knowledge that needs to be shared in the team.]]></summary></entry><entry><title type="html">Three reasons to get a Samman coach</title><link href="https://chocolatedrivendevelopment.com/2023/08/30/learning-on-the-job/" rel="alternate" type="text/html" title="Three reasons to get a Samman coach" /><published>2023-08-30T00:00:00+00:00</published><updated>2023-08-30T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2023/08/30/learning-on-the-job</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2023/08/30/learning-on-the-job/"><![CDATA[<p>Writing software is knowledge work. 
The quality of the codebase, infrastructure and team interactions affects both the profit 
and the well-being of the team. 
My favourite way to share knowledge is called Samman Technical Coaching.
<a href="https://sammancoaching.org">It is described more in detail on this website</a>
and <a href="/references/samman.html">in the book by Emily Bache</a>. 
It can be used to improve both code quality,
infrastructure (as code) and team interactions.</p>

<p>In short Samman coaching consists of two parts, a learning hour and working in an ensemble. 
The learning hour is interactive and tailored to the needs of each team.
It is a way to explore new skills and concepts in a safe and well prepared setting.</p>

<p>The ensemble working is done in production code and is coach facilitated.
<a href="/posts/#ensemble">I have several posts on working in ensemble and its benefits</a></p>

<p>I claim that this is far more powerful than it initially seems,
at least when done right.
I want to compare it to regular courses,
since I think they are the closest alternative.</p>

<h3 id="with-your-people">With your people</h3>
<p>Samman technical coaching is done with your team.
No more returning from a course and trying to convince the others of the value in what you learned.
It is also adjusted to the knowledge level of your team and 
facilitates learning and teaching within the team.
Samman technical coaching provides new knowledge, a learning culture
and tools for learning together.</p>

<h3 id="where-you-know-the-domain">Where you know the domain</h3>
<p>Learning how to deal with complex problems is hard. 
You need a complex problem to solve, 
understand that complex problem and still have cognitive capacity left 
to learn a new tool or method to solve it.
When working with problems found in your production code,
you already understand the domain. 
That leaves more room for learning the tools, without having to use an 
unrealistic and limited problem.
(The coach needs to know the material well enough to teach it in any codebase.)
This brings more confidence in the tools and skills, 
since the team can see that they can be applied in their reality.
(If the tools do not work in the current production code
the coach will have to adapt the plan for the learning hours.
That feedback is not possible with traditional courses.)</p>

<h3 id="solving-your-problems">Solving your problems</h3>

<blockquote>
  <p>Happy families are all alike; every unhappy family is unhappy in its own way.</p>

  <p>– <cite>Leo Tolstoy in Anna Karenina</cite></p>
</blockquote>

<p>The goal is code that is dependable and easy to change.
How to get there is different for each team.
As a Samman technical coach you listen to the team and read their code.
The goal is to provide as much value as possible in a digestible way. 
All topics are presented one hour at the time,
often in small steps.
That way new concepts have a chance to get repeated and to stick.
As it is directly tried in the production code 
(it does not have to be producing value, but it can)
the team can try things out at their own pace.
This creates an offer of knowledge that can then be pulled into everyday use.
Change is best done without fear.
Samman coaching provides the specific tools that your team needs for change, 
but in a way that is safe and fun.</p>

<h3 id="conclusion">Conclusion</h3>
<p>Samman technical coaching brings the team together.
By using familiar production code it can teach more complex topics.
As the content is tailored to the needs of the team, 
and proven useful to them in their codebase,
it sticks and provides value in the everyday work for a long time.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="ensemble" /><category term="agile" /><category term="code" /><summary type="html"><![CDATA[Samman technical coaching improves learning by applying the knowledge in a familiar environment as a team. Everyone learns together and can validate the new skills where they will be applied.]]></summary></entry><entry><title type="html">The value of quality</title><link href="https://chocolatedrivendevelopment.com/2023/08/03/the-value-of-quality/" rel="alternate" type="text/html" title="The value of quality" /><published>2023-08-03T00:00:00+00:00</published><updated>2023-08-03T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2023/08/03/the-value-of-quality</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2023/08/03/the-value-of-quality/"><![CDATA[<p>This text is a reaction to this micro blog post:</p>

<blockquote>
  <p>early-career people should take the time to download and look at the leaked farcry code.
not to learn some new technical lessons,
but to disabuse themselves of the notion of “clean code”. 
<a href="https://twitter.com/nice_byte/status/1675621641131556864?s=61&amp;t=Mchgzl3goM1KCJAvA_p9oQ">nicebyte</a></p>
</blockquote>

<p>From reading more of the thread, my interpretation is:
“You don’t need good programming practises to make money from software.”
That might be true, in some circumstances, but to make it an “early-career”-advice I would like to add some
perspective.</p>

<p>First I want to separate internal and external software quality,
<a href="/2023/08/01/external-internal-quality/">as described in this post</a>.
Internal quality is from a developer perspective,
external quality is what the user sees.
They can be more or less dependent of each other, but have different effects.</p>

<p>J.B. Rainsberger has a talk on “The economics of software design” (<a href="https://youtu.be/TQ9rng6YFeY?t=735">video</a>).
There he introduces t0, the point in time where the total cost of having written the code is the same
regardless of if we just did it fast and sloppy or slower and intentionally sustainable.
We don’t know when t0 will be, but it exists for every project.
After t0 you reap the profit from having continuously improved the code since the start.
In just implementing features as fast as possible,
we bet against the project surviving past t0.
We only save money by not caring about “clean code” if the project does not reach t0.
The t0 measure is about the value of internal quality.</p>

<p>It is interesting to use a game as an example for when internal quality is unnecessary.
Games are one of the few kinds of software still distributed on physical media.
I believe that a lot of games change less over time then other software.
The cost of a messy codebase come when we want to edit it.
Bugfixes in a feature complete codebase can be plastered on,
as long as the code do not move.</p>

<p>In my <a href="/2023/07/27/useworthiness/">post on useworthiness</a>
I talk about how utility and usability mix to decide if software is worth using. 
If we can not add new features utility will suffer. 
Usability will be a problem if the internal quality problems show as 
external quality problems, or slow down improvements in user experience over all.</p>

<p>For games that change more over time, like Pokémon Go,
the condition of the codebase matters, and will start to show.
<a href="https://www.eurogamer.net/pokemon-go-developer-commits-to-improving-games-quality-after-recent-remote-raid-shiny-snafu?fbclid=IwAR26nV1LOSzsa7lygePIacsFofsfagyYKJlCEUHHfFf4fbTrSB2uPHjq57A"> Niantic has publicly stated that they have quality problems</a>.
In Pokémon Go the problems shows as defects, delayed features and draining of the users resources such as mobile data and battery.
All of that results in lower external quality.</p>

<p>The gamble here is both with t0, “will the project die before the codebase does?”, 
and with the users tolerance for unreliability, in relationship to how the game makes money.</p>

<p>Pokemon Go makes <a href="https://mobilegamer.biz/mays-top-grossing-mobile-games-worldwide/">money</a>, 
but Niantic has still recently <a href="https://variety.com/2023/digital/news/niantic-layoffs-pokemon-go-shutting-down-games-1235658759/">laid off 25% of its workforce</a>.</p>

<p>This is why my “early-career” advice is:</p>
<blockquote>
  <p>Find work where they care about code quality.</p>
</blockquote>

<p>It will be better for your mental health as well, but that is for another post.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="quality" /><category term="code" /><category term="product" /><summary type="html"><![CDATA[Is "clean code" important for successful software development? It depends on the life expectancy of the software, if it needs to follow changes in the business and how well the user reacts to defects.]]></summary></entry><entry><title type="html">Internal or external quality?</title><link href="https://chocolatedrivendevelopment.com/2023/08/01/external-internal-quality/" rel="alternate" type="text/html" title="Internal or external quality?" /><published>2023-08-01T00:00:00+00:00</published><updated>2023-08-01T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2023/08/01/external-internal-quality</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2023/08/01/external-internal-quality/"><![CDATA[<p>When talking about software quality we should separate internal and external
quality.
What is the user experience and what is the developer experience?</p>

<p>Internal quality is a codebase where the functionality is easy to change without
unexpected side effects.</p>

<p>External quality is software that behave as expected by the user, 
demanding as little effort as possible.</p>

<p>Sometimes the two are related.
Code forced into new purposes without prior refactoring might behave clunky or erratic.</p>

<p>A lack in internal quality can still be prevented from showing to the user. 
This is where we do endless manual testing, extensive monitoring in operations or add
a lot of extra computational resources.</p>

<p>On the other hand, software with high internal quality might still have poor external quality.
If the behaviour of the application is hard for the user to navigate and predict,
it will still not be perceived as working correctly.</p>

<p>If the software has internal quality it is easier to change.
This makes it easier to do user research and update its behaviour,
so that it works well for the user.</p>

<p>Internal quality makes it easy to write software that do what we expect.
External quality is software that does what the end users expect.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="quality" /><category term="agile" /><category term="code" /><summary type="html"><![CDATA[When talking about software quality we should separate internal and external quality. Internal quality makes it easy to write software that do what we expect. External quality is software that does what the end users expect.]]></summary></entry><entry><title type="html">Useworthiness</title><link href="https://chocolatedrivendevelopment.com/2023/07/27/useworthiness/" rel="alternate" type="text/html" title="Useworthiness" /><published>2023-07-27T00:00:00+00:00</published><updated>2023-07-27T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2023/07/27/useworthiness</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2023/07/27/useworthiness/"><![CDATA[<p>A product that only improves my life marginally has to be really good 
for me to keep using it.</p>

<p>On the other hand, a badly designed, or even unstable, product that provides
something really valuable, will be used anyway.
(That is, until something better is available, or the pain grows too big.)</p>

<p>Useworthiness is the combination of usability and utility.
How well it works is weighted with how valuable the function is.
Both impact how the user interacts with your product.</p>

<p>Compare it with food.
That something is easy to eat and that it is tasty is two
different things. 
Eating canned corn with a spoon is really easy.
Despite that, I prefer to eat it fresh on the cob, 
including the flossing required afterwards.</p>

<p>If you work with software that provides something really useful,
people might be using it <em>despite</em> its level of quality.</p>

<p>If it is something that the user has to do,
participation data is even less valuable to decide the quality of your product.</p>

<p>Get feedback from you user, besides recorded data,
to separate the usability from the utility and retain customers over time.</p>

<p>If you take pride in producing quality user experience and product stability,
make sure you work with something valuable to people, so that it is not wasted.</p>

<p>User research is the best way to get useworthy products.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="product" /><category term="quality" /><category term="code" /><summary type="html"><![CDATA[Useworthiness is the combination of usability and utility. How well it works is weighted with how valuable the function is. Both impact how the user interacts with software.]]></summary></entry><entry><title type="html">DevOps vs. FullStack</title><link href="https://chocolatedrivendevelopment.com/2023/07/26/devopsfullstack/" rel="alternate" type="text/html" title="DevOps vs. FullStack" /><published>2023-07-26T00:00:00+00:00</published><updated>2023-07-26T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2023/07/26/devopsfullstack</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2023/07/26/devopsfullstack/"><![CDATA[<p>DevOps and FullStack are orthogonal concepts. 
They express information along two different axis, independent of each other.</p>

<p>FullStack is about what kind of software you are comfortable writing. 
Where the stack starts and ends depend on who you are asking. 
It includes at least two layers of software.</p>

<p>DevOps is about what parts of the software lifecycle you are comfortable with.
The requirement is that you see it through at least until it brings value to the end user.</p>

<p>You can be a mobile app developer and do DevOps,
as long as your responsibility includes the distribution of the app,
and that is all that is required for it to reach the user.</p>

<p>You can be fullstack and not do DevOps,
if you let go of the code as soon as your feature is implemented.</p>

<p>If you, and your team, are responsible for development and operations,
that is DevOps.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="devops" /><category term="agile" /><category term="code" /><summary type="html"><![CDATA[DevOps and FullStack are orthogonal concepts. One is about technology and the other is about the software lifecycle.]]></summary></entry><entry><title type="html">What is tugging at your team?</title><link href="https://chocolatedrivendevelopment.com/2023/07/24/tug-of-war/" rel="alternate" type="text/html" title="What is tugging at your team?" /><published>2023-07-24T00:00:00+00:00</published><updated>2024-02-16T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2023/07/24/tug-of-war</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2023/07/24/tug-of-war/"><![CDATA[<p>External dependencies cause:</p>
<blockquote>
  <ol>
    <li>Communication overhead</li>
    <li>Risk of conflicting interests</li>
    <li>Temporal dependencies and scheduling problems</li>
  </ol>
</blockquote>

<p>(Interruptions from auditing, or bugs found by external quality assurance,
is a version of temporal dependencies.)</p>

<p>This consumes resources that could’ve created value.</p>

<p>As soon as the software organization grows enough for the developers to split into more than one team,
the dependencies will change.
In the worst case both teams depend on everything the old team depended on, 
and each other. 
Managing dependencies more important in bigger companies (due to math).
<a href="https://tidyfirst.substack.com/p/scaling-extreme-programming-dependencies">Kent Beck has a great text on what you can do to deal with dependencies from within an
existing team</a>.
The suggestions below require more influence over the organization.
The goal is to create working software with as few dependencies as possible for each team,
while maintaining a reasonable team size.
The book <a href="/references/team-topologies.html">Team Topologies</a>
covers much more on how to organize teams, so I include their names for different teams along my own.</p>

<h2 id="including-the-stakeholder-in-the-team">Including the stakeholder in the team</h2>
<p>This is done in DevOps. 
When running the code is included in the responsibilities for the team,
operations is no longer a stakeholder.
The same can be done with product, security and user experience.
This is one of the reasons to have the customer be part of the team in XP.
A cross functional team gathers all expertise in one place.
The main focus is solving the business problem as well as possible.
This improves all three listed problems with dependencies,
since collaboration is moved to within the team.</p>

<h2 id="intent-centered-software-teams--slicing-teams-along-intent">Intent centered software teams — slicing teams along intent</h2>
<p>Organize teams around their goal (user path or feature) instead of what technology they use.
This also requires cross functional teams.
It is easier for the code to adhere to the single responsibility principle 
when the team has only one goal.
In Team Topologies the “Stream aligned team” is clearly intent centered.
“Subsystem teams” and “platform teams” can also fit the description,
if the other teams are seen as their customers. 
Solving the scheduling aspect of the dependencies relies on that the stream aligned teams can move forward independently of the subsystem and
platform teams.
(Platform teams are very different from a backend team,
that still has to implement changes for each feature in the frontend.)</p>

<p>One way to see it is that the business logic is created by stream aligned teams. 
The technical advantage can be created as a subsystem or platform,
used to improve the work of other teams as it gets available.</p>

<h2 id="service-teams--from-push-to-pull">Service teams — from push to pull</h2>
<p>If the overhead from having specialists in each team gets too big, 
you can have service teams.
In Team topologies those are “Enabling teams”.
This flips the direction of dependency between teams. 
If the legal team is there to control, it is a stakeholder for the software team.
On the other hand, if the software teams take full responsibility for the
legality of their code, the legal team can be there to serve them.
The legal team then has the software teams as their stakeholder.
It can still create delays, but the control and the responsibility is with the development team.
Legal advice is pulled from the legal team instead of pushed to the development team.
This can be used for other areas as well.
Service teams still have to manage their time, but they should at least not have to explain
why their work is needed. So the conflict in interests is solved.</p>

<h2 id="universal-design--including-diversity-in-the-norm">Universal design — including diversity in the norm</h2>
<p>The core in universal design is to move away from the able bodied user as a norm.
People with disabilities are not a new kind of user, they are a part of the general user.
We design for different screen sizes, without having stories like 
“as an iPad user I want to be able to buy a ticket”.
The same way we can simply make accessibility a part of how we work.
This is easier with a diverse team.
Universal design can also be expanded to include other marginalized groups. 
I don’t think that “as an African American I want to be able to use face recognition” should (need to) be its own story.
It is what we want to achieve that differentiates users,
not the circumstances we are (currently) in.</p>

<h2 id="bonus-cutting-dependencies-within-a-team">Bonus: Cutting dependencies within a team</h2>
<p><a href="/posts/#ensemble">Read my posts on working in an ensemble!</a>
This deals with all the listed problems with dependencies, 
but between individuals within the team.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="agile" /><category term="product" /><category term="code" /><summary type="html"><![CDATA[The software quality suffers when a team, and their code, try to satisfy conflicting needs. Communication overhead, and hard dependencies on work by other teams, make it worse. This is a compilation of some things commonly done to limit this.]]></summary></entry><entry><title type="html">The SOLID principles for organizing work</title><link href="https://chocolatedrivendevelopment.com/2023/07/17/solid-for-people/" rel="alternate" type="text/html" title="The SOLID principles for organizing work" /><published>2023-07-17T00:00:00+00:00</published><updated>2023-07-17T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2023/07/17/solid-for-people</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2023/07/17/solid-for-people/"><![CDATA[<p>Conway’s law states that:</p>
<blockquote>
  <p>Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization’s communication structure.</p>
</blockquote>

<p>We also know from the <a href="https://services.google.com/fh/files/misc/state-of-devops-2019.pdf">DORA DevOps report</a>
that we want loosely coupled code.
The SOLID principles can help us write code that has high cohesion and low coupling. 
I think we can translate those to work for organizations as well, 
and see how we can help the code be flexible through how we work.</p>

<h2 id="the-single-responsibility-principle">The Single-responsibility principle</h2>
<blockquote>
  <p>There should never be more than one reason for a class to change.</p>
</blockquote>

<p>This is really about stakeholders. 
(<a href="/2022/10/04/single-responsibility-salt/">See this blogpost for more on how it works in code.</a>)</p>

<blockquote>
  <p>Aim for as few stakeholders as possible for a team</p>
</blockquote>

<p>The stakeholder can be internal or external.</p>

<p>(I expand on what to do to achieve this in <a href="/2023/07/24/tug-of-war/">another post.</a>)</p>

<h2 id="the-openclosed-principle">The Open–closed principle</h2>
<blockquote>
  <p>Software entities … should be open for extension, but closed for modification.</p>
</blockquote>

<p>We want change to happen where it makes sense and only when needed.
For organizations we get there by team design.</p>
<blockquote>
  <p>Create small, long term, self sufficient teams that collaborate.</p>
</blockquote>

<p>Teams get better with time.</p>

<h2 id="the-liskov-substitution-principle">The Liskov substitution principle</h2>
<blockquote>
  <p>Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.</p>
</blockquote>

<p>How something is solved can change, and you should not have to care about it.
The design of the base class helps us find the purpose of the object from the user perspective.</p>

<blockquote>
  <p>Internal services are internal products</p>
</blockquote>

<p>Create internal services as if they would be sold to external customers.
We want each part of the system to have a clear purpose and each team to have independent pacing of their work.
It also makes it possible to swap it for “off the shelf”-solutions if the service is no longer a part of the competitive edge.
(And let the team take on a new project.)</p>

<h2 id="the-interface-segregation-principle">The Interface segregation principle</h2>
<blockquote>
  <p>Clients should not be forced to depend upon interfaces that they do not use.</p>
</blockquote>

<p>We don’t want code to be weighed down by conforming to rules that does not apply to it.
The same is true for teams.</p>

<blockquote>
  <p>Let each team own their process.</p>
</blockquote>

<p>There can not be one flavour of agile in a big company.
Instead, each team should be provided with the time and expertise to learn how to improve their own work.
Be clear with desired outcomes and core values,
let the team do the rest.</p>

<h2 id="the-dependency-inversion-principle">The Dependency inversion principle</h2>
<blockquote>
  <p>Depend upon abstractions, not concretions.</p>
</blockquote>

<p>This is about integrity.</p>

<blockquote>
  <p>No micro management.</p>
</blockquote>

<p>Give the team one stakeholder and the capabilities they need to fill one purpose for that stakeholder,
then trust them.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="agile" /><category term="code" /><category term="devops" /><summary type="html"><![CDATA[The SOLID principles help us write loosely coupled code. We also know that the structure of the organization is reflected in the resulting code. So how can we translate SOLID to help with a loosely coupled organization?]]></summary></entry><entry><title type="html">The Octopus Theory</title><link href="https://chocolatedrivendevelopment.com/2023/05/02/octopus/" rel="alternate" type="text/html" title="The Octopus Theory" /><published>2023-05-02T00:00:00+00:00</published><updated>2023-05-02T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2023/05/02/octopus</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2023/05/02/octopus/"><![CDATA[<p>Octopuses in captivity have <a href="https://www.neaq.org/blog/octopus-box/">puzzle boxes</a> 
to keep them happy and occupied.
A bored octopus, <a href="https://www.telegraph.co.uk/news/newstopics/howaboutthat/3328480/Otto-the-octopus-wrecks-havoc.html">like the german octopus Otto</a>,
might cause the electricity to short circuit,
throw rocks at the glass, 
juggle hermit crabs or start moving things around in the aquarium.
When lacking stimuli, an octopus might even <a href="https://www.peta.org/features/5-times-octopuses-made-headlines/">die from it</a>.</p>

<p>I believe that software developers are a lot like octopuses.
To thrive, we need problems to solve, or we will create new problems, 
and in some cases, problems for others.</p>

<p>Most software development can be done quite simply today.
We have high level languages, frameworks and libraries for
technical advanced things that used to be done by each team.
Now the work consists of using existing tools to express the domain and adapt them for the product.
Most software today is developed where the programming part does not require you to be very clever.
(In a proper, modern, environment. Unless you are doing something totally new, most are not. I am not even going into AI.)</p>

<p>Implementing a solution, screen by screen, or api-call by api-call, 
that someone else designed, is not enough of a puzzle.</p>

<p>So, what options are there for a developer who loves problems?</p>

<p>My suggestion is that programmers should be a part of product development.
Give software developers business problems to solve, as part of a team.
Then we can safely aim to make our codebase easy to work with, even boring,
because we know that we will never run out of problems to solve.
The cognitive ability will be put to use where it is most needed, 
to solve hard technical problems when they arise,
and to support the business at all time.
And that is only one of the benefits!</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="product" /><category term="agile" /><category term="code" /><summary type="html"><![CDATA[Creatures with an innate need to solve problems, like octopuses and software developers, will look for problems to solve. Invite the development team to be a part of solving the business problems, and provide octopuses in captivity with puzzle boxes.]]></summary></entry><entry><title type="html">Optimize for reading</title><link href="https://chocolatedrivendevelopment.com/2023/04/18/optimized-for-reading/" rel="alternate" type="text/html" title="Optimize for reading" /><published>2023-04-18T00:00:00+00:00</published><updated>2024-02-16T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2023/04/18/optimized-for-reading</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2023/04/18/optimized-for-reading/"><![CDATA[<p>We did not evolve to write software.
In fact, we did not evolve to read and write at all.</p>

<p>Still <a href="https://www.journals.uchicago.edu/doi/10.1086/502806">research shows</a> 
that the shapes constructing glyphs are similar over different alphabets.
So is the frequency of those shapes.
On top of that, the common shapes in our alphabets are also those common in nature.
Patterns we <em>did</em> evolve to recognize.</p>

<p>Neurological <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC1359523/">research on cats</a>
shows how the matching of parts to a whole works when recognizing shapes. 
The process of matching a shape, in different fonts and sizes, to a specific letter,
seems to be build into our brains.
Or, more correctly, our letters have evolved to match how the brain decodes shapes.</p>

<p>An “x” is easy to recognize, but takes three movements to draw by hand.
So the theory is that the cost of forming a letter is seen as less important,
than the cost of recognizing it.
When exploring shorthand and scribbles,
other shapes are found, shapes optimized for our motor function.</p>

<p>Our current alphabets, not only the Latin one, have evolved to be easily decoded.
They have not evolved to be easy to shape.</p>

<p>We have not evolved to create software, 
but we should let software development evolve as our letters have.</p>

<p><strong>Code should always be easier to read than it was to write!</strong></p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="empathy" /><category term="code" /><summary type="html"><![CDATA[The glyphs in the Latin alphabet are based on shapes that we evolved to recognize, not the figures our hands evolved to draw. Code should also always be easier to read than it was to write.]]></summary></entry><entry><title type="html">Test it like it’s pure</title><link href="https://chocolatedrivendevelopment.com/2022/11/30/pure/" rel="alternate" type="text/html" title="Test it like it’s pure" /><published>2022-11-30T00:00:00+00:00</published><updated>2022-11-30T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2022/11/30/pure</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2022/11/30/pure/"><![CDATA[<p>A pure function:</p>

<blockquote>
  <ol>
    <li>has no side effects.</li>
    <li>always produces the same output for a given input.</li>
  </ol>
</blockquote>

<p>Pure functions are known to be easy to test.
We can use their characteristics to make all code easier to test.</p>

<h3 id="dont-mix-logic-and-side-effects-in-the-same-method">Don’t mix logic and side effects in the same method</h3>
<p>Even if you don’t write functional code, this is good practise. 
When separated from the rest you can test the logic to your hearts content, 
and create a single integration test for the side effects.
We need side effects, but keep them isolated and in methods without conditionals.</p>

<h3 id="inject-your-dependencies">Inject your dependencies</h3>
<p>If everything that might vary is part of the input,
the output can be deterministic.
In contrast, letting the method have access to collaborators and state
“behind the scenes”, creates variance that is independent of the input.
That will make for more setup in the tests, and more combinations to cover.</p>

<p>Pure functions remove some of the hardest part from testing, 
you can use that knowledge in all software development.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="code" /><category term="quality" /><summary type="html"><![CDATA[It is not always possible to write pure functions. Still, the properties of pure functions can help us write testable code.]]></summary></entry><entry><title type="html">The upside-down framework anti-pattern</title><link href="https://chocolatedrivendevelopment.com/2022/11/04/upside-down/" rel="alternate" type="text/html" title="The upside-down framework anti-pattern" /><published>2022-11-04T00:00:00+00:00</published><updated>2022-11-04T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2022/11/04/upside-down</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2022/11/04/upside-down/"><![CDATA[<p>In the tv-series <a href="https://en.wikipedia.org/wiki/Stranger_Things">Stranger things</a> there are tentacles, or maybe vines,
spreading through the underworld called “the upside-down”. 
It’s a scary place of darkness,
and the thick dark cords infiltrate and consume.
The clinging and squirming things are also connected to each other.
Step on one and all the others will know.</p>

<p>There is code like this, frameworks that infiltrate the domain code until they are inseparable. 
Change one part and it affects all of it. You are never safe to move. 
Bad habits of the team that designed the framework will seep into the code base. 
(Regardless if the framework is external or developed alongside the domain logic.) 
Getting free takes time. 
Approval tests and safe refactoring are the flamethrowers that can save us.</p>

<p>To avoid this anti-pattern, keep your frameworks at arms length. 
Isolate code that is framework specific from your domain logic. 
Use interfaces!
<a href="https://en.wikipedia.org/wiki/Hexagonal_architecture_(software)">Hexagonal design (ports and adapters)</a> 
can be used for this.</p>

<p>A bonus is that the code will be testable. 
Frameworks are good at side effects. 
Let them deal with that.
The domain code is then easy to put in unit tests.</p>

<p>If the framework is not working for you, or is updated, 
make sure the interface is preserved and the change is mostly done. 
It won’t even make your nose bleed.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="code" /><category term="quality" /><category term="devops" /><summary type="html"><![CDATA[Don't let frameworks interlace with the domain code. Keep them separate and working with the codebase won't require super powers.]]></summary></entry><entry><title type="html">A playground for code</title><link href="https://chocolatedrivendevelopment.com/2022/10/30/playground/" rel="alternate" type="text/html" title="A playground for code" /><published>2022-10-30T00:00:00+00:00</published><updated>2022-10-30T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2022/10/30/playground</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2022/10/30/playground/"><![CDATA[<p>I see unit tests as the playground where code learns to behave.</p>

<p>We want reusable code.
Being easily unit testable is proof that the code can work in two contexts.
As soon as you use the unit outside the test, 
you are already reusing it.</p>

<p>Design pressure from driving development with tests
is like the training kids get from play. 
We teach the code how to interact with others, 
experiment with interfaces, boundaries and naming.</p>

<p>When we have code that works well in a unit test 
(<a href="/2021/12/16/dangerous-skills/">and no, if you need a fancy testing framework the code is not behaving well enough</a> )
we can let it play with the rest of the production code.</p>

<p>If it is a pain to test, it will be a pain to use, maintain and debug. 
So play with the code a bit first, it will be worth it.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="code" /><category term="quality" /><summary type="html"><![CDATA[Unit tests are the playground where code learns to behave. If the code is both easy to test and easy to use, it has shown to be reusable.]]></summary></entry><entry><title type="html">Let code grow old in peace</title><link href="https://chocolatedrivendevelopment.com/2022/10/29/grow-old-in-peace/" rel="alternate" type="text/html" title="Let code grow old in peace" /><published>2022-10-29T00:00:00+00:00</published><updated>2022-10-29T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2022/10/29/grow-old-in-peace</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2022/10/29/grow-old-in-peace/"><![CDATA[<p><a href="/2022/10/04/single-responsibility-salt/">Single responsibility principle</a>,
<a href="https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle">open-closed principle</a> and
<a href="https://en.wikipedia.org/wiki/Law_of_Demeter">Law of Demeter</a> are all design principles that allow code to grow old in peace.</p>

<p>Code that has a limited responsibility, with only one stakeholder. 
Objects and functions that can be part of composition, without being altered. 
Interactions designed to work even if the implementation details of one actor changes. 
They will all likely result in code that has not been touched or altered for a very long time. 
The code is still in use, but as “done” as code ever gets.</p>

<p>It is a blessing when code is allowed to grow stale. 
We should design our code so that it can slowly sediment, 
harden by itself, 
in the peace good design and proper testing creates.
The codebase as a whole will still evolve, and that is going fast. 
Changes to support the business are quickly done in small units with good interfaces. 
Sometimes a bigger part is swapped out. 
In other cases, an old trustworthy part is promoted into a library. 
There is movement where it is needed, but the ripple effects don’t reach far.</p>

<p>When I hear about code freeze or software hardening as part of a delivery pipeline, 
I think about the aging and maturing of code. 
With small units of decoupled and well tested code, it will naturally harden. 
Some files will be created, 
used for days or decades, 
and then deleted, 
without ever being changed.
Others will have an eventful youth, 
but soon settle into being run, but not altered. 
For me, that is the goal, letting the legacy of code create a solid foundation for new work.</p>

<p>What do you have to change to let your code age in peace?</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="code" /><category term="devops" /><category term="quality" /><summary type="html"><![CDATA[Design the code so that as little as possible needs to change when the world changes.]]></summary></entry><entry><title type="html">True conditionals</title><link href="https://chocolatedrivendevelopment.com/2022/10/12/true-conditionals/" rel="alternate" type="text/html" title="True conditionals" /><published>2022-10-12T00:00:00+00:00</published><updated>2024-02-16T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2022/10/12/true-conditionals</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2022/10/12/true-conditionals/"><![CDATA[<p>Complexity in code can be of two types. 
The domain has complexity that has to be represented in the code.
On top of that we add complexity that is related to our solution.
Sometimes this is called inherent and accidental complexity.</p>

<p>Conditionals, like if- and switch-statements, can be used to
model complexity.
When we encounter a conditional in the code we should stop and consider:</p>

<blockquote>
  <p>Is this conditional a part of the domain, or created by how we implemented the solution?</p>
</blockquote>

<p>To me, a true conditional is related to the domain. 
The rest, like error handling, is also important, but should be isolated.</p>

<p>The <a href="https://en.wikipedia.org/wiki/Guard_(computer_science)">guard clause pattern</a> can be used for this.
It uses early return and can be used to check for invalid input.
The “true” conditionals can then work with a known state and the rest of the function will focus on the domain.</p>

<p>At a larger scale than a function, the guard clause pattern turns into a border around the domain code. 
An example of this is hexagonal design, or ports and adapters.
The input is happening on the border, also dealing with validation.
So the domain logic can expect a valid state.<br />
Inside the hexagon we have domain code that can be written as pure functions (or the object oriented equivalent).
When passing the result on, 
we let the border deal with the messy reality outside our bubble,
like retrying when a POST request times out.</p>

<p>Separating the domain logic from uncertainty caused by our dependencies and architecture is also useful when testing.
Tests needed for the domain should be roughly the same independent of what technology we use. 
The test cases we need for the architecture are often related to our language and framework. 
External dependencies, like talking to the database, should be kept out of unit tests entirely. 
Mixing the different testing areas makes it harder to spot when things get unnecessarily complicated. 
I am all for the design pressure aspect of unit tests.</p>

<p>So, is this conditional something you would use when explaining the domain to someone, 
or a result of how it is implemented?</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="code" /><summary type="html"><![CDATA[Conditionals in the code can come from rules in the domain, or from how we constructed the solution. Make sure to know the differance.]]></summary></entry><entry><title type="html">What’s in a name? On unmasking dishonest code.</title><link href="https://chocolatedrivendevelopment.com/2022/10/10/whats-in-a-name/" rel="alternate" type="text/html" title="What’s in a name? On unmasking dishonest code." /><published>2022-10-10T00:00:00+00:00</published><updated>2022-10-10T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2022/10/10/whats-in-a-name</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2022/10/10/whats-in-a-name/"><![CDATA[<p>Reading code that you are not going to change is mostly waste.</p>

<p>Arlo Belshee describes his <a href="https://www.digdeeproots.com/articles/c/series/">Seven stages of naming</a>
in this series of blogposts.
It is a method for reading by refactoring and it is awesome. 
Here I describe a tiny part of one aspect of it, in my words.</p>

<p>Arlo points out that our code is full of names that are nonsense, 
but dishonest nonsense. 
Names that look good, but does not represent the code hiding behind it.
Those names are dangerous in a way than a “bad”, but honest name, is not.</p>

<blockquote>
  <p>getUsers()</p>
</blockquote>

<p>It looks good, but if you don’t trust the code completely, 
you will still want to read the implementation.
And if you don’t read the code,
and the name is dishonest, 
you will break things.</p>

<p>Instead, turn the name into honest nonsense, like applesauce. 
At least that will not lure you into believing that you know what is going on.</p>
<blockquote>
  <p>appleSauce()</p>
</blockquote>

<p>The next step is to find something we know about the code, 
but stay honest by also including the incompleteness of the name.</p>

<blockquote>
  <p>parsesXMLToCreateUsersAndThenSomethingElseIsGoingOn()</p>
</blockquote>

<p>Then we can slowly find out what the code is really doing.
We figure things out, 
and save each piece of information as a part of the name. 
We do this until we have a name that can be read instead of reading the code.</p>

<blockquote>
  <p>parseXMLToCreateUsersAndThenEmailThemAboutPasswordRenewalIfPasswordIsOlderThanAMonth()</p>
</blockquote>

<p>That is a really long name. 
But I prefer long names to emailing people by mistake. 
Now I can see what the code does, 
without reading it, 
and the verbosity of the name tells me something else.</p>

<p>The names in our codebase can show the level of integrity
the code holds, as long as we let them. 
Instead of trying to make the names in our code “look good”,
we should use naming to make our design a tiny bit better,
step by step.
Then, eventually, the code will have good naming and deserve it. 
Remember, we don’t want to read code if we don’t have to.</p>

<p>If we let messy methods have honest and complete names, 
they will also guide our refactoring.
More on that in a later post.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="learning hour" /><category term="code" /><summary type="html"><![CDATA[Verbose and descriptive naming can be ugly, but if the code is messy it is better to show that in the names. Then the names can be a tool for further re-design.]]></summary></entry><entry><title type="html">Single responsibility and salty porridge</title><link href="https://chocolatedrivendevelopment.com/2022/10/04/single-responsibility-salt/" rel="alternate" type="text/html" title="Single responsibility and salty porridge" /><published>2022-10-04T00:00:00+00:00</published><updated>2022-10-04T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2022/10/04/single-responsibility-salt</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2022/10/04/single-responsibility-salt/"><![CDATA[<p>Single responsibility principle is the S in <a href="https://en.wikipedia.org/wiki/SOLID">SOLID</a>.</p>

<p>There is a proverb present in many languages.</p>

<blockquote>
  <p>Many chefs spoil the soup.</p>
</blockquote>

<p>In German there is a version:</p>

<blockquote>
  <p>Many chefs spoil the porridge, 
by adding too much salt.</p>
</blockquote>

<p>(It sounds much better in German.)</p>

<p>I like the German version since it is specific on how the porridge is ruined. 
Each chef has their own plan, adding their own salt,
and the porridge can’t take it. 
That is what happens with code as well. 
The single responsibility principle is about that.</p>

<p>Code should have only one responsibility, 
so that there is only one chef who might put salt in it.
If a piece of code has more than one stakeholder, chef,
too much stuff, salt, will be added to the code.</p>

<p>So what is a chef/stakeholder in this case?</p>

<p>Stakeholders are people, or organisations,
who want to change how the code works.</p>

<p>It can be an external API that is used, and then changes. 
Governments can change a law that effects your code.
Marketing might be a stakeholder.
A specific target audience for the product might add extra salt.</p>

<p>By separating all those interests, 
preferable using interfaces, 
we can make sure that each chef only puts salt in their own pot of porridge.</p>

<p>ps. Developers sharing responsibility for code is a good thing.
We are not stakeholders in this example, as long as we work as a team.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="learning hour" /><category term="code" /><category term="quality" /><summary type="html"><![CDATA[What does too many stakeholders do to a piece of code?]]></summary></entry><entry><title type="html">A forest of developers</title><link href="https://chocolatedrivendevelopment.com/2022/07/29/random-forest/" rel="alternate" type="text/html" title="A forest of developers" /><published>2022-07-29T00:00:00+00:00</published><updated>2022-07-29T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2022/07/29/random-forest</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2022/07/29/random-forest/"><![CDATA[<p>Random forest is a machine learning algorithm.
It is an ensemble algorithm composed of decision trees.
Ensemble machine learning algorithms use the fact that kind of good models 
gets really good if a lot of them are used together. 
They just have to be fully independent of each other.</p>

<p>In ensemble programming we can use the same principle,
but for a forest of developers. 
Everyone in the team does not have to be good at everything.
The important thing is that the team has enough psychological safety so that all
developers are “independent” and can add to the total result.</p>

<p>This is one way to understand the power of ensemble programming.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="ensemble" /><category term="empathy" /><category term="code" /><summary type="html"><![CDATA[Ensemble programming does with developers what the machine learning model random forest does with decision trees. The combination is far better than the parts, if independent enough.]]></summary></entry><entry><title type="html">Software developers don’t hatch</title><link href="https://chocolatedrivendevelopment.com/2022/07/28/dont-hatch/" rel="alternate" type="text/html" title="Software developers don’t hatch" /><published>2022-07-28T00:00:00+00:00</published><updated>2022-07-28T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2022/07/28/dont-hatch</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2022/07/28/dont-hatch/"><![CDATA[<p>When a human is born it lacks most skills. 
Children depend on people around them for years.
Others have to teach them things and care for them until they grow up.</p>

<p>Some other animals are hatched with everything they need to know to survive.
The parents, or rather the source of the egg and sperm, might be miles away.
Still the young know what to do to get by on their own.</p>

<p>As a grown up human it is easy to forget everything we once didn’t know.
In the software industry I see this manifest in a specific way.</p>

<blockquote>
  <p>Software developers are mammals.</p>
</blockquote>

<p>Every TLA (three letter acronym), language caveat, “convention over configuration”
and buzz-word you know, was once new to you.</p>

<blockquote>
  <p>Software developers do not hatch.</p>
</blockquote>

<p>Remember this when you interact
with people that are new to the technology you are using.</p>

<blockquote>
  <p>Remember that you once did not know the things you know today.</p>
</blockquote>

<p>Be kind. 
State things explicitly. 
Create documentation that make people feel smart 
(and not in the “I just deciphered something” way).
Be curious about what others know that you have yet to learn.</p>

<blockquote>
  <p>Software developers are born, not hatched.</p>
</blockquote>

<p>ps. I recommend the <a href="https://en.wikipedia.org/wiki/Becky_Chambers#Wayfarers_series">Wayfarers series</a>
by Becky Chambers for more inspiration on things like sentient reptiles.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="empathy" /><category term="code" /><summary type="html"><![CDATA[It is easy to forget what you once did not know. Be kind to new developers and create an environment for learning.]]></summary></entry><entry><title type="html">Under the hood</title><link href="https://chocolatedrivendevelopment.com/2022/05/17/under-the-hood/" rel="alternate" type="text/html" title="Under the hood" /><published>2022-05-17T00:00:00+00:00</published><updated>2024-02-16T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2022/05/17/under-the-hood</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2022/05/17/under-the-hood/"><![CDATA[<p>Usually this blog does not focus on technical details. 
Until I figure out a better way to share it, this is an exception. 
I wanted to share my setup, in case it helps someone else. 
If I left out the detail you needed, feel free to contact me.</p>

<h2 id="development">Development</h2>
<p>This blog is created with <a href="https://jekyllrb.com/">Jekyll</a>.
For development I use Docker and docker-compose.</p>

<p>The <code class="language-plaintext highlighter-rouge">docker-compose.yml</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>---
services:
    jekyll:
      image: bretfisher/jekyll-serve
      volumes:
        - .:/site
      ports:
        - '4000:4000'
</code></pre></div></div>

<p>That way I can work on any machine that has git and Docker (with docker-compose).
The project has a readme.md where I store everything I have to remember,
including ToDos.
The <code class="language-plaintext highlighter-rouge">exclude</code> list in <code class="language-plaintext highlighter-rouge">_config.yml</code> is used to make sure convenience files are not
included in the final site. That gives me freedom to add what I need.</p>

<h3 id="migration">Migration</h3>
<p>I used the RSS-feed and a ruby script to do a rough migration of my texts.
Since the old platform did not support a feed containing all posts,
I had to do some un-publishing to make it work.</p>

<h3 id="editor">Editor</h3>
<p>I prefer to use RubyMine for writing blog posts and have created custom templates
for the collections I create most often.
<a href="https://www.jetbrains.com/help/idea/using-file-and-code-templates.html">How to create custom templates.</a></p>

<h2 id="deployment">Deployment</h2>
<p>The site is run on Ubuntu with nginx.
Updates are made by GitHub actions. 
The deploy-action is based on an ssh-action. 
It logs in to the server, 
pulls the latest version from git, 
builds the site on the server and copies it to the right folder.
I like how GitHub actions are stored with the source code.
Since I can push to git over 443, I can also deploy from places with very strict 
firewalls.</p>

<h2 id="analytics">Analytics</h2>
<p>The site uses <a href="https://matomo.org/">Matomo</a>. 
Currently I use their SaaS, but it is easy to host on your own. 
I have disabled all cookies for tracking. 
That gives me less data, but probably enough data. 
If I change my mind you will see the banner.</p>

<h2 id="images">Images</h2>

<p>For images I use a Jekyll <code class="language-plaintext highlighter-rouge">_data</code>-file and an <code class="language-plaintext highlighter-rouge">include</code>.
The illustrations.yml has a path to the image file,
the alt-tag text, and credits (often including copyright information.)
Illustrations also have a name, used as an id. 
This way I can make sure that all images have the meta data needed.</p>

<p>My <code class="language-plaintext highlighter-rouge">image.html</code> in <code class="language-plaintext highlighter-rouge">_includes</code>. The 
<code class="language-plaintext highlighter-rouge">{% assign ill ...</code> 
line finds the illustration based on name.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
{% if include.image %}
    {% assign ill = site.data.illustrations[include.image] %}
        &lt;img src="/assets/images/{{ill.assets-path}}" alt="{{ ill.alt }}" title="{{ill.cred}}"/&gt;
{% endif%}

</code></pre></div></div>

<p>In the layout files it looks like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
  {% include image.html image=post.illustration %}

</code></pre></div></div>
<p>where <code class="language-plaintext highlighter-rouge">post.illustration</code> is the name of the illustration.</p>

<p>To get the image to preview in social media I use  <code class="language-plaintext highlighter-rouge">_includes/head.html</code></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
  {% if page.illustration %}
    {% assign ill = site.data.illustrations[page.illustration] %}
    &lt;meta property="og:image" content="{{ site.url }}/assets/{{ ill.assets-path }}" /&gt;
  {% endif %}

</code></pre></div></div>

<p>There are Jekyll plugins for images, but I did not think that they fit my needs.
I might change my mind later.</p>

<h2 id="comments">Comments</h2>
<p>I have not had many comments on my previous setup,
so I opted for a low-tech “e-mail me” version. 
The link tag pre-populates the to-address
and what post the comment refers to is included in the subject.
If there are loads of comments I will need another solution,
but that is a nice problem to have.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="code" /><summary type="html"><![CDATA[This is a meta text about how this site is build using Jekyll.]]></summary></entry><entry><title type="html">Refactor or rewrite?</title><link href="https://chocolatedrivendevelopment.com/2022/05/11/refactor-or-rewrite/" rel="alternate" type="text/html" title="Refactor or rewrite?" /><published>2022-05-11T00:00:00+00:00</published><updated>2022-05-11T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2022/05/11/refactor-or-rewrite</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2022/05/11/refactor-or-rewrite/"><![CDATA[<p>I’ve just migrated this website and feel the need to write about why I don’t like big rewrites.
I moved my blog since the platform I used has flaws I could not live with, and had no power to change.
So I had to move. But otherwise I am “team refactor”. Here I explain why.</p>

<h2 id="specification-missing">Specification missing</h2>
<p>It is very rare that a system has a complete documentation of its feature set. 
When doing a rewrite you still have to figure out what to implement. 
Often that is a big part of the job. That also makes it really hard to estimate the size of the rewrite.</p>

<h2 id="information-in-the-code">Information in the code</h2>
<p>Legacy code contains a lot of information. 
If you don’t know the code well, it is hard to know if it is domain complexity or accidental complexity.
If it is domain complexity, the new system will be as hard to understand, but in a new, unfamiliar way.</p>

<h2 id="stable-and-making-money">Stable and making money</h2>
<p>New code has a tendency to be more flaky than old code. Not true everywhere. 
But those of you who hit this site, while I figured out this or that, knows how my 404-page looks.
I have also not written any blogs in like forever, while working on the website.
An old codebase can be terrible to work in, but it is often running in production and creating value.</p>

<h2 id="sustainable">Sustainable</h2>
<p>When the code is something you own, its condition is in your hands. 
If hard to change code is always thrown out, we miss a chance to learn.
And it is wasteful. Imagine moving house instead of spring cleaning. 
The skills we need for refactoring will make our software better in a way no rewrite ever will.</p>

<p>So learn how to take care of your code. Mend it and refactor it.
Use patterns that will make it possible to replace parts when they get outdated,
without tearing out all the domain code.
The grass is not always greener in green field development.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="quality" /><category term="code" /><summary type="html"><![CDATA[Learning to refactor instead of rewriting preserves the domain knowledge build into the old codebase while it can keep making money. The skill of continuous improvement is important for developers, and might be neglected in a "rewrite" culture.]]></summary></entry><entry><title type="html">Dangerous skills</title><link href="https://chocolatedrivendevelopment.com/2021/12/16/dangerous-skills/" rel="alternate" type="text/html" title="Dangerous skills" /><published>2021-12-16T00:00:00+00:00</published><updated>2021-12-16T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2021/12/16/dangerous-skills</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2021/12/16/dangerous-skills/"><![CDATA[<p>Being good at managing stress could be dangerous.
Being good at preventing long term stress should be our aim.</p>

<p>The same way,
testing the untestable looks good on your resume.
Used careless, it is also a way to allow sloppy software design.
The goal is code that is easy to test.
Because code that is easy to test is easier to work with, long term.
A powerful tool for testing can become a liability.
Awesome testing skills become a danger,
if it leads to code that had no design pressure.</p>

<p>We need skills for the life we have, including its stress and hard to test code.
But don’t confuse necessity with virtue.
To build the world we want to have, we have to hone skills for such a world.
It can be removing the cause of stress or getting better at software architecture.
It will make our old skills a bit less valuable.
Allow yourself to grieve that.
it will also require us to do things we are not that good at yet.
It is ok to find that scary.
Just don’t let today’s skills dictate tomorrow’s reality.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="quality" /><category term="code" /><summary type="html"><![CDATA[Being good at things nobody should ever have to do is a tricky thing. This is a text about wishing for a better world, also when you don't yet have the skills needed to perform well in that world.]]></summary></entry><entry><title type="html">Choosing a language or framework</title><link href="https://chocolatedrivendevelopment.com/2021/09/29/choosing-a-language-or-framework/" rel="alternate" type="text/html" title="Choosing a language or framework" /><published>2021-09-29T00:00:00+00:00</published><updated>2024-02-16T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2021/09/29/choosing-a-language-or-framework</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2021/09/29/choosing-a-language-or-framework/"><![CDATA[<p>When starting a new project,
or adding a new module to an existing project,
the question of language and framework arises.
This is a list of things that I consider when picking a language.</p>

<h2 id="existing-ecosystem">Existing ecosystem</h2>

<p>If you already have a handful of different technologies in the project,
it is hard to maintain a good level of knowledge for them.
Adding another language or framework will not help.
It most of the code is stable,
so that it never change,
and simple enough to be replaced easily when an upgrade is necessary,
this is less of an issue.
But if you have a lot of code that is still actively maintained by the team,
pick something that is already existing in the ecosystem.
If the technical requirements are new,
say you will build the first native smartphone app for the project,
exceptions must be made.
If you are afraid that the technology you have won’t be fast enough,
write a small test. Guess at the part that will demand the most of the system,
implement it for a load test in a technology you already have.
Then you will know if you need to introduce more complexity to the project or not.</p>

<h2 id="knowledge-in-the-team">Knowledge in the team</h2>

<p>If you do not have a lot of code in place,
but you have the people,
let them decide.
Not from the shiny toys they want to try, but something they have experience in.
Set aside time to experiment on new technology
outside of the main project to play with the shiny stuff.
That is not for production.
If you need to introduce new technology,
as in the smartphone example above,
make sure that the entire team learns enough
to at least be able to fix a simple bug and deploy to production.</p>

<h2 id="culture-of-the-technology">Culture of the technology</h2>

<p>Languages and frameworks have communities.
One of my favourite podcasts, <a href="https://www.greaterthancode.com/">&gt;Code</a>,
have panelists who learned Ruby
because of the people who go to Ruby conferences.
If you need to introduce something new,
try to get a feel of the people who already use the technology.
Read the code of conduct for the major conferences.
Look at the tone in replies to bug reports and feature requests.</p>

<h2 id="availability-when-hiring">Availability when hiring</h2>

<p>It you do not have a team,
or the team needs to grow, can you hire for the technology?
Senior developers should,
in my opinion, be able to learn any technology quite quickly.
But it might be easier to choose something
that people already know and use.
I would say that this is extra important
if you are not the owner of the product,
but helping a customer to get it started.</p>

<h2 id="patterns-and-practises">Patterns and practises</h2>

<p>Beside the “people culture” around a technology,
there is also a programming culture.
Look at the testing frameworks and what patterns people use.
Will it be easy to find high quality examples online?
Is the standard way of doing things containing patterns
that will prevent you from following good practise?
An example was a framework
that encouraged scripts that swapped lines in configuration files,
instead of allowing different configurations when building your target.
That practise then also leaked into other parts of our project,
wreaking havoc in the setup of originally more sensible frameworks.
People will learn from what they do,
don’t bring technology with bad practises into your ecosystem.
Overly powerful testing tools is also a smell.
If you need to “power mock” something, that is a sign of bad design.
If all the focus is on integrated tests, that is also a warning.</p>

<h2 id="the-actual-language">The actual language</h2>

<p>Yes, if you do not have very specific requirements,
that you have verified are true,
the actual language comes last.
For projects that are totally new,
where you know you have enough people,
and multiple languages are good candidates,
you might need to consider the language design.
In that case my preference is to look for two things:
integrity and decoupling.
How easy is it to make sure
that my assumptions of the state of the running program is correct?
This contains things as dealing with null, memory, types and exceptions.
How easy is it to write modular code?
That has to do with things as interfaces or protocols,
the status of functions,
imports and the
<a href="https://en.wikipedia.org/wiki/Liskov_substitution_principle">Liskov substitution principle</a>.
What I value in a language change as I learn more.</p>

<p>Writing code for people (including yourself)
is harder than writing it for the computer.
That is why the people aspect of a technology is more important to me
than the technical aspects.
That is true also when choosing a language or a framework.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="code" /><category term="list" /><summary type="html"><![CDATA[Languages and frameworks will be part of a larger context. Consider the existing environment when choosing a language or framework.]]></summary></entry><entry><title type="html">The importance of signatures</title><link href="https://chocolatedrivendevelopment.com/2021/09/29/the-importance-of-signatures/" rel="alternate" type="text/html" title="The importance of signatures" /><published>2021-09-29T00:00:00+00:00</published><updated>2021-09-29T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2021/09/29/the-importance-of-signatures</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2021/09/29/the-importance-of-signatures/"><![CDATA[<p>The signature of a function,
or method,
is its name together with the signature of its inputs and outputs.</p>

<p>To get the benefits from abstractions
we need to turn each signature into a curiosity barrier.
When looking at the signature,
a developer should know what the piece of code does,
without needing to read the implementation.
To achieve that we use all the parts of the signature.</p>

<h2 id="name">Name</h2>

<p>Naming is hard, but rewarding if done right.
<a href="https://www.digdeeproots.com/articles/on/naming-process/">Naming as a process</a>
can help,
since it uses an iterative approach to finding a really good name.
Making sure that the domain is present in the naming is also key.
In a <a href="https://youtu.be/icGhEOWPqB4">presentation on documentation</a>
Cyrille Martraire suggest creating a
<a href="https://en.wikipedia.org/wiki/Tag_cloud#Text_cloud">word cloud</a>,
a weighted visual representation, from the codebase.
If you can not see your domain in the cloud that is a code smell.</p>

<h2 id="inputs">Inputs</h2>

<p>Make sure that the prerequisites for the code is explicit.
You want your code to be a small friendly blob, that can be moved around.
You do not want it to be something that looks small and cute,
but where the backside have tentacles that are everywhere
and where moving it will kill everything that it worked its way into.
Achieving this is done by having all collaborators as inputs.
This is often called dependency injection.
Ways to access system time,
or other environment information,
is also a collaborator.
Writing unit tests is a good way
to discover what your code needs access to.
The setup for the test
should only consist of constructing inputs for the call.
If the list of inputs is too big,
that is a sign that the code needs refactoring.</p>

<h2 id="outputs">Outputs</h2>

<p>Side effects are dangerous,
so having outputs that tell the whole story of what has been done is preferable.
If the purpose of the code is a side effect,
like sending an email or saving to the database,
it is good if the output reflects that.
One way is to let all functions with side effects be void functions.
That requires that dealing with errors is done by some other means,
so it is not always possible.
For side effect free functions,
the output should give as much information on what to expect from the function
as needed.
The unit tests for non-void functions should be fine only asserting on the output
(for the happy path at least),
since they should be side effect free.</p>

<p>The goal is to use all the parts of the signature
to still the curiosity of the developer using the code.
Our struggle to achieve that will also tell us things about the design,
if we listen.
So make sure to use all the parts of the signature
when describing what your code does.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="code" /><summary type="html"><![CDATA[Get the benefits from abstractions by turning each signature into a curiosity barrier. When looking at the signature, a developer should know what the piece of code does, without needing to read the implementation.]]></summary></entry><entry><title type="html">The best kind of code</title><link href="https://chocolatedrivendevelopment.com/2021/09/09/the-best-kind-of-code/" rel="alternate" type="text/html" title="The best kind of code" /><published>2021-09-09T00:00:00+00:00</published><updated>2021-09-09T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2021/09/09/the-best-kind-of-code</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2021/09/09/the-best-kind-of-code/"><![CDATA[<blockquote>
  <ol>
    <li>Code never written</li>
    <li>Code never read</li>
    <li>Code never changed</li>
    <li>Code telling a story</li>
  </ol>
</blockquote>

<p>The best code is the one we never write.
Perhaps user research shows that there will be no value.
Or there might be a library we could use, or some service.</p>

<p>If we have to write code it should have an interface
so clear that it tells all there is to know.
If the code can be trusted,
and we know how to use it,
there is no need to read it.</p>

<p>If we need to read it,
at least it should have so little responsibility
that there is only one reason to change it.
And if there is only one reason to change it,
nothing else should be at risk breaking due to that change.</p>

<p>If we have to change it,
like really change it,
keeping some functionality and changing other parts.
Then it should at least tell us
so much about it self that we know what is going on.</p>

<p>This is my code type top-list. What is your favourite kind of code?</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="code" /><category term="list" /><summary type="html"><![CDATA[Code never written, code never read, code never changed and code telling a story]]></summary></entry><entry><title type="html">A language agnostic debugging list</title><link href="https://chocolatedrivendevelopment.com/2021/06/09/a-language-agnostic-debugging-list/" rel="alternate" type="text/html" title="A language agnostic debugging list" /><published>2021-06-09T00:00:00+00:00</published><updated>2024-02-16T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2021/06/09/a-language-agnostic-debugging-list</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2021/06/09/a-language-agnostic-debugging-list/"><![CDATA[<p>Checklists are nice cognitive tools.
This one can also work as a reminder when designing code.
Please come with feedback and suggestions for improvement.</p>

<p>It is not always the case that we immediately spot the reason for an error in a codebase.
Sometimes it is hard to find due to the design.
In other cases the definition of correct behaviour is the problem.
It might also be a lack in understanding when it comes to the technology used.
This checklist is useful regardless of your knowledge of the language you are debugging.
Depending on domain knowledge, technical knowledge and the state of the code base,
how long the steps take and what information they give, will vary.
This is, as most knowledge work,
best done together with someone else,
or with an entire team.</p>

<h2 id="a-test">A test</h2>

<p>Write a test,
of some kind,
that captures the unintended behaviour.
In worst case it is a description of steps to take
written on a piece of paper.
Best case is a unit test.
This will define where we see the problem,
with its setup and the state it leaves the program in.</p>

<h2 id="specifications">Specifications</h2>

<p>Do we know for sure that this is a problem,
not just a state where the behaviour is not clearly defined?
Make sure that we know what the code is supposed to do
in this particular case.</p>

<h2 id="location">Location</h2>

<p>Are we sure that this is where the problem is caused? Check that the in-data is correct,
and that the data out is not as expected.
Try to narrow it down,
define as little code as possible where the error might be.</p>

<h2 id="regression">Regression</h2>

<p>Has it ever worked?
If it has, what has changed since then?
Version control is your friend here.</p>

<h2 id="static-analysis">Static analysis</h2>

<p>Is the IDE saying anything?
A real development environment uses parts of the same algorithms
as the compiler/transpiler/interpreter,
to be able to give hints and syntax highlighting.
There is also often static code analysis tools
that can highlight practises that make the code fragile.
Use tools.</p>

<h2 id="surrounding-state">Surrounding state</h2>

<p>Are there inputs, not stated as such, in the code we are looking at?
Some code use state that is external in some way.
One way to check this is by trying to write a unit test,
instead of an integration test.
What do we need in our setup to make it work?
The state could be a global variable used by a collaborator,
today’s date, or some settings in the system.
Make sure that we know all the <em>actual</em> input data to the code we are investigating.
Try to make the implicit input explicit when testing the code.</p>

<h2 id="comparing">Comparing</h2>

<p>If there is comparing going on,
is it done correctly (for that language)?</p>

<h2 id="things-missing">Things missing</h2>

<p>Do we know what could be null/nil/empty?
Keeping null-checks at the boundaries of code makes this easier.
Use the tools the language provide to deal with missing data.</p>

<h2 id="data-structures">Data structures</h2>

<p>Are data-structures used as intended?
If iteration happens,
are the boundaries the right one?
Do the data-structures have any quirks in this framework?</p>

<h2 id="language-specifics">Language specifics</h2>

<p>Are there other language features that could be a problem? In Python,
default arguments can turn into singletons.
In ObjectiveC a method call on a deallocated object will return 0,
or nil, but succeed.
Try to rewrite the code, even if it turns it bulkier,
just to see if misdirected “cleverness” might be the problem.
Then read the documentation to understand what happens if the behaviour changes.</p>

<h2 id="flow">Flow</h2>

<p>Is the flow of execution as we think it is?
Use a debugger to step through the calls, following the control flow.
Test cases can also be run in debug-mode.
Make sure that there are no code skipped.
One example is if code is executed as part of a condition,
that is already evaluated as true, and therefore skipped.</p>

<h2 id="threads">Threads</h2>

<p>Are we working with asynchronous code?
If we are, then make sure that it is done correctly.
Test ways to make sure that all of the suspect code is run synchronous,
to eliminate logic errors that are not timing related
, even if the code can never run like that in production.</p>

<h2 id="identity">Identity</h2>

<p>Is everything what we think it is?
Is the runtime scope clear?
Do we have inheritance, this/self references,
variables or functions that might shadow each other,
or other things that might not be what we assume that they are?
Do we reuse variable names or references?
Might there be things where ownership is unclear and it is garbage collected?
Use a debugger, or print statements, to check that things are what we expect.
(<a href="https://www.youtube.com/watch?v=IyYnnUcgeMc">Playing Destiny’s Child while doing this is optional</a>,
but it is a good reminder that scope in JavaScript is tricky.)</p>

<h2 id="self-care">Self care</h2>

<p>Take a break, if you have not already.
At this point I might start searching the internet,
or try writing a question at Stack Overflow.
(Often the solution is in writing the post, not posting it.)
I might also call a friend.
My experience is that the harder the answer is to find,
on the internet,
the more likely it is that the mistake made is really basic.</p>

<p>Hope this list helps.
I will use it the next time I get stuck on code not working as I intended.</p>

<p>How do you find your mistakes?
Do you have anything to add?
Have I missed anything language specific that is not included in the steps above?</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="quality" /><category term="code" /><category term="list" /><summary type="html"><![CDATA[A cognitive tool in shape of a list of things that often go wrong when writing code. Nice to have when you get stuck.]]></summary></entry><entry><title type="html">Lift with your legs</title><link href="https://chocolatedrivendevelopment.com/2021/04/19/lift-with-your-legs/" rel="alternate" type="text/html" title="Lift with your legs" /><published>2021-04-19T00:00:00+00:00</published><updated>2021-04-19T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2021/04/19/lift-with-your-legs</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2021/04/19/lift-with-your-legs/"><![CDATA[<p>When lifting we always want to do it correctly,
so that we do it right by reflex as we lift something heavy.
No personal trainer will tell you that it is ok to be sloppy with the lighter weights.
Damage is prevented by always using our legs and keeping the back straight.</p>

<p>What is the equivalent in software development?</p>

<p>Premature optimisation is a thing.
There are also things that do not take that much time to do
when we know how to do them.
The first times we try to lift with our legs,
or get the movement right with a barbell,
it is tricky.
It will take more time than if we just did it without care.
But at some point it comes natural.
And it is definitely easier to learn it with something
that is also not the heaviest we can lift.
We should be practising the skills we need to manage “heavy” code
also on “light” code.
Getting to a point where the sustainable way to write software is done by reflex,
could save pain the same way that lifting with your legs does.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="code" /><summary type="html"><![CDATA[We have to practise new skills in a setting where everything else is easy. Getting to a point where the sustainable way to write software is done by reflex, also on the easier tasks.]]></summary></entry></feed>