<?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.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.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">Workshops that work</title><link href="https://chocolatedrivendevelopment.com/2024/12/04/workshop-work/" rel="alternate" type="text/html" title="Workshops that work" /><published>2024-12-04T00:00:00+00:00</published><updated>2024-12-04T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2024/12/04/workshop-work</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2024/12/04/workshop-work/"><![CDATA[<p>A workshop can be a powerful tool for leading, creating or exploring.
If it is a retrospective, design sprint or a learning hour,
some aspects are common for success.</p>

<h2 id="purpose">Purpose</h2>

<p>Only one thing can be the <em>most</em> important.
If we want to align a workshop well, aligning it for one thing,
and nothing else, is the easiest.
A workshop has limited time, so the scope must be limited.
Decide what the most important outcome is for the workshop,
and design it fully for that outcome.</p>

<h2 id="participation">Participation</h2>

<p>Everyone is important in a workshop.
If the purpose is learning,
each participant needs to get a chance to grow.
For workshops aimed at creating or exploring,
the views from everyone are even more crucial.
It is important to have a structure that works for extroverted
and for introverted people. 
One way to do that is by using exercises that let people think on a topic in multiple ways,
some of those can be found among the <a href="https://www.liberatingstructures.com">liberating structures.</a></p>

<h2 id="structure">Structure</h2>

<p>Guiding towards the purpose, and enabling participation,
is done through structure.
<a href="/2023/09/26/retro-interface/">This post is about creating structure in a workshop</a></p>

<h2 id="time">Time</h2>

<p>For a workshop to work as planned, you need to be able to complete
all steps.
Some workshops can bring value when half-finished,
but most need the conclusion and some make things worse if left half done.</p>

<h2 id="information">Information</h2>

<p>The workshop needs full focus.
If the participants lack information, the facilitator has to have it at hand;
otherwise the schedule will be disrupted.
Try to anticipate what will be needed, or plan for breaks long enough
so that missing information can be found.</p>

<h2 id="trust">Trust</h2>

<p>The last, but not least, part is trust.
The environment has to be psychologically safe, and the
facilitator must be trusted by the participants.
Trust can be cognitive or emotional.
The important part is to have a mandate to lead the workshop,
and that everyone else feels safe to participate.
<a href="/2020/07/07/diversity-and-psychological-safety-the-struggle-of-the-little-mermaid/">You can read more about psychological safety here.</a></p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="equity" /><category term="agile" /><category term="retros" /><summary type="html"><![CDATA[Workshops can be powerful tools, but with a clear purpose, full participation, supporting structure, managed time, enough information and trust in facilitator, they are even better.]]></summary></entry><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 magic of comfort zones</title><link href="https://chocolatedrivendevelopment.com/2023/09/28/comfort-zone/" rel="alternate" type="text/html" title="The magic of comfort zones" /><published>2023-09-28T00:00:00+00:00</published><updated>2023-09-28T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2023/09/28/comfort-zone</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2023/09/28/comfort-zone/"><![CDATA[<p>Kid’s independence is a love battery, 
charged and grown with closeness, 
safety and care, for their entire childhood.
Until one day they can carry that sense of safety with them out in the world, 
powered by just knowing that they are loved.</p>

<p>If we want people to learn new things,
collaborate with an open heart,
and challenge the limits of their capacity,
we do that by creating a safe and nurturing place for them.</p>

<p>The way out of the comfort zone is to have a comfort zone to start with.
Make people feel so safe that they get bored and start creating,
so cherished that they dare make a fool of themselves,
and so relaxed that all energy go into the task at hand.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="empathy" /><category term="equity" /><category term="devops" /><summary type="html"><![CDATA[When we feel comfortable there is room to try new and uncomfortable things. Then we can take (calculated) risks, collaborate and create. Value real comfort zones.]]></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">IT-stress, part 2 — change</title><link href="https://chocolatedrivendevelopment.com/2023/08/22/stress-2/" rel="alternate" type="text/html" title="IT-stress, part 2 — change" /><published>2023-08-22T00:00:00+00:00</published><updated>2024-02-16T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2023/08/22/stress-2</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2023/08/22/stress-2/"><![CDATA[<p>Software that is unreliable or hard to use causes stress in the work place. 
It also lowers productivity.</p>

<p><a href="/2023/08/21/stress-1/">The previous post is on coping with IT-stress</a>
This is about preventing it.</p>

<h3 id="software-can-change">Software can change</h3>
<p>Software is named in contrast to hardware.
Computer programs should be easy to change.
You can get an update into production in less then an hour, with modern methods.
( Refer to <a href="/references/accelerate.html">Accelerate</a> 
if you encounter someone who says otherwise.)
If the software is not working, for the ones using it, the software should be changed.</p>

<h3 id="be-a-part-of-the-process">Be a part of the process</h3>
<p>Half of corporate budgets for software (in Sweden) is used for customisation. 
Either for modifications of existing software by external parties
or external developers working on in-house projects.
On top of that, about 40% of IT-workers in Sweden work for companies that produce something else than software.</p>

<p>That is a lot of software being written with a specific customer in mind.
If you are that customer, demand to be a part of the entire process.
Software tailored to your needs requires your input,
just as a suit or dress is made with multiple fittings.</p>

<p>“Off the shelf”-software has to be tried by the end users before committed to.
The cognitive ergonomics when investing in software should be considered similar
to ergonomics when furnishing a workshop or office.</p>

<p>If the software is a part of your “competitive edge”, consider having a dedicated 
team of software developers, who get to know you and your domain really well.
Provide them with direct access to the end user
and put them close to (or in) the product team.</p>

<blockquote>
  <p>The software team should be like a painters brush, 
swift in the hands of product development.</p>
</blockquote>

<p>If your software team can not deliver on that, provide them with training and other support until they do.
Your organisation deserves it.</p>

<h3 id="put-the-user-in-the-center">Put the user in the center</h3>
<p>The purpose of software is to make things better.
It is a failure if the end user can not easily use the product.
We can check that we are building the right thing as we go,
if we have the end user close and work in small steps.
In Extreme Programing, a flavour of agile, the customer is represented in the team.
If that does not work, find another way to get constant and real feedback.
This avoids delivering something that is “done”, but can not be used.</p>

<h3 id="expect-more-of-software">Expect more of software</h3>
<p>Whenever you can, demand more of software you encounter.
<a href="/references/accelerate.html">Accelerate</a> 
is a good book on what can be expected of an organisation delivering software.
<a href="/references/devops-2021.html">The DevOps report 2021</a>
and
<a href="/references/devops-2019.html">The DevOps report 2019</a> 
are shorter reports covering the findings from the research.
Remember that soft in software is soft as in changeable.
If you are in charge of spending money on software, off-the-shelf or in developer hours,
take your responsibility.
Software development is best done with the end user in focus and in small steps.
Don’t accept less.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="quality" /><category term="product" /><category term="agile" /><summary type="html"><![CDATA[IT-stress has gotten into the top list of problems in the workplace. This is a text about changing that.]]></summary></entry><entry><title type="html">IT-stress, part 1 — coping</title><link href="https://chocolatedrivendevelopment.com/2023/08/21/stress-1/" rel="alternate" type="text/html" title="IT-stress, part 1 — coping" /><published>2023-08-21T00:00:00+00:00</published><updated>2023-08-21T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2023/08/21/stress-1</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2023/08/21/stress-1/"><![CDATA[<blockquote>
  <p>It is not your fault.</p>
</blockquote>

<p>Software causes stress in the workplace.</p>

<p>The stress can come from things breaking down unexpectedly,
like projectors not starting,
audio missing in the video conference call or
the e-mail draft disappearing as you refill your coffee.</p>

<p>There are also the thousand cuts from the paper free work place.
Interfaces that are clunky,
dropdowns with a thousand options, where the most common is the last.
Forms demanding you to type in the same information three times
and then complains about the format.
(Perhaps by erasing everything you entered in so far.)
Information portals with unreliable search and no predictable structure.
Not to get stared on permissions to add or change information (or structure).</p>

<h2 id="coping">Coping</h2>

<p>This text is about coping with what you can not change.
Part two is about eliminating the source of the stress (bad software).</p>

<h3 id="put-the-blame-where-it-belongs">Put the blame where it belongs</h3>

<p>Software should never make you feel stupid.</p>

<p>When the printer throws a tantrum or an app suddenly restarts,
the responsible people are:</p>
<ul>
  <li>involved engineers</li>
  <li>their managers</li>
  <li>the one buying/financing the software (sometimes)</li>
</ul>

<p>Unless you are on that list, it is not your fault.</p>

<p>Software doesn’t have to be like that. 
The industry knows how to create intuitive interfaces.
There are processes for writing reliable software.
User research exists, just not enough.
You deserve better software. 
No human is non-technical, 
it is the technology that is inhumane.</p>

<h3 id="write-a-bug-report">Write a bug report</h3>

<p>Reporting issues with software has two benefits.
If the software organisation is good, it will use the feedback.
For organisations too immature to appreciate it, 
at least you can use it to let out some steam.
Put your frustration into precisely worded descriptions
and screen recordings showing the problem. 
Be polite, since that will help the organisations who welcome it and
annoy those who don’t.</p>

<h2 id="for-managers">For managers</h2>
<p>If the workbench has the wrong height,
or the knives are blunt,
you can not expect the best results.
The same is true with IT.
You have to adjust the expectations on your staff accordingly.
(At least until you are able to fix the software.)</p>

<p>The cognitively ergonomics of a workplace are as important as the physical ergonomics.
Software that is hard to use and/or unreliable, will affect the work,
regardless of the attitude among the employees. 
It is biology.</p>

<h2 id="the-it-industry">The IT-industry</h2>
<p>Software developers also suffer from IT-related stress.
No one is too clever to benefit from easy to use software.
If you are taxed by flaky tests or buggy editors,
know that you also deserve good interfaces and reliable experiences.
You are not less for wanting to work smart rather than hard.
If you struggle with getting software to work,
it has nothing to do with your aptitude as a developer.
You don’t have to be smart to make someone else feel stupid.</p>

<p>If you are a manger, or a role model, in IT, don’t idealise fire fighting.
Acknowledge when infrastructure and tooling are slowing you down,
and celebrate the canaries in the team.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="empathy" /><category term="equity" /><category term="product" /><summary type="html"><![CDATA[IT-stress has gotten into the top list of problems in the workplace. This is a text about coping with it.]]></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">Ensemble to make a smarter team</title><link href="https://chocolatedrivendevelopment.com/2022/11/29/collective-intelligence/" rel="alternate" type="text/html" title="Ensemble to make a smarter team" /><published>2022-11-29T00:00:00+00:00</published><updated>2022-11-29T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2022/11/29/collective-intelligence</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2022/11/29/collective-intelligence/"><![CDATA[<p>Problem solving ability is not only related to relevant knowledge or expertise.
For one person, doing cognitive work,
the explaining factor is called general intelligence (IQ).</p>

<p>IQ is a measurement widely used,
though problematic, due to its history and how it has been used.
(<a href="https://radiolab.org/series/radiolab-presents-g">I recommend this series by RadioLab</a>)</p>

<p>For a group working together the same phenomenon is called “collective intelligence factor”.
Just like individual intelligence, it aims to describe why some teams have consistent better performance,
independent of the nature of the task. 
<a href="https://www.einsteinmed.edu/uploadedFiles/diversity/collective-intelligence-science.pdf">Research by Woolley et al.</a>
shows that there are two major factors
that contribute to how intelligent a group of people is.</p>

<blockquote>
  <ol>
    <li>Correctly reading the emotional state of others</li>
    <li>Equal contribution in conversations and turn taking</li>
  </ol>
</blockquote>

<p>Compare this with aspects of ensemble programming.</p>

<ol>
  <li>
    <p><strong>Regular retrospectives create a place
for learning about others experiences.</strong>
Retrospectives are a great way to improve your work, 
and one aspect is practising empathy.
It creates a forum for sharing your perspective, including how you feel. 
An ensemble session ending with a short retro builds a feedback system for the team interactions.</p>
  </li>
  <li>
    <p><strong>Talking on a timer creates a framework
for distributing contribution.</strong>
<a href="https://pure.mpg.de/rest/items/item_68785_7/component/file_506904/content">We are not very good at judging how talking time is actually distributed.</a>
Strict ensemble working, with a timer, helps us get input from everyone. 
It could also help us get a better sense of what equal talking time feels like.</p>
  </li>
</ol>

<p>The interactions of a team is more important for the result than their individual
intelligence. 
That is good news. 
It is hard (or even impossible, depending on definition) to improve ones intelligence.
The dynamics of a team, and how we read and regard others emotions, can develop.</p>

<p>If you want to improve the general performance of a team, help them:</p>

<ol>
  <li>Take note of each others emotions.</li>
  <li>Get the input from everyone.</li>
</ol>

<p>One way to do this is through ensemble working, ending it with a short retrospective.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="ensemble" /><category term="empathy" /><category term="retros" /><summary type="html"><![CDATA[Teams perform better when dividing talking time and recognizing each others emotions. Working in an ensemble facilitates both of them, when done right.]]></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">Anti-work polluters</title><link href="https://chocolatedrivendevelopment.com/2022/10/28/anti-work-polluters/" rel="alternate" type="text/html" title="Anti-work polluters" /><published>2022-10-28T00:00:00+00:00</published><updated>2022-10-28T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2022/10/28/anti-work-polluters</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2022/10/28/anti-work-polluters/"><![CDATA[<p>Anti-work, the unplanned work, that eliminates planned work, as it uninvited enters your day.
It is everything from fire fighting to bug fixes and cleaning up afterwards. 
Your intentions for progress goes up in proverbial smoke.</p>

<p>Not only will anti-work make life harder inside the organisation, 
it also leaks into the surrounding world. 
Anti-work pollution!</p>

<p>There is a lot of literature on the topic targeting the IT-industry.
<a href="/references/phoenix.html">The Phoenix Project</a> both describes where it comes from, 
and parts of what we can do about it. 
Preventing anti-work is also something a Technical Coach helps with.</p>

<p>We want to minimise anti-work to be more profitable and a better work place. 
We should also pay attention to what our anti-work does to people outside the company.
An organisation that fails to prevent anti-work for its employee,
will also cause anti-work for its customer.</p>

<p>It might not be that the entire system is down. 
It is enough that there is some kind of unavailability or error,
that will ask more of the customer than they planned for. 
Restarting apps or devices.
Forms that clear all entries on a single error.
Data that don’t sync properly.
Having to wait or reschedule your task for another time.
And it is not only software that manifests it,
though it is often software involved.
(Or better software could have prevented it.)</p>

<p>Ordered food that only partly show up might not seem like a biggie, 
but it might also cause the anti-work that blows up something really 
important for that individual at that time.</p>

<p>When the anti-work hits your life, instead of your work,
we often lack protective systems. 
The nuclear-family team of two, or one, doesn’t have the redundancy of an IT-department.
If the service you build is of any use, or importance at all, 
it hurts when it fails the user. 
It might only be a paper cut,
but could be one of thousands in total. 
It will probably hit harder for people with less privilege to start with. 
As a system, a society, we should all be more careful with each others time and energy.</p>

<p>Don’t be an anti-work polluter! Take care to build quality software!</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="quality" /><category term="product" /><category term="equity" /><summary type="html"><![CDATA[Anti-work in an organization will spread to its customers. No defect is too small to lower the quality of life for people a bit, and combined it is an unnecessary burden for the often already disadvantaged.]]></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">Westrum in a restroom</title><link href="https://chocolatedrivendevelopment.com/2022/09/21/westrum/" rel="alternate" type="text/html" title="Westrum in a restroom" /><published>2022-09-21T00:00:00+00:00</published><updated>2022-09-21T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2022/09/21/westrum</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2022/09/21/westrum/"><![CDATA[<p>The sociologist Dr. Ron Westrum defined <a href="https://cloud.google.com/architecture/devops/devops-culture-westrum-organizational-culture">three main categories of company cultures</a>:
pathological, bureaucratic and generative.</p>

<p>The first time I heard of Westrum organisational culture I misheard it as
“Restroom Culture”.
I thought it was a way to tell company culture by looking at shared facilities.
It turned into a neat mnemonic, so now I bring you the explanation of the three
organisational cultures of Westrums, using restrooms.
Hopefully, though a bit silly, it will help you remember the real name,
as well as the concept. 
What kind of culture do you work in?</p>

<h2 id="pathological">Pathological</h2>
<p>No one dares to use up the last square of toilet paper. 
That person will be punished and might even be fired.
The storage is locked, some few select have a key. 
If you are friendly with someone who has access to extra toilet paper you might 
get a fresh roll.
But first you have to find out who those people are, and how to suade them. 
No one dares to mention that it might be wasteful to limit access to toilet paper.
The last one who brought up the subject
was first publicly blamed for all restroom related problems and then let go.
Some people bring their own rolls, but in secret,
so that it won’t be taken for critique.</p>

<h2 id="bureaucratic">Bureaucratic</h2>
<p>Toilet paper is refilled Tuesdays and Thursdays. 
If it runs out any other day there is a form to fill out that heed approval from
your bosses boss.
Any suggestion to change this will be ignored.
Employees are not trusted with important things like toilet paper.</p>

<h2 id="generative">Generative</h2>
<p>Toilet paper is stored where everyone has access to it.
If it runs low anyone who notices takes action.
There is also a supply of sanitary products available in all restrooms,
as a result of an employee initiative.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="devops" /><category term="empathy" /><summary type="html"><![CDATA[The Westrum model for company culture distinguishes between pathological, bureaucratic and generative. To remember the model it is presented as ways to deal with a common restroom.]]></summary></entry><entry><title type="html">The &amp;amp; in DevOps</title><link href="https://chocolatedrivendevelopment.com/2022/08/23/and-in-devops/" rel="alternate" type="text/html" title="The &amp;amp; in DevOps" /><published>2022-08-23T00:00:00+00:00</published><updated>2022-08-23T00:00:00+00:00</updated><id>https://chocolatedrivendevelopment.com/2022/08/23/and-in-devops</id><content type="html" xml:base="https://chocolatedrivendevelopment.com/2022/08/23/and-in-devops/"><![CDATA[<p>In the book ‘Thinking in systems’ Donella M. Meadows quotes the Sufi teaching:</p>

<blockquote>
  <p>You think because you understand ‘one’ you must also understand ‘two’,
because one and one make two. 
But you must also understand ‘and’.</p>
</blockquote>

<p>DevOps is Dev and Ops. 
For something to be DevOps the team must do development. 
The same team has to run operations.
In this an invisible ‘&amp;’ gets created between Dev and Ops.
This ‘&amp;’ has value that can not be seperated from it joining Dev and Ops.</p>

<p>Getting unique value from putting responsibility for Dev and Ops in the same team
can be hard to grasp. 
It is creating a new system with improved self organisation and 
evolution capabilities.
This evolution and self organisation might manifest as a demand for new software,
development practises or an interest in cloud services. 
But these are only side effects of the newly created ‘&amp;’.
Don’t mistake a continues integration server for DevOps.</p>

<p>Some want the ‘&amp;’ that this change brings to life 
to be bottled and sold on its own.</p>

<p>We see software marketed as DevOps.
Or a service as DevOps.
“Let us do your DevOps for you.”</p>

<p>Introducing external dependencies, and thereby removing agency for the team,
damages the very ‘&amp;’ it is confused with.</p>

<p>You can’t sell love, company culture, life, ‘rainforestness’
or any other ‘&amp;’ from systems we have around us.</p>

<p>DevOps can only be created by letting one team have responsibility
for dev, ops and everything else that is needed for software to bring value.</p>]]></content><author><name>Ester Daniel Ytterbrink</name></author><category term="devops" /><summary type="html"><![CDATA[Systems thinking helps us understand why DevOps happens in the joining of dev and ops. It can not be bottled and sold separately.]]></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></feed>