<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://www.tripled.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.tripled.io/" rel="alternate" type="text/html" /><updated>2025-07-04T21:19:33+00:00</updated><id>https://www.tripled.io/feed.xml</id><title type="html">Triple D</title><subtitle>Triple D is a Belgian based software company.</subtitle><entry><title type="html">The Evolution of Programming</title><link href="https://www.tripled.io/18/06/2025/Evolution-of-programming-AI/" rel="alternate" type="text/html" title="The Evolution of Programming" /><published>2025-06-18T00:00:00+00:00</published><updated>2025-06-18T00:00:00+00:00</updated><id>https://www.tripled.io/18/06/2025/Evolution-of-programming-AI</id><content type="html" xml:base="https://www.tripled.io/18/06/2025/Evolution-of-programming-AI/"><![CDATA[<h1 id="the-evolution-of-programming-from-assembly-to-ai-driven-development">The Evolution of Programming: From Assembly to AI-Driven Development</h1>

<p>The software development landscape is experiencing a seismic shift. We’re witnessing a transformation as significant as the move from assembly language to high-level programming languages—except this time, we’re transitioning from writing code and compiling it to crafting prompts and sending them to large language models (LLMs).</p>

<p>This evolution feels familiar. The inertia we’re experiencing today mirrors what assembly developers felt when the first compilers emerged. Back then, many questioned whether these new tools could truly replace the precision and control of hand-crafted assembly code. Today, we’re asking similar questions about AI-generated code.</p>

<h2 id="the-foundation-still-matters">The Foundation Still Matters</h2>

<p>What made programming truly powerful wasn’t just the languages or tools—it was the practices we developed around them. These practices didn’t emerge overnight; they evolved as our understanding of software quality and maintainability deepened.</p>

<p>Consider Test-Driven Development (TDD). This practice gave us the safety net we desperately needed, allowing us to refactor with confidence and catch regressions early. Clean code principles made our codebases more readable and maintainable, enabling new team members to contribute effectively without drowning in complexity.</p>

<p>When you combine TDD with clean code practices, something magical happens. You get more than just a safety net—you get living documentation that describes what your application is supposed to do and clear insight into how those features are implemented. This foundation becomes the launchpad for continuous deployment, enabling rapid feedback loops with customers.</p>

<p>But the practices don’t stop there. Once your application is running in production, you need monitoring, reliability engineering, and resilience patterns. As your data grows and your user base expands, you’ll face new architectural challenges that create additional feedback loops. Each practice builds upon the others, creating a snowball effect of quality and reliability.</p>

<h2 id="ai-builds-upon-those-foundations">AI Builds upon those Foundations</h2>

<p>Here’s the crucial insight: <strong>all of these practices are still needed when AI is doing the coding</strong>. There’s no silver bullet embedded in AI-generated solutions that magically solves the fundamental challenges of software development.</p>

<p>AI can write code faster than humans, but it can’t inherently understand your business requirements, your system’s constraints, or the long-term maintainability implications of its decisions. It doesn’t automatically implement proper error handling, logging, monitoring, or security measures unless explicitly guided to do so.</p>

<p>We might need to revise some of our older practices to work effectively with AI, but we’ll need them in some form or another. The core principles of good software development remain unchanged—we’re simply changing the tools we use to implement them.</p>

<h2 id="enhancing-ai-with-good-practices">Enhancing AI with Good Practices</h2>

<p>Interestingly, traditional development practices can actually enhance AI’s effectiveness. Clean code provides richer metadata to your LLM about the current implementation. When your codebase follows consistent patterns and conventions, the AI has better context for generating appropriate solutions.</p>

<p>Your tests become even more valuable in an AI-driven workflow. They provide crystal-clear specifications of what the system should do, giving the AI concrete examples of expected behavior. When prompting an AI to implement new features, start by describing the use case and the tests that should pass. Have the implementation written after establishing these requirements.</p>

<p>This approach might seem like taking the long road, but shortcuts in AI-driven development are just as detrimental as they are in traditional TDD. The temptation to skip the specification phase and jump straight to implementation is strong when AI can generate code so quickly, but this shortcut often leads to solutions that work for the immediate case but fail to consider edge cases, maintainability, or integration with existing systems.</p>

<p>Architectural patterns like Clean Architecture prove their worth even more in the AI era. When your system is properly layered with clear boundaries between business logic, application services, and infrastructure concerns, integrating new AI capabilities becomes remarkably straightforward. Take Model Context Protocol (MCP) connectivity, for example—it’s just another piece of incoming infrastructure that can be quickly implemented at the adapter layer without impacting your core business logic or existing system components. The risk of integration becomes minimal because your architecture naturally isolates changes to specific layers, allowing you to experiment with AI integrations safely and incrementally.</p>

<h2 id="the-path-forward">The Path Forward</h2>

<p>As we embrace AI-assisted development, we shouldn’t abandon the practices that made software development mature and reliable. Instead, we should adapt these practices to work synergistically with AI tools.</p>

<p>The future of programming isn’t about replacing human judgment with AI generation—it’s about augmenting human expertise with AI capabilities while maintaining the disciplined practices that ensure quality, maintainability, and reliability.</p>

<p>Just as compilers didn’t eliminate the need for good software engineering practices but rather enabled us to focus on higher-level concerns, AI coding assistants should free us to concentrate on architecture, business logic, and user experience while handling more of the routine implementation details.</p>

<p>The assembly programmers who embraced compilers and learned to work with higher-level abstractions thrived in the new paradigm. Similarly, the developers who learn to effectively collaborate with AI while maintaining strong engineering practices will define the next era of software development.</p>

<h2 id="the-tools-are-evolving-but-the-fundamentals-of-building-great-software-remain-as-relevant-as-ever">The tools are evolving, but the fundamentals of building great software remain as relevant as ever.</h2>]]></content><author><name>Kris Hofmans</name></author><summary type="html"><![CDATA[From Assembly to AI-Driven Development]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.tripled.io/img/ai-evolution.jpg" /><media:content medium="image" url="https://www.tripled.io/img/ai-evolution.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">My first year at Triple D</title><link href="https://www.tripled.io/26/12/2022/starting-at-tripled/" rel="alternate" type="text/html" title="My first year at Triple D" /><published>2022-12-26T00:00:00+00:00</published><updated>2022-12-26T00:00:00+00:00</updated><id>https://www.tripled.io/26/12/2022/starting-at-tripled</id><content type="html" xml:base="https://www.tripled.io/26/12/2022/starting-at-tripled/"><![CDATA[<h1 id="my-first-year-at-triple-d">My first year at Triple D</h1>

<p>In February 2022 I joined Triple D and as my first year as employee is coming to an end I will use this as an opportunity to tell what it’s like to join and be part of this company.
It has been an amazing first year for me, and I hope everything below will show you why.
I will start by providing some context on where I was professionally before I joined Triple D, what the recruitment process was like and how it’s been so far.</p>

<h2 id="about-me">About me</h2>

<p>I am currently 31 years old, have spent 4 years teaching software development and 3 years actually doing it.
A bit over a year ago I was working at a large service provider.
I already had a starting notion of clean code, TDD, architecture,… 
In the interview for that job, they asked me what I knew about DDD, microservices, and other techniques or technologies that piqued my interest.
I reasoned that if they want to know how knowledgeable I am about these subjects, they must be using them in practice! 
While there was some truth to that, reality fell short of what I had imagined beforehand.
There was the notion that things could and should be done better, but there was never time nor budget to actually make the required changes.
This became increasingly frustrating and eventually led me to look for a new job elsewhere.</p>

<h2 id="triple-d">Triple D</h2>

<p>Triple D was founded by independent contractors who experienced that individually they could not have the desired impact.
They realised that by joining forces it allowed them to reach the high level of support they want to give their clients.
By surrounding themselves with like-minded individuals they could also learn from each other and grow more quickly.</p>

<p>I had found Triple D before when looking for people or companies focussed on software craftsmanship, but then it was in the context of finding speakers for a teaching session at the university college I worked for. 
Now I was looking for a job for myself and immediately thought of Triple D again.
There were two quotes on their homepage that spoke to me:</p>

<blockquote>
  <p>“We” are a group of veteran software engineers with the aim of having a <em>larger, positive impact</em> on the Belgian software industry.</p>
</blockquote>

<blockquote>
  <p>A challenging job well done, that is what we aim for.</p>
</blockquote>

<p>These two quotes perfectly captured what I was looking for: people that do not want to just do their job, they want to do it well <em>and</em> they aim to spread the knowledge they have. 
That second part hit home for me as I was a teacher before and always hoped to retain some teaching aspects in a future job.</p>

<h2 id="applying-at-triple-d">Applying at Triple D</h2>

<p>I emailed them explaining the frustration at my current job, my ambition of being a better developer, and how perfectly Triple D’s mission statement matched that ambition.
I quickly received a reply and an initial online meeting was set up.
There we discussed more in-depth what both myself and Triple D were looking for.
As I had hoped, this was a match, and we scheduled an IRL interview.</p>

<p>This was not a typical interview. 
Me, Guido and Domenique spent an entire day together, evenly split between paired coding sessions and talking.
We went through a code kata and this in itself was already an eye-opening experience.
It quickly became clear that while I knew some things already, there was so much more to learn.
And these people knew exactly those things!
They showed me in a very clear way that they appreciated what I already knew but also pointed me to where the holes in my knowledge were.
During the time not spent coding, we discussed the state of the industry, shared frustrations, what Triple D aims to do about those frustrations, their vision, what my role could be, and much more. 
The relaxed and down-to-earth attitude Guido and Domenique had throughout this day put me at ease and allowed me to show the best version of myself.</p>

<p>They also invited me to one of their Triple Dojo Days.
These are day-long gatherings of like-minded people socializing, discussing and learning from each other.
For me, it was a great opportunity to get to know not only my potential colleagues, but also other people from the community.
For Triple D, it allowed them to see if I was a good cultural fit.</p>

<p class="center-img-text"><img src="/img/posts/starting-at-triple-d/harm-and-sander.jpg" alt="Sander and me during a refactor session at the Triple Dojo Day." width="500px" />
<em>Sander and me during a refactor session at the Triple Dojo Day.</em></p>

<p>A day or two after the interview they provided me with feedback on how they experienced the interview and what they thought of me. 
They liked my attitude and while there was still much I did not know, they saw how motivated I was to learn.
Not much later they made an offer I couldn’t refuse, and we decided on february 1st being my first day working for Triple D.</p>

<h2 id="my-first-month-at-triple-d">My first month at Triple D</h2>

<p>I spent my entire first month at Triple D learning.
Together with Guido, Kris and Doménique I deepened my knowledge of TDD, DDD, (clean) architecture, refactoring, and learned new things such as Event Storming and Domain Storytelling.
We used the <a href="https://leanpub.com/agiletechnicalpracticesdistilled">Agile Technical Practices Distilled</a> book as a guide for most of it, but they provided me with other books such as <a href="https://www.oreilly.com/library/view/domain-driven-design-distilled/9780134434964/">Domain Driven Design Distilled</a> and <a href="https://www.oreilly.com/library/view/implementing-domain-driven-design/9780133039900/">Implementing Domain Driven Design</a>. 
You don’t learn just by reading of course, so all this was supplemented with plenty of time pairing on katas and a larger project.</p>

<p>Having an entire month dedicated to just learning is an amazing thing in and of itself, but having experts on the subject directly available is a great boon on top of that. 
It allowed me to quickly ask for clarification when something wasn’t clear and avoided learning incorrect interpretations of new concepts.</p>

<p class="center-img-text"><img src="/img/posts/starting-at-triple-d/first-day.jpg" alt="My first day" width="500px" />
<em>My first day on the job, with some reading material</em></p>

<h2 id="my-first-client">My first client</h2>

<p>After the initial month of intensive learning, I started at my first client.
Triple D would have liked to place me with a client together with a Triple D colleague but sadly that wasn’t possible.
The client I’m working at is an old client of theirs: a couple of years ago two-three people worked there. 
Triple D knew this client would be a good fit because they are very open to improvements (in contrast with my previous employer).
This means they had a good idea of who was working there, what they were working on, and what the struggles were.</p>

<p>It soon became clear that there were plenty of opportunities to bring my upgraded skills into practice.
Under the guidance of both Triple D and my new colleagues, I was given full support when I saw opportunities for improvement.
This has by now allowed me to take up ownership of multiple small to medium-sized refactors.
I try and do and learn as much as possible by myself, knowing that I can always fall back on the knowledge of my colleagues at Triple D when I reach my current limits.</p>

<h2 id="personal-development">Personal Development</h2>

<p>The text above should already show you how well-supported I’ve been on my learning path.
In addition to the day-to-day support, Triple D has also sent me to <a href="https://dddeurope.com/">DDD Europe</a>, the <a href="https://socratesbe.org/">Socrates Conference</a> and has provided me with plenty of budget to purchase access to other sources of information.</p>

<p>They have met my expectations when it came to helping me reach my full potential, and I’m confident that they will continue to do so.</p>

<h2 id="conclusion">Conclusion</h2>

<p>I realise that most of what I have written can be interpreted as propaganda for my employer.
There’s some similarities with what a new consultant would write a couple of months after signing their contract with your typical run-of-the-mill consultancy company: 
“Everything is great here!”, “The people are amazing!”, “My company car is so shiny!”.</p>

<p>The difference is that Triple D has allowed me to turn my back on all the frustrations I had when working at my previous employer, and start developing at a higher skill level.
I have learned even more than I expected, and am sure I will continue to do so.
I now have the skills to have noticeable impact.
My client seems very happy with my work, and so am I.</p>]]></content><author><name>Harm De Weirdt</name></author><category term="recruitment" /><summary type="html"><![CDATA[A rundown of how I got started at Triple D and how the first year has been.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.tripled.io/img/logo-alt.png" /><media:content medium="image" url="https://www.tripled.io/img/logo-alt.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Vocabulary and Validation</title><link href="https://www.tripled.io/08/10/2022/VocabularyValidation/" rel="alternate" type="text/html" title="Vocabulary and Validation" /><published>2022-10-08T00:00:00+00:00</published><updated>2022-10-08T00:00:00+00:00</updated><id>https://www.tripled.io/08/10/2022/VocabularyValidation</id><content type="html" xml:base="https://www.tripled.io/08/10/2022/VocabularyValidation/"><![CDATA[<h1 id="vocabulary-and-validation">Vocabulary and Validation</h1>

<p>A discussion that I keep encountering over the years is the following: <strong>How and where to handle the validation of your incoming data requests?</strong></p>
<ul>
  <li>Do you validate this data inside your domain model? Or outside your domain model? After all, it is kinda business logic. But do we want the raw data to pollute our domain?</li>
  <li>We also don’t want to have the same logic in different places. Since it is then only a matter of time before it gets out of sync and different logic is applied depending on which entry path we take into our application.</li>
  <li>What to do if it isn’t valid data? Throw exceptions? Return once we encounter the first data error? Thus forcing the client to correct the data entry one by one?</li>
</ul>

<p>In this blog post, I’ll try to convey my approach to the topic, hoping that it has some value for someone.</p>

<h2 id="the-problem">The problem</h2>

<p>For clarification purposes, we will use a simple example. A request/command that is received contains a name, a shoe size, and an amount. These simple data fields each have their restrictions.</p>
<ul>
  <li>The <em>name</em> must be at least 2 characters and a maximum of 100. With no whitespace at the front or the end.</li>
  <li>The <em>shoe size</em> is a fixed set of valid values. Valid values are [27, 28.5, 30, 31.5, 32.5, 33, …, 46, 47, 50, 52, 56]</li>
  <li>The <em>amount</em> must be a discreet positive number. With an upper limit of 1000. If someone is ordering more than 1000 shoes, we need to talk :)</li>
</ul>

<p>So a possible incoming JSON request can look like this:</p>

<figure class="highlight"><pre><code class="language-json" data-lang="json"><span class="p">{</span><span class="w">
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Guido"</span><span class="p">,</span><span class="w">
</span><span class="nl">"shoeSize"</span><span class="p">:</span><span class="w"> </span><span class="s2">"47"</span><span class="p">,</span><span class="w">
</span><span class="nl">"amount"</span><span class="p">:</span><span class="w"> </span><span class="mi">5</span><span class="w">
</span><span class="p">}</span></code></pre></figure>

<p>With the following as possible implementation:</p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="cm">/** The application API **/</span>
<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PlaceOrderAPI</span> <span class="o">{</span>
    <span class="kt">void</span> <span class="nf">placeOrder</span><span class="o">(</span><span class="nc">String</span> <span class="n">name</span><span class="o">,</span> <span class="nc">String</span> <span class="n">size</span><span class="o">,</span> <span class="nc">Integer</span> <span class="n">amount</span><span class="o">)</span>
<span class="o">}</span>


<span class="nd">@RestController</span><span class="o">()</span>
<span class="kd">class</span> <span class="nc">PlaceOrderController</span>
<span class="o">{</span>
    <span class="kd">private</span> <span class="kd">final</span> <span class="nc">PlaceOrderAPI</span> <span class="n">applicationApi</span><span class="o">;</span>

    <span class="nd">@PostMapping</span><span class="o">(</span><span class="s">"/PlaceOrder"</span><span class="o">)</span>
    <span class="nc">String</span> <span class="nf">placeOrder</span><span class="o">(</span><span class="nd">@RequestBody</span> <span class="nc">PlaceOrderRequest</span> <span class="n">request</span><span class="o">)</span>
    <span class="o">{</span>
        <span class="c1">// Do we validate before we invoke the application API?</span>
        <span class="n">applicationApi</span><span class="o">.</span><span class="na">placeOrder</span><span class="o">(</span><span class="n">request</span><span class="o">.</span><span class="na">getName</span><span class="o">(),</span><span class="n">request</span><span class="o">.</span><span class="na">getSize</span><span class="o">(),</span><span class="n">request</span><span class="o">.</span><span class="na">getAmount</span><span class="o">());</span>

        <span class="c1">// or is the implementation of PlaceOrderAPI responsible for this</span>

        <span class="c1">// And how do we capture and report potential validation errors?</span>
        <span class="k">return</span> <span class="n">messages</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>

<span class="c1">// The same questions for a possible CLI adapter</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">ConsoleAdapter</span> <span class="o">{</span>

    <span class="kd">private</span> <span class="kd">final</span> <span class="nc">PlaceOrderAPI</span> <span class="n">applicationApi</span><span class="o">;</span>

    <span class="kd">public</span> <span class="nf">ConsoleAdapter</span><span class="o">(</span><span class="nc">PlaceOrderAPI</span> <span class="n">applicationApi</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">applicationApi</span> <span class="o">=</span> <span class="n">applicationApi</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="nc">String</span> <span class="nf">placeOrder</span><span class="o">(</span><span class="nc">String</span> <span class="n">orderLine</span><span class="o">)</span> <span class="o">{</span>
        <span class="c1">// Do we validate before we invoke the application api?</span>
        <span class="kd">final</span> <span class="nc">String</span><span class="o">[]</span> <span class="n">split</span> <span class="o">=</span> <span class="n">orderLine</span><span class="o">.</span><span class="na">split</span><span class="o">(</span><span class="s">"\\s"</span><span class="o">);</span>
        <span class="kd">final</span> <span class="nc">String</span> <span class="n">name</span> <span class="o">=</span> <span class="n">split</span><span class="o">[</span><span class="mi">0</span><span class="o">];</span>
        <span class="kd">final</span> <span class="nc">Integer</span> <span class="n">amount</span> <span class="o">=</span> <span class="nc">Integer</span><span class="o">.</span><span class="na">parseInt</span><span class="o">(</span><span class="n">split</span><span class="o">[</span><span class="mi">1</span><span class="o">]);</span>
        <span class="kd">final</span> <span class="nc">String</span> <span class="n">size</span> <span class="o">=</span> <span class="n">split</span><span class="o">[</span><span class="mi">1</span><span class="o">];</span>

        <span class="n">applicationApi</span><span class="o">.</span><span class="na">placeOrder</span><span class="o">(</span><span class="n">name</span><span class="o">,</span> <span class="n">size</span><span class="o">,</span> <span class="n">amount</span><span class="o">);</span>

        <span class="c1">// or is the implementation of PlaceOrderAPI responsible for this</span>

        <span class="c1">// And how do we capture and report potential validation errors?</span>
        <span class="k">return</span> <span class="s">"Success"</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span></code></pre></figure>

<p><em>Note that all the code used in this blog post can be found in <a href="https://github.com/tripledio/vocabulary-validation-blog-example">github</a> <sup id="fnref:6" role="doc-noteref"><a href="#fn:6" class="footnote" rel="footnote">1</a></sup></em></p>

<p>The incoming data will be sent through our application. So the question is: Where and how do we validate the data request? Before or after the internal application API? And how to report any validation errors?</p>

<p class="center-img-text"><img src="/img/posts/vocabularyvalidation/validation-problem.jpg" alt="Problem" width="500px" />
Where do we validate the data?</p>

<h2 id="definitions">Definitions</h2>

<p>First, we need to start off with some quick definitions, describing the context and high-level architecture in which we will operate. So let’s start with a high-level drawing.</p>

<p class="center-img-text"><img src="/img/posts/vocabularyvalidation/landscape-architecture.jpg" alt="Landscape" width="500px" />
Example application</p>

<p>Let’s take as a basis a simple application with a hexagonal architecture. This is not necessary the required architecture, the most important part is the separation between the technically implemented public API that accepts for example JSON, and the internal application API that just talks code and has no knowledge of any external formats. So if you have an internal application API that is separate from the public-facing API, the following discussion is applicable. The discussion we will have will revolve around the following components:</p>

<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Definition</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Layer</td>
      <td>A group of modules with a given responsibility</td>
    </tr>
    <tr>
      <td>Module</td>
      <td>A software module. A jar, dll, …</td>
    </tr>
    <tr>
      <td>API Module</td>
      <td>A module containing only contracts and the necessary data structures. This (optional) module serves as a separation between modules, to obtain dependency inversion.</td>
    </tr>
    <tr>
      <td>Ports</td>
      <td>An abstraction/interface that decouples technical implementation concerns from business functionality</td>
    </tr>
    <tr>
      <td>Adapters</td>
      <td>A module that performs a technical translation/action. It implements a port or uses an API module.</td>
    </tr>
    <tr>
      <td>Application</td>
      <td>The application is the whole, of all the different components combined, that make up the application. In the old days, it typically was a single deployable but it doesn’t have to be. And this doesn’t change anything for our story.</td>
    </tr>
    <tr>
      <td>Public application API</td>
      <td>The API that clients use to communicate with us. This is what is available to the outside world. Typically a REST API that can be called by external parties.</td>
    </tr>
    <tr>
      <td>Internal application API</td>
      <td>The internal API module that exposes the functionality that our application offers. This is a pure code API so it can not be exposed directly to the outside world. There is no knowledge of HTTP, Rest, or JSON here. Just plain old code.</td>
    </tr>
    <tr>
      <td>Use cases</td>
      <td>The internal application API is typically implemented by transactional use cases. But those implementation details are hidden by the internal application API.</td>
    </tr>
    <tr>
      <td>Domain model</td>
      <td>Depending on the complexity of your application, there might be a domain model inside that makes it easy to offer the needed functionality. (Note that this has nothing to do with your database model.) But this to is an implementation detail, hidden by the internal application API.</td>
    </tr>
  </tbody>
</table>

<p>To expose the internal API via the public API, we need an adapter. An adapter is just a module that performs a technical translation. It adapts, as the name says, from one format to another. In a hexagonal architecture, the inbound adapters handle the translation of the exposed public API to the internal API. Important is that <strong>we don’t want any business logic inside those adapters</strong> because we want to be able for them to be easily interchangeable. A Rest adapter translates the JSON that arrives in the rest controller to concrete calls that are done on the internal API. A CLI adapter could translate command line-level instructions to invocations on the internal application API. Each will have a different translation, but they will arrive, through the internal Application API in the same application. We can easily represent those components as a more classic layered architecture. Where a layer is just a group of modules that can be categorized together.</p>

<p class="center-img-text"><img src="/img/posts/vocabularyvalidation/layered-arch.jpg" alt="Layered" width="500px" />
The application represented as a classic layered architecture</p>

<h2 id="validation-requirements">Validation requirements</h2>

<p>As mentioned in the beginning there are a couple of requirements we impose on the validation.</p>

<ul>
  <li>1) The validation logic should not be duplicated. If the logic needs to be modified, we want to change it just in one place.</li>
  <li>2) There should be no need to do the validation more than once. The applied validation should not get lost. Once something is validated, this information should not get lost.</li>
  <li>3) The validation should return as much info as possible. If there are 5 violations, please tell them all 5 immediately if possible. No need to force the client to trial and error.</li>
  <li>4) Validating should be part of the normal flow. Normally, validation can have multiple outcomes. No is a normal answer to a question. No need for the code to throw a fit :-). Which is one of the reasons we do not want to use exceptions as part of our normal validation flow. Exceptions are disruptive technically, but they also make for an unclear API.</li>
</ul>

<p class="center-img-text"><img src="/img/posts/vocabularyvalidation/throwing-fit.png" alt="fit" width="200px" />
<em>No need to throw exceptions when there is a validation error</em></p>

<p>To give some more context to these validation requirements I would like to use a real-world metaphor. Which I think also answers the question “where should the validation occur?”</p>

<h2 id="security-guards">Security Guards</h2>

<p>We can look at our application as a very exclusive club, the hottest place in town, where everyone wants to enter. All the cool kids want to spend their Saturday night at our club. Which is great of course. However, this comes with a responsibility. We need to make sure that it is a safe environment for all our clientele. So for people that come in, we need to make sure that</p>

<ul>
  <li>Everyone is at least 18 years old</li>
  <li>No weapons are smuggled inside</li>
  <li>People that are on the blacklist are not allowed to enter</li>
  <li>Music performers should be on the performer list</li>
</ul>

<p>Certain constraints are mandatory by law, so we need to enforce those if we want to stay in business. We also want to provide a good experience for the performing artists as well as for our staff. Everyone should want to party with, perform or work for us. Security is a big part of this. Gambling that the only people who walk through the door are all law-abiding citizens is a recipe for disaster. The more well-known our bar is, the more bad elements it will attract. So how would we go about ensuring those constraints without making it a horrible experience?</p>

<p class="center-img-text"><img src="/img/posts/vocabularyvalidation/place-to-be.jpg" alt="Party" width="800px" />
<em>How to enforce security in our exclusive bar?</em></p>

<p>We will want some security in place that enforces the given constraints. We can easily see we have the same requirements present for a security check as with a data validation:</p>

<p>We want the security check applied when people come in. Once people are inside, everyone wants to be sure that they met the conditions set to enter. It’s not the barman’s job to check for weapons. So no additional checks should be necessary, it is perfectly safe inside. It is not possible to just walk inside.</p>

<p>So this answers the question: [Where does validation need to occur?] Before we cross the internal application API boundary. The API guarantees that everything that crosses it is a well-behaving citizen. No validation should happen in the domain model. Because by then it is too late, the party crashers can already be inside.</p>

<p>This leads us to another question: if there is more than one possible entrance, we need to ensure that the same security rules are applied. If the main entrance checks your identity card, but the side entrance does not, then we can all predict what will happen. So the security guards must all enforce the same rules. This maps on the <em>“validation logic should not be duplicated”</em> requirement.</p>

<p>Once people are vetted and identified as Customer, Personel, or Artist, it would be convenient that the people inside can also quickly discern who’s vetted for what. So when someone goes backstage it is immediately clear if they are allowed there. So once inside, we haven’t lost the context of the checks that were made at the entrance. Once you’ve been checked as a registered performer, inside, you don’t need to prove this again. With we can easily do this by handing out badges where needed so that <em>“the applied validation knowledge should not get lost”</em></p>

<p>Of course, it is also polite that when we refuse people entrance, we let them know why. This maps on the <em>“validation should be part of normal flow”</em> and <em>“validation should return as much info as possible”</em> requirement.</p>

<p>Hopefully, this example gave some context on the why of the requirements we impose on validation. So how does this map to our application?</p>

<h2 id="enter-vocabulary-module">Enter vocabulary module</h2>

<p>Through the security guard metaphor, we determined that we want to perform the validation before we cross the internal application API, which means <strong>the validation should occur in the inbound adapter</strong>. But given that there is possibly more than one inbound adapter, we now have a problem. Because we determined that we don’t want to duplicate the validation logic across the different inbound adapters. So how do we solve this? How to validate the adapters without duplicating the validation logic across the adapters? By introducing <strong>domain primitives</strong> grouped in a <strong>vocabulary module</strong> that can be used by all the inbound adapters.</p>

<p class="center-img-text"><img src="/img/posts/vocabularyvalidation/vocabulary-module.jpg" alt="Vocabulary" width="400px" />
Enter the vocabulary</p>

<p>The rules for the vocabulary module are the following</p>
<ul>
  <li>The vocabulary module only contains <em>immutable, domain primitives</em></li>
  <li>Everyone <em>inside</em> the application can access the vocabulary module</li>
  <li>The contents of the vocabulary module do <em>not get exposed</em> to the outside world.</li>
</ul>

<p>Be very careful not to turn this module into a garbage bin that is used to circumvent the imposed dependency limitations of your application architecture. The vocabulary module should contain only domain primitives. The convenience of having a module that everyone can access is very tempting. We do want the vocabulary module to be easily changeable. The internal language and concepts of our application do not need to leak to the outside world. So do not carelessly expose it to the outside world. If you refactor the Vocabulary in your IDE, no external contract should get broken.</p>

<p class="center-img-text"><img src="/img/posts/vocabularyvalidation/garbage-bin.png" alt="Garbage bin" width="300px" />
A Vocabulary is not a garbage bin</p>

<h4 id="domain-primitives">Domain Primitives</h4>

<p>A well-known pattern, especially in DDD context is <a href="https://www.martinfowler.com/bliki/ValueObject.html">Value object</a> <sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">2</a></sup>.
A value object is an object</p>
<ul>
  <li>that has no separate identity</li>
  <li>models a conceptual whole</li>
  <li>is immutable</li>
  <li>can be compared with others using value equality</li>
</ul>

<p>Domain primitives are a special case of value objects. It is a pattern that was named in the excellent book <a href="https://www.manning.com/books/secure-by-design">Secure by design</a> <sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">3</a></sup>. So let me just quote from there:</p>

<blockquote>
  <p>A value object precise enough in its definition that it, by its mere existence, manifests its validity is called a domain primitive.
Domain primitives are similar to value objects in Domain-Driven Design. Key differences are that we require invariants to exist and they must be enforced at the point of creation. We’re also prohibiting the use of simple language primitives, or generic types (including null), as representations of concepts in the domain model.</p>
</blockquote>

<p>Note that some say that a Value object also has the self-validation property. I follow the original DDD definitions that make the distinction between value objects and domain primitives. If you always let your value objects self-validate: great! Then you are already using domain primitives and your code is more robust for it.</p>

<p>When you are using domain primitives this has the added benefit of avoiding primitives like String and Int in your domain model, avoiding primitive obsession, <sup id="fnref:3" role="doc-noteref"><a href="#fn:3" class="footnote" rel="footnote">4</a></sup> which I will rant about later. So for now, going back to our example declared in the problem statement, we need a domain primitive for Name, Shoe Size, and Amount that enforces the restrictions we imposed upon them.</p>

<p><em>The basic Name primitive</em></p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Name</span> <span class="o">{</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">MAX_LENGTH</span> <span class="o">=</span> <span class="mi">100</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">MIN_LENGTH</span> <span class="o">=</span> <span class="mi">2</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">final</span> <span class="nc">String</span> <span class="n">value</span><span class="o">;</span>

    <span class="kd">private</span> <span class="nf">Name</span><span class="o">(</span><span class="nc">String</span> <span class="n">value</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">value</span> <span class="o">=</span> <span class="n">value</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kd">static</span> <span class="nc">Name</span> <span class="nf">name</span><span class="o">(</span><span class="nc">String</span> <span class="n">value</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">value</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="k">throw</span> <span class="k">new</span> <span class="nc">RuntimeException</span><span class="o">(</span><span class="s">"Name value may not be NULL"</span><span class="o">);</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">value</span><span class="o">.</span><span class="na">isBlank</span><span class="o">())</span> <span class="k">throw</span> <span class="k">new</span> <span class="nc">RuntimeException</span><span class="o">(</span><span class="s">"Name value may not be blank"</span><span class="o">);</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">value</span><span class="o">.</span><span class="na">length</span><span class="o">()</span> <span class="o">&gt;</span> <span class="no">MAX_LENGTH</span><span class="o">)</span> <span class="k">throw</span> <span class="k">new</span> <span class="nc">RuntimeException</span><span class="o">(</span><span class="s">"Name length may not be larger than "</span> <span class="o">+</span> <span class="no">MAX_LENGTH</span> <span class="o">+</span> <span class="s">". ["</span> <span class="o">+</span> <span class="n">value</span><span class="o">.</span><span class="na">substring</span><span class="o">(</span><span class="mi">0</span><span class="o">,</span> <span class="mi">20</span><span class="o">)</span> <span class="o">+</span> <span class="s">"]"</span><span class="o">);</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">value</span><span class="o">.</span><span class="na">length</span><span class="o">()</span> <span class="o">&lt;</span> <span class="no">MIN_LENGTH</span><span class="o">)</span> <span class="k">throw</span> <span class="k">new</span> <span class="nc">RuntimeException</span><span class="o">(</span><span class="s">"Name length may not be smaller than "</span> <span class="o">+</span> <span class="no">MIN_LENGTH</span> <span class="o">+</span> <span class="s">". ["</span> <span class="o">+</span> <span class="n">value</span> <span class="o">+</span> <span class="s">"]"</span><span class="o">);</span>
        <span class="k">return</span> <span class="k">new</span> <span class="nf">Name</span><span class="o">(</span><span class="n">value</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="c1">//toString, equals and hashcode omitted for brevity</span>
<span class="o">}</span></code></pre></figure>

<p><em>The basic Amount primitive</em></p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Amount</span> <span class="o">{</span>
    <span class="kd">private</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">MAX</span> <span class="o">=</span> <span class="mi">1000</span><span class="o">;</span>
    <span class="kd">private</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">MIN</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="nc">Amount</span> <span class="no">ZERO</span> <span class="o">=</span> <span class="nc">Amount</span><span class="o">.</span><span class="na">mandatoryAmount</span><span class="o">(</span><span class="no">MIN</span><span class="o">);</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="nc">Amount</span> <span class="no">ONE</span> <span class="o">=</span> <span class="nc">Amount</span><span class="o">.</span><span class="na">mandatoryAmount</span><span class="o">(</span><span class="mi">1</span><span class="o">);</span>

    <span class="kd">public</span> <span class="kt">int</span> <span class="n">value</span><span class="o">;</span>

    <span class="kd">private</span> <span class="nf">Amount</span><span class="o">(</span><span class="kt">int</span> <span class="n">value</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">value</span> <span class="o">=</span> <span class="n">value</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kd">static</span> <span class="nc">Amount</span> <span class="nf">amount</span><span class="o">(</span><span class="kt">int</span> <span class="n">value</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">isAmountTooSmall</span><span class="o">(</span><span class="n">value</span><span class="o">))</span> <span class="k">throw</span> <span class="k">new</span> <span class="nc">RuntimeException</span><span class="o">(</span><span class="s">"The amount ["</span> <span class="o">+</span> <span class="n">value</span> <span class="o">+</span> <span class="s">"] must be a larger than "</span> <span class="o">+</span> <span class="no">MIN</span><span class="o">);</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">isAmountTooLarge</span><span class="o">(</span><span class="n">value</span><span class="o">))</span> <span class="k">throw</span> <span class="k">new</span> <span class="nc">RuntimeException</span><span class="o">(</span><span class="s">"The amount ["</span> <span class="o">+</span> <span class="n">value</span> <span class="o">+</span> <span class="s">"] must be smaller than "</span> <span class="o">+</span> <span class="no">MAX</span><span class="o">);</span>
        <span class="k">return</span> <span class="k">new</span> <span class="nf">Amount</span><span class="o">(</span><span class="n">value</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="kd">private</span> <span class="kd">static</span> <span class="kt">boolean</span> <span class="nf">isAmountTooSmall</span><span class="o">(</span><span class="kt">int</span> <span class="n">value</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">value</span> <span class="o">&lt;</span> <span class="no">MIN</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">private</span> <span class="kd">static</span> <span class="kt">boolean</span> <span class="nf">isAmountTooLarge</span><span class="o">(</span><span class="kt">int</span> <span class="n">value</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">value</span> <span class="o">&gt;=</span> <span class="no">MAX</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="c1">//toString, equals and hashcode omitted for brevity</span>
<span class="o">}</span></code></pre></figure>

<p><em>The basic ShoeSize primitive</em></p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">enum</span> <span class="nc">ShoeSize</span> <span class="o">{</span>

    <span class="no">SIZE_TWENTY_SEVEN</span><span class="o">,</span>
    <span class="no">SIZE_TWENTY_EIGHT</span><span class="o">,</span>
    <span class="no">SIZE_THIRTY</span><span class="o">,</span>
    <span class="no">SIZE_THIRTY_ONE_HALF</span><span class="o">,</span>
    <span class="no">SIZE_THIRTY_TWO_HALF</span><span class="o">,</span>
    <span class="no">SIZE_FIFTY</span><span class="o">,</span>
    <span class="no">SIZE_FIFTY_TWO</span><span class="o">,</span>
    <span class="no">SIZE_FIFTY_SIX</span><span class="o">;</span>

    <span class="kd">static</span> <span class="nc">ShoeSize</span> <span class="nf">shoeSize</span><span class="o">(</span><span class="kt">int</span> <span class="n">value</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">switch</span> <span class="o">(</span><span class="n">value</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">case</span> <span class="mi">27</span><span class="o">:</span>
            <span class="k">return</span> <span class="no">SIZE_TWENTY_SEVEN</span><span class="o">;</span>
        <span class="k">case</span> <span class="mi">28</span><span class="o">:</span>
            <span class="k">return</span> <span class="no">SIZE_TWENTY_EIGHT</span><span class="o">;</span>
        <span class="k">case</span> <span class="mi">315</span><span class="o">:</span>
            <span class="k">return</span> <span class="no">SIZE_THIRTY_ONE_HALF</span><span class="o">;</span>
        <span class="c1">//...</span>
        <span class="k">case</span> <span class="mi">50</span><span class="o">:</span>
            <span class="k">return</span> <span class="no">SIZE_FIFTY</span><span class="o">;</span>
        <span class="k">default</span><span class="o">:</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nf">RuntimeException</span><span class="o">(</span><span class="s">"Unknown shoe Size "</span> <span class="o">+</span> <span class="n">value</span><span class="o">);</span>
        <span class="o">}</span>
    <span class="o">}</span>
<span class="o">}</span></code></pre></figure>

<p><em>Code with basic domain primitives be found in <a href="https://github.com/tripledio/vocabulary-validation-blog-example/tree/vocabulary/code/vocabulary/src/main/java/io/tripled/example/vocabulary">github</a> <sup id="fnref:6:1" role="doc-noteref"><a href="#fn:6" class="footnote" rel="footnote">1</a></sup></em></p>

<p>Note that in the intermediate examples above we will still throw exceptions, not bothering yet with validations. But it is already impossible to create incorrect domain primitives. They are immutable, correct, and have an actual meaning relevant to the business. By using these domain primitives in our application API, we have already met validation requirements 1 and 2.</p>

<h2 id="the-domain-primitives-as-a-basic-building-block-of-the-internal-api">The domain primitives as a basic building block of the internal API</h2>

<p>Through our security guard example, we’ve determined that the validation should occur <em>before</em> the internal application API. Inside the adapters. So if multiple adapters make use of the internal application API, then they all map their incoming data request to the application API by making use of the shared domain primitives. Once inside the application, no validation should be necessary anymore. By inserting the validation logic inside our domain primitives, which themselves reside in the vocabulary module that can be used by all the different adapters, there is no need to duplicate that logic anymore. It is encapsulated in the domain primitives and all the adapters can access them. So we’ve obtained the first validation requirement: <em>“The validation logic should not be duplicated”</em>.</p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="cm">/** The application api **/</span>
<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PlaceOrderAPI</span> <span class="o">{</span>
    <span class="kt">void</span> <span class="nf">placeOrder</span><span class="o">(</span><span class="nc">Name</span> <span class="n">name</span><span class="o">,</span> <span class="nc">ShoeSize</span> <span class="n">size</span><span class="o">,</span> <span class="nc">Amount</span> <span class="n">amount</span><span class="o">)</span>
<span class="o">}</span>


<span class="nd">@RestController</span><span class="o">()</span>
<span class="kd">class</span> <span class="nc">PlaceOrderController</span>
<span class="o">{</span>
    <span class="kd">private</span> <span class="kd">final</span> <span class="nc">PlaceOrderAPI</span> <span class="n">applicationApi</span><span class="o">;</span>

    <span class="nd">@PostMapping</span><span class="o">(</span><span class="s">"/PlaceOrder"</span><span class="o">)</span>
    <span class="nc">String</span> <span class="nf">placeOrder</span><span class="o">(</span><span class="nd">@RequestBody</span> <span class="nc">PlaceOrderRequest</span> <span class="n">request</span><span class="o">)</span>
    <span class="o">{</span>
        <span class="c1">// We map the data request, specific to this adapter, to our internal, well-known domain primitives.</span>
        <span class="kd">final</span> <span class="nc">Name</span> <span class="n">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">(</span><span class="n">request</span><span class="o">.</span><span class="na">getName</span><span class="o">());</span>
        <span class="kd">final</span> <span class="nc">ShoeSize</span> <span class="n">shoeSize</span> <span class="o">=</span> <span class="n">shoeSize</span><span class="o">(</span><span class="n">request</span><span class="o">.</span><span class="na">getSize</span><span class="o">());</span>
        <span class="kd">final</span> <span class="nc">Amount</span> <span class="n">amount</span> <span class="o">=</span> <span class="n">amount</span><span class="o">(</span><span class="n">request</span><span class="o">.</span><span class="na">getAmountName</span><span class="o">());</span>

        <span class="c1">//We invoke the API, which is blissfully unaware of any concrete adapter details</span>
        <span class="n">applicationApi</span><span class="o">.</span><span class="na">placeOrder</span><span class="o">(</span><span class="n">name</span><span class="o">,</span><span class="n">shoeSize</span><span class="o">,</span><span class="n">amount</span><span class="o">);</span>

        <span class="c1">// Let's answer this questions next..</span>
        <span class="k">return</span> <span class="n">messages</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span></code></pre></figure>

<p><em>Code can be found in <a href="https://github.com/tripledio/vocabulary-validation-blog-example/blob/vocabulary/code/infra/frontend-adapters/rest-adapter/src/main/java/io/tripled/example/rest/RestController.java">github</a> <sup id="fnref:6:2" role="doc-noteref"><a href="#fn:6" class="footnote" rel="footnote">1</a></sup></em></p>

<p>If we use only domain primitives in our API and inside our application domain we will have fulfilled the second validation requirement [There should be no need to do the validation more than once]. So by using the domain primitives as the basic building block of the internal API, and performing the mapping in the inbound adapters, we have met the first two of our <a href="#validation-requirements">validation requirements</a></p>

<h4 id="primitive-obsession">Primitive obsession</h4>

<p>Using no data primitives directly is however a controversial statement. I always encounter a lot of resistance when I advocate having no primitives like <em>String</em> passed on through an application. Which has always baffled me. Because if we have not validated before the data came in, it could contain all kinds of garbage. Like a 300-page XML for example. And if we have done some validation on the data primitives but then pass it on still as a data primitive, we have lost the knowledge of that validation. The main safeguard for knowing what is in a data primitive is the variable name. So that variable name should always be correct, clear and hopefully never misinterpreted.</p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="cm">/** Some function inside our application**/</span>
<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">SomeInterface</span> <span class="o">{</span>
    <span class="c1">//Trust me. I'm a valid businessId and email because I say so.</span>
    <span class="kt">void</span> <span class="nf">createInvoice</span><span class="o">(</span><span class="nc">String</span> <span class="n">businessId</span><span class="o">,</span> <span class="nc">String</span> <span class="n">email</span><span class="o">)</span>
<span class="o">}</span>

<span class="kd">public</span> <span class="kd">class</span> <span class="nc">SomeClass</span> <span class="o">{</span>
    <span class="c1">//Let's hope the context doesn't get lost along the way</span>
    <span class="kt">void</span> <span class="nf">createInvoice</span><span class="o">(</span><span class="nc">String</span> <span class="n">b</span><span class="o">,</span> <span class="nc">String</span> <span class="n">m</span><span class="o">)</span>
<span class="o">}</span></code></pre></figure>

<p>This <strong>primitive obsession</strong> <sup id="fnref:3:1" role="doc-noteref"><a href="#fn:3" class="footnote" rel="footnote">4</a></sup>, when developing in a type-based system has always seemed very contradictory to me. For the “cost” of a simple type, we could make our code so much safer, hard to misuse, and hard to misinterpret. But the mental cost of creating an extra class seems to outweigh those benefits. Luckily this is my blog post, so let me make my final stance one more time: No Strings in my domain! ;D</p>

<p class="center-img-text"><img src="/img/posts/vocabularyvalidation/caveman.png" alt="Primitive obsesion" width="400px" />
Please no primitive obsession</p>

<h4 id="compose-domain-primitives">Compose domain primitives</h4>

<p>Note that in a real application, you will want to combine the necessary domain primitives in a higher-level type. Which can have its own validation and constraints. But it relies on the domain primitives as its core building blocks.</p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">PlaceOrderCommand</span><span class="o">{</span>
    <span class="kd">public</span> <span class="kd">final</span> <span class="nc">Name</span> <span class="n">name</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">final</span> <span class="nc">ShoeSize</span> <span class="n">shoeSize</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">final</span> <span class="nc">Amount</span> <span class="n">amount</span><span class="o">;</span>

    <span class="c1">//details omitted for clarity</span>
<span class="o">}</span>

<span class="cm">/** The application api **/</span>
<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PlaceOrderAPI</span> <span class="o">{</span>
    <span class="kt">void</span> <span class="nf">placeOrder</span><span class="o">(</span><span class="nc">PlaceOrderCommand</span> <span class="n">command</span><span class="o">)</span>
<span class="o">}</span></code></pre></figure>

<h2 id="validation">Validation</h2>

<p>Using the basic domain primitives in our adapters we have met the first two of our <a href="#validation-requirements">validation requirements</a>. So how will we tackle the other two requirements? Namely, letting <em>“The validation return as much info as possible”</em> and making <em>“Validating a part of the normal flow”</em>?</p>

<h4 id="notification-pattern">Notification pattern</h4>

<p>To gather all the validation information in one go we can make use of the <a href="https://www.martinfowler.com/eaaDev/Notification.html">notification Pattern</a><sup id="fnref:4" role="doc-noteref"><a href="#fn:4" class="footnote" rel="footnote">5</a></sup> to gather all the validation messages. In my code example, we will introduce a new class ValidationResult that will capture all the validation messages.</p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="c1">// The validation result as an implementation of the notification pattern</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">ValidationResult</span> <span class="o">{</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="nc">ValidationResult</span> <span class="no">EMPTY</span> <span class="o">=</span> <span class="nc">ValidationResult</span><span class="o">.</span><span class="na">builder</span><span class="o">().</span><span class="na">build</span><span class="o">();</span>
    <span class="kd">public</span> <span class="kd">final</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">&gt;</span> <span class="n">messages</span><span class="o">;</span>
    
    <span class="kd">private</span> <span class="nf">ValidationResult</span><span class="o">(</span><span class="nc">Builder</span> <span class="n">b</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">messages</span> <span class="o">=</span> <span class="nc">Collections</span><span class="o">.</span><span class="na">unmodifiableList</span><span class="o">(</span><span class="n">b</span><span class="o">.</span><span class="na">messages</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kd">static</span> <span class="nc">Builder</span> <span class="nf">builder</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="k">new</span> <span class="nf">Builder</span><span class="o">();</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kd">static</span> <span class="nc">ValidationResult</span> <span class="nf">create</span><span class="o">(</span><span class="nc">String</span> <span class="n">singleMessage</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="nc">ValidationResult</span><span class="o">.</span><span class="na">builder</span><span class="o">().</span><span class="na">addMessage</span><span class="o">(</span><span class="n">singleMessage</span><span class="o">).</span><span class="na">build</span><span class="o">();</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="nc">ValidationResult</span> <span class="nf">merge</span><span class="o">(</span><span class="nc">ValidationResult</span> <span class="n">other</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="nc">ValidationResult</span><span class="o">.</span><span class="na">builder</span><span class="o">().</span><span class="na">addMessages</span><span class="o">(</span><span class="k">this</span><span class="o">.</span><span class="na">messages</span><span class="o">).</span><span class="na">addMessages</span><span class="o">(</span><span class="n">other</span><span class="o">.</span><span class="na">messages</span><span class="o">).</span><span class="na">build</span><span class="o">();</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">isEmpty</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">messages</span><span class="o">.</span><span class="na">isEmpty</span><span class="o">();</span>
    <span class="o">}</span>

    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="nc">String</span> <span class="nf">toString</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="s">"ValidationResult{"</span> <span class="o">+</span> <span class="n">messages</span> <span class="o">+</span> <span class="sc">'}'</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">class</span> <span class="nc">Builder</span> <span class="o">{</span>
        <span class="c1">//Basic builder pattern impl</span>
    <span class="o">}</span>
<span class="o">}</span></code></pre></figure>

<p>Note that using Strings in the ValidationResult here is ok. We are creating the Strings ourselves, placing them in a primitive with a clear purpose which is to serve as information for the outside world. A validation result should not be crossing the application API inward.</p>

<h4 id="validation-part-of-normal-flow">Validation part of normal flow</h4>

<p>We want to make validation part of a normal flow. So that the creation of a domain primitive can have two answers. The requested domain primitive or the reasons why the domain primitive could not be created. As explained before this should not be exceptional but part of the normal flow. It is the same principle/pattern as in <a href="https://www.youtube.com/watch?v=fYo3LN9Vf_M">Railway oriented programming</a>. <sup id="fnref:5" role="doc-noteref"><a href="#fn:5" class="footnote" rel="footnote">6</a></sup></p>

<p>So let’s introduce a second class, FactoryResult, which contains the result of the factory or the reasons why it could not be created.</p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">FactoryResult</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="o">{</span>
    <span class="kd">private</span> <span class="kd">final</span> <span class="no">T</span> <span class="n">createdInstance</span><span class="o">;</span>
    <span class="kd">private</span> <span class="kd">final</span> <span class="nc">ValidationResult</span> <span class="n">validationResult</span><span class="o">;</span>

    <span class="kd">private</span> <span class="nf">FactoryResult</span><span class="o">(</span><span class="no">T</span> <span class="n">createdInstance</span><span class="o">,</span> <span class="nc">ValidationResult</span> <span class="n">validationResult</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">createdInstance</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">&amp;&amp;</span> <span class="n">validationResult</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="k">throw</span> <span class="k">new</span> <span class="nc">RuntimeException</span><span class="o">(</span><span class="s">"A factoryResult may not have a createdInstance and errorMessages"</span><span class="o">);</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">createdInstance</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">&amp;&amp;</span> <span class="o">((</span><span class="n">validationResult</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">||</span> <span class="n">validationResult</span><span class="o">.</span><span class="na">isEmpty</span><span class="o">()))</span>
        <span class="k">throw</span> <span class="k">new</span> <span class="nf">RuntimeException</span><span class="o">(</span><span class="s">"A factoryResult must have a createdInstance or errorMessages"</span><span class="o">);</span>
        <span class="k">this</span><span class="o">.</span><span class="na">createdInstance</span> <span class="o">=</span> <span class="n">createdInstance</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">validationResult</span> <span class="o">=</span> <span class="o">(</span><span class="n">validationResult</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">?</span> <span class="nc">ValidationResult</span><span class="o">.</span><span class="na">EMPTY</span> <span class="o">:</span> <span class="n">validationResult</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kd">static</span> <span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nc">FactoryResult</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nf">success</span><span class="o">(</span><span class="no">T</span> <span class="n">t</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="k">new</span> <span class="nc">FactoryResult</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;(</span><span class="n">t</span><span class="o">,</span> <span class="kc">null</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kd">static</span> <span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nc">FactoryResult</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nf">failure</span><span class="o">(</span><span class="nc">List</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">&gt;</span> <span class="n">errorMessages</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="k">new</span> <span class="nc">FactoryResult</span><span class="o">&lt;&gt;(</span><span class="kc">null</span><span class="o">,</span> <span class="nc">ValidationResult</span><span class="o">.</span><span class="na">builder</span><span class="o">().</span><span class="na">addMessages</span><span class="o">(</span><span class="n">errorMessages</span><span class="o">).</span><span class="na">build</span><span class="o">());</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kd">static</span> <span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nc">FactoryResult</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nf">failure</span><span class="o">(</span><span class="nc">String</span><span class="o">...</span> <span class="n">errorMessages</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="k">new</span> <span class="nc">FactoryResult</span><span class="o">&lt;&gt;(</span><span class="kc">null</span><span class="o">,</span> <span class="nc">ValidationResult</span><span class="o">.</span><span class="na">builder</span><span class="o">().</span><span class="na">addMessages</span><span class="o">(</span><span class="nc">Arrays</span><span class="o">.</span><span class="na">stream</span><span class="o">(</span><span class="n">errorMessages</span><span class="o">).</span><span class="na">toList</span><span class="o">()).</span><span class="na">build</span><span class="o">());</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kd">static</span> <span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nc">FactoryResult</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nf">createIfValid</span><span class="o">(</span><span class="nc">ValidationResult</span> <span class="n">validationResult</span><span class="o">,</span> <span class="nc">Supplier</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="n">factoryMethod</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">validationResult</span><span class="o">.</span><span class="na">isEmpty</span><span class="o">())</span> <span class="k">return</span> <span class="nc">FactoryResult</span><span class="o">.</span><span class="na">success</span><span class="o">(</span><span class="n">factoryMethod</span><span class="o">.</span><span class="na">get</span><span class="o">());</span>
        <span class="k">else</span> <span class="k">return</span> <span class="nc">FactoryResult</span><span class="o">.</span><span class="na">failure</span><span class="o">(</span><span class="n">validationResult</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kd">static</span> <span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nc">FactoryResult</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nf">failure</span><span class="o">(</span><span class="nc">ValidationResult</span> <span class="n">validationResult</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="nf">failure</span><span class="o">(</span><span class="n">validationResult</span><span class="o">.</span><span class="na">messages</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">onSuccess</span><span class="o">(</span><span class="nc">Consumer</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="n">happyPathHandler</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">hasValidInstance</span><span class="o">())</span> <span class="o">{</span>
            <span class="n">happyPathHandler</span><span class="o">.</span><span class="na">accept</span><span class="o">(</span><span class="n">createdInstance</span><span class="o">);</span>
        <span class="o">}</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">onFailure</span><span class="o">(</span><span class="nc">Consumer</span><span class="o">&lt;</span><span class="nc">List</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">&gt;&gt;</span> <span class="n">errorHandler</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">hasNoValidInstance</span><span class="o">())</span> <span class="o">{</span>
            <span class="n">errorHandler</span><span class="o">.</span><span class="na">accept</span><span class="o">(</span><span class="n">validationResult</span><span class="o">.</span><span class="na">messages</span><span class="o">);</span>
        <span class="o">}</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="no">T</span> <span class="nf">mandatoryValidInstance</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">hasNoValidInstance</span><span class="o">())</span> <span class="k">throw</span> <span class="k">new</span> <span class="nc">RuntimeException</span><span class="o">(</span><span class="s">"A valid instance was expected but there were unexpected errors "</span> <span class="o">+</span> <span class="n">validationResult</span><span class="o">.</span><span class="na">toString</span><span class="o">());</span>
        <span class="k">else</span> <span class="k">return</span> <span class="n">createdInstance</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="nc">ValidationResult</span> <span class="nf">validationResult</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">validationResult</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">private</span> <span class="kt">boolean</span> <span class="nf">hasValidInstance</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">createdInstance</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">private</span> <span class="kt">boolean</span> <span class="nf">hasNoValidInstance</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">createdInstance</span> <span class="o">==</span> <span class="kc">null</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span></code></pre></figure>

<p>We will place these two classes also in the Vocabulary module. ( Details on <a href="https://github.com/tripledio/vocabulary-validation-blog-example/tree/validation/code/vocabulary/src/main/java/io/tripled/example/vocabulary">github</a> ) You could argue that they are not part of the domain but are a mini-validation framework. But since they are two immutable classes that are part of our normal flow I consider them domain primitives and part of the Vocabulary.</p>

<h4 id="domain-primitives-with-validation">Domain Primitives with Validation</h4>

<p>Using the ValidationResult and FactoryResult, we can modify our earlier domain primitives so they no longer throw exceptions on a validation violation.</p>

<p><em>The Name primitive with validation</em></p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Name</span> <span class="o">{</span>
    
    <span class="c1">//...</span>
    
    <span class="kd">private</span> <span class="nf">Name</span><span class="o">(</span><span class="nc">String</span> <span class="n">value</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">value</span> <span class="o">=</span> <span class="n">value</span><span class="o">;</span>
    <span class="o">}</span>
    
    <span class="c1">//No exceptions were thrown during the making of this domain primitive</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="nc">FactoryResult</span><span class="o">&lt;</span><span class="nc">Name</span><span class="o">&gt;</span> <span class="nf">name</span><span class="o">(</span><span class="nc">String</span> <span class="n">value</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">value</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="k">return</span> <span class="n">failure</span><span class="o">(</span><span class="s">"Name value may not be NULL"</span><span class="o">);</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">value</span><span class="o">.</span><span class="na">isBlank</span><span class="o">())</span> <span class="k">return</span> <span class="n">failure</span><span class="o">(</span><span class="s">"Name value may not be blank"</span><span class="o">);</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">value</span><span class="o">.</span><span class="na">length</span><span class="o">()</span> <span class="o">&gt;</span> <span class="no">MAX_LENGTH</span><span class="o">)</span> <span class="k">return</span> <span class="n">failure</span><span class="o">(</span><span class="s">"Name length may not be larger than "</span> <span class="o">+</span> <span class="no">MAX_LENGTH</span> <span class="o">+</span> <span class="s">". ["</span> <span class="o">+</span> <span class="n">value</span><span class="o">.</span><span class="na">substring</span><span class="o">(</span><span class="mi">0</span><span class="o">,</span> <span class="mi">20</span><span class="o">)</span> <span class="o">+</span> <span class="s">"]"</span><span class="o">);</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">value</span><span class="o">.</span><span class="na">length</span><span class="o">()</span> <span class="o">&lt;</span> <span class="no">MIN_LENGTH</span><span class="o">)</span> <span class="k">return</span> <span class="n">failure</span><span class="o">(</span><span class="s">"Name length may not be smaller than "</span> <span class="o">+</span> <span class="no">MIN_LENGTH</span> <span class="o">+</span> <span class="s">". ["</span> <span class="o">+</span> <span class="n">value</span> <span class="o">+</span> <span class="s">"]"</span><span class="o">);</span>
        <span class="k">return</span> <span class="nf">success</span><span class="o">(</span><span class="k">new</span> <span class="nc">Name</span><span class="o">(</span><span class="n">value</span><span class="o">));</span>
    <span class="o">}</span>

    <span class="c1">//...   </span>
<span class="o">}</span></code></pre></figure>

<p><em>The Amount primitive with validation</em></p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Amount</span> <span class="o">{</span>
    <span class="c1">//...</span>

    <span class="kd">public</span> <span class="kt">int</span> <span class="n">value</span><span class="o">;</span>

    <span class="kd">private</span> <span class="nf">Amount</span><span class="o">(</span><span class="kt">int</span> <span class="n">value</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">value</span> <span class="o">=</span> <span class="n">value</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="c1">//No exceptions were thrown during the making of this domain primitive</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="nc">FactoryResult</span><span class="o">&lt;</span><span class="nc">Amount</span><span class="o">&gt;</span> <span class="nf">amount</span><span class="o">(</span><span class="kt">int</span> <span class="n">amount</span><span class="o">)</span> <span class="o">{</span>
        <span class="kd">final</span> <span class="nc">ValidationResult</span> <span class="n">validationResult</span> <span class="o">=</span> <span class="n">validate</span><span class="o">(</span><span class="n">amount</span><span class="o">);</span>
        <span class="k">return</span> <span class="nc">FactoryResult</span><span class="o">.</span><span class="na">createIfValid</span><span class="o">(</span><span class="n">validationResult</span><span class="o">,</span> <span class="o">()</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nc">Amount</span><span class="o">(</span><span class="n">amount</span><span class="o">));</span>
    <span class="o">}</span>

    <span class="c1">//...</span>
<span class="o">}</span></code></pre></figure>

<p><em>The ShoeSize primitive with validation</em></p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">enum</span> <span class="nc">ShoeSize</span> <span class="o">{</span>
    
    <span class="no">SIZE_TWENTY_SEVEN</span><span class="o">,</span>
    <span class="no">SIZE_TWENTY_EIGHT</span><span class="o">,</span>
    <span class="no">SIZE_THIRTY</span><span class="o">,</span>
    <span class="no">SIZE_THIRTY_ONE_HALF</span><span class="o">,</span>
    <span class="no">SIZE_THIRTY_TWO_HALF</span><span class="o">,</span>
    <span class="no">SIZE_FIFTY</span><span class="o">,</span>
    <span class="no">SIZE_FIFTY_TWO</span><span class="o">,</span>
    <span class="no">SIZE_FIFTY_SIX</span><span class="o">;</span>
    
    <span class="c1">//No exceptions were thrown during the making of this domain primitive</span>
    <span class="kd">static</span> <span class="nc">FactoryResult</span><span class="o">&lt;</span><span class="nc">ShoeSize</span><span class="o">&gt;</span> <span class="nf">create</span><span class="o">(</span><span class="kt">int</span> <span class="n">value</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">switch</span> <span class="o">(</span><span class="n">value</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">case</span> <span class="mi">27</span><span class="o">:</span>
        <span class="k">return</span> <span class="nc">FactoryResult</span><span class="o">.</span><span class="na">success</span><span class="o">(</span><span class="no">SIZE_TWENTY_SEVEN</span><span class="o">);</span>
        <span class="k">case</span> <span class="mi">28</span><span class="o">:</span>
        <span class="k">return</span> <span class="nc">FactoryResult</span><span class="o">.</span><span class="na">success</span><span class="o">(</span><span class="no">SIZE_TWENTY_EIGHT</span><span class="o">);</span>
        <span class="k">case</span> <span class="mi">315</span><span class="o">:</span>
        <span class="k">return</span> <span class="nc">FactoryResult</span><span class="o">.</span><span class="na">success</span><span class="o">(</span><span class="no">SIZE_THIRTY_ONE_HALF</span><span class="o">);</span>
        <span class="c1">//...</span>
        <span class="k">case</span> <span class="mi">50</span><span class="o">:</span>
        <span class="k">return</span> <span class="nc">FactoryResult</span><span class="o">.</span><span class="na">success</span><span class="o">(</span><span class="no">SIZE_FIFTY</span><span class="o">);</span>
        <span class="k">default</span><span class="o">:</span>
        <span class="k">return</span> <span class="nc">FactoryResult</span><span class="o">.</span><span class="na">failure</span><span class="o">(</span><span class="s">"Unknown shoe Size "</span> <span class="o">+</span> <span class="n">value</span><span class="o">);</span>
    <span class="o">}</span>
<span class="o">}</span></code></pre></figure>

<h2 id="putting-it-all-together">Putting it all together</h2>

<p>Now that the domain primitives in our shared Vocabulary module are well-behaved and return a proper response, no matter the outcome of the creation request, all the incoming adapters can map their incoming data requests to the internal application API. Which is constructed from domain primitives. In practice this looks like this:</p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">RestController</span> <span class="o">{</span>

    <span class="kd">private</span> <span class="kd">final</span> <span class="nc">PlaceOrderAPI</span> <span class="n">applicationApi</span><span class="o">;</span>

    <span class="kd">public</span> <span class="nf">RestController</span><span class="o">(</span><span class="nc">PlaceOrderAPI</span> <span class="n">applicationApi</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">applicationApi</span> <span class="o">=</span> <span class="n">applicationApi</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="nd">@PostMapping</span><span class="o">(</span><span class="s">"/PlaceOrder"</span><span class="o">)</span>
    <span class="nc">String</span> <span class="nf">placeOrder</span><span class="o">(</span> <span class="nd">@RequestBody</span> <span class="nc">PlaceOrderRequest</span> <span class="n">request</span><span class="o">)</span> <span class="o">{</span>
        <span class="c1">// We map the data request, specific to this adapter, to our internal, well-known domain primitives.</span>
        <span class="c1">// For simplicity we perform the mapping directly in the controller</span>
        <span class="c1">// For more complex cases, it would be better to extract the mapping logic to a separate mapper class</span>
        
        <span class="kd">final</span> <span class="nc">FactoryResult</span><span class="o">&lt;</span><span class="nc">Name</span><span class="o">&gt;</span> <span class="n">name</span> <span class="o">=</span> <span class="nc">Name</span><span class="o">.</span><span class="na">name</span><span class="o">(</span><span class="n">request</span><span class="o">.</span><span class="na">getName</span><span class="o">());</span>
        <span class="kd">final</span> <span class="nc">FactoryResult</span><span class="o">&lt;</span><span class="nc">ShoeSize</span><span class="o">&gt;</span> <span class="n">shoeSize</span> <span class="o">=</span> <span class="nc">ShoeSize</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="n">request</span><span class="o">.</span><span class="na">getSize</span><span class="o">());</span>
        <span class="kd">final</span> <span class="nc">FactoryResult</span><span class="o">&lt;</span><span class="nc">Amount</span><span class="o">&gt;</span> <span class="n">amount</span> <span class="o">=</span> <span class="nc">Amount</span><span class="o">.</span><span class="na">amount</span><span class="o">(</span><span class="n">request</span><span class="o">.</span><span class="na">getAmount</span><span class="o">());</span>
        
        <span class="kd">final</span> <span class="nc">ValidationResult</span> <span class="n">validationResult</span> <span class="o">=</span> <span class="n">name</span><span class="o">.</span><span class="na">validationResult</span><span class="o">().</span><span class="na">merge</span><span class="o">(</span><span class="n">shoeSize</span><span class="o">.</span><span class="na">validationResult</span><span class="o">()).</span><span class="na">merge</span><span class="o">(</span><span class="n">amount</span><span class="o">.</span><span class="na">validationResult</span><span class="o">());</span>
        
        <span class="k">if</span> <span class="o">(</span><span class="n">validationResult</span><span class="o">.</span><span class="na">isEmpty</span><span class="o">())</span> <span class="o">{</span>        
            <span class="c1">//We invoke the api, who is blissfully unaware of any concrete adapter details</span>
            <span class="n">applicationApi</span><span class="o">.</span><span class="na">placeOrder</span><span class="o">(</span>
                <span class="n">name</span><span class="o">.</span><span class="na">mandatoryValidInstance</span><span class="o">(),</span>
                <span class="n">shoeSize</span><span class="o">.</span><span class="na">mandatoryValidInstance</span><span class="o">(),</span>
                <span class="n">amount</span><span class="o">.</span><span class="na">mandatoryValidInstance</span><span class="o">());</span>
            <span class="k">return</span> <span class="s">"Success"</span><span class="o">;</span>
        <span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
            <span class="k">return</span> <span class="n">validationResult</span><span class="o">.</span><span class="na">toString</span><span class="o">();</span>
        <span class="o">}</span>
    <span class="o">}</span>
<span class="o">}</span></code></pre></figure>

<p>Now we have met all of our initially imposed <a href="#validation-requirements">validation requirements</a>. No exceptions are thrown and all the necessary information is available in one go. And we have an expressive Vocabulary and application-api on top of it.</p>

<h2 id="a-little-bit-of-refactoring">A little bit of refactoring</h2>

<p>The code above was kept as is for clarity. But of course, we want to refactor it a bit more. Extracting the mapping logic outside the adapters, placing the arguments from the API together in a composite… After a bit of refactoring it could look as simple as this:</p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">RestController</span> <span class="o">{</span>

    <span class="kd">private</span> <span class="kd">final</span> <span class="nc">PlaceOrderAPI</span> <span class="n">applicationApi</span><span class="o">;</span>

    <span class="kd">public</span> <span class="nf">RestController</span><span class="o">(</span><span class="nc">PlaceOrderAPI</span> <span class="n">applicationApi</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">applicationApi</span> <span class="o">=</span> <span class="n">applicationApi</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="nd">@PostMapping</span><span class="o">(</span><span class="s">"/PlaceOrder"</span><span class="o">)</span>
    <span class="nc">String</span> <span class="nf">placeOrder</span><span class="o">(</span> <span class="nd">@RequestBody</span> <span class="nc">PlaceOrderRequest</span> <span class="n">request</span><span class="o">)</span> <span class="o">{</span>
        <span class="kd">final</span> <span class="nc">FactoryResult</span><span class="o">&lt;</span><span class="nc">PlaceOrderCommand</span><span class="o">&gt;</span> <span class="n">result</span> <span class="o">=</span> <span class="nc">PlaceOrderMapper</span><span class="o">.</span><span class="na">mapRequestToCommand</span><span class="o">(</span><span class="n">request</span><span class="o">);</span>
        <span class="k">return</span> <span class="n">result</span><span class="o">.</span><span class="na">process</span><span class="o">(</span><span class="k">this</span><span class="o">::</span><span class="n">placeOrder</span><span class="o">,</span> <span class="k">this</span><span class="o">::</span><span class="n">validationErrorsToMessage</span><span class="o">);</span>
    <span class="o">}</span>


    <span class="kd">private</span> <span class="nc">String</span> <span class="nf">placeOrder</span><span class="o">(</span><span class="nc">PlaceOrderCommand</span> <span class="n">command</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">applicationApi</span><span class="o">.</span><span class="na">placeOrder</span><span class="o">(</span><span class="n">command</span><span class="o">);</span>
        <span class="k">return</span> <span class="s">"Success"</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">private</span> <span class="nc">String</span> <span class="nf">validationErrorsToMessage</span><span class="o">(</span><span class="nc">ValidationResult</span> <span class="n">x</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">x</span><span class="o">.</span><span class="na">messages</span><span class="o">.</span><span class="na">toString</span><span class="o">();</span>
    <span class="o">}</span>
<span class="o">}</span>

<span class="c1">//The mapping logic is moved to separate mapper</span>
<span class="kd">final</span> <span class="kd">class</span> <span class="nc">PlaceOrderMapper</span> <span class="o">{</span>
     
    <span class="c1">//...</span>

    <span class="kd">static</span> <span class="nc">FactoryResult</span><span class="o">&lt;</span><span class="nc">PlaceOrderCommand</span><span class="o">&gt;</span> <span class="nf">mapRequestToCommand</span><span class="o">(</span><span class="nc">PlaceOrderRequest</span> <span class="n">request</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="nc">PlaceOrderCommand</span><span class="o">.</span><span class="na">newFactoryResultBuilder</span><span class="o">()</span>
                <span class="o">.</span><span class="na">withShoeSize</span><span class="o">(</span><span class="nc">ShoeSize</span><span class="o">.</span><span class="na">shoeSize</span><span class="o">(</span><span class="n">request</span><span class="o">.</span><span class="na">getSize</span><span class="o">()))</span>
                <span class="o">.</span><span class="na">withName</span><span class="o">(</span><span class="nc">Name</span><span class="o">.</span><span class="na">name</span><span class="o">(</span><span class="n">request</span><span class="o">.</span><span class="na">getName</span><span class="o">()))</span>
                <span class="o">.</span><span class="na">withAmount</span><span class="o">(</span><span class="nc">Amount</span><span class="o">.</span><span class="na">amount</span><span class="o">(</span><span class="n">request</span><span class="o">.</span><span class="na">getAmount</span><span class="o">()))</span>
                <span class="o">.</span><span class="na">build</span><span class="o">();</span>
    <span class="o">}</span>


<span class="o">}</span></code></pre></figure>

<p>The Console controller would look similar with the mapping logic extracted:</p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">ConsoleAdapter</span> <span class="o">{</span>

    <span class="kd">private</span> <span class="kd">final</span> <span class="nc">PlaceOrderAPI</span> <span class="n">applicationApi</span><span class="o">;</span>

    <span class="kd">public</span> <span class="nf">ConsoleAdapter</span><span class="o">(</span><span class="nc">PlaceOrderAPI</span> <span class="n">applicationApi</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">applicationApi</span> <span class="o">=</span> <span class="n">applicationApi</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="nc">String</span> <span class="nf">placeOrder</span><span class="o">(</span><span class="nc">String</span> <span class="n">orderLine</span><span class="o">)</span> <span class="o">{</span>
        <span class="kd">final</span> <span class="nc">FactoryResult</span><span class="o">&lt;</span><span class="nc">PlaceOrderCommand</span><span class="o">&gt;</span> <span class="n">result</span> <span class="o">=</span> <span class="nc">PlaceOrderParser</span><span class="o">.</span><span class="na">parsePlaceOrderCommand</span><span class="o">(</span><span class="n">orderLine</span><span class="o">);</span>
        <span class="k">return</span> <span class="n">result</span><span class="o">.</span><span class="na">process</span><span class="o">(</span><span class="k">this</span><span class="o">::</span><span class="n">placeOrder</span><span class="o">,</span> <span class="k">this</span><span class="o">::</span><span class="n">validationErrorsToMessage</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="kd">private</span> <span class="nc">String</span> <span class="nf">validationErrorsToMessage</span><span class="o">(</span><span class="nc">ValidationResult</span> <span class="n">x</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">x</span><span class="o">.</span><span class="na">messages</span><span class="o">.</span><span class="na">toString</span><span class="o">();</span>
    <span class="o">}</span>

    <span class="kd">private</span> <span class="nc">String</span> <span class="nf">placeOrder</span><span class="o">(</span><span class="nc">PlaceOrderCommand</span> <span class="n">command</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">applicationApi</span><span class="o">.</span><span class="na">placeOrder</span><span class="o">(</span><span class="n">command</span><span class="o">);</span>
        <span class="k">return</span> <span class="s">"Success"</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>

<span class="kd">final</span> <span class="kd">class</span> <span class="nc">PlaceOrderParser</span> <span class="o">{</span>
    <span class="c1">//..</span>
    
    <span class="kd">static</span> <span class="nc">FactoryResult</span><span class="o">&lt;</span><span class="nc">PlaceOrderCommand</span><span class="o">&gt;</span> <span class="nf">parsePlaceOrderCommand</span><span class="o">(</span><span class="nc">String</span> <span class="n">orderLine</span><span class="o">)</span> <span class="o">{</span>
            <span class="kd">final</span> <span class="nc">String</span><span class="o">[]</span> <span class="n">split</span> <span class="o">=</span> <span class="n">orderLine</span><span class="o">.</span><span class="na">split</span><span class="o">(</span><span class="s">"\\s"</span><span class="o">);</span>
            <span class="k">if</span> <span class="o">(</span><span class="n">split</span><span class="o">.</span><span class="na">length</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="o">)</span> <span class="k">return</span> <span class="nc">FactoryResult</span><span class="o">.</span><span class="na">failure</span><span class="o">(</span><span class="s">"Unable to parse command. Expected three arguments"</span><span class="o">);</span>

            <span class="k">return</span> <span class="nc">PlaceOrderCommand</span><span class="o">.</span><span class="na">newFactoryResultBuilder</span><span class="o">()</span>
                    <span class="o">.</span><span class="na">withAmount</span><span class="o">(</span><span class="nc">Amount</span><span class="o">.</span><span class="na">amount</span><span class="o">(</span><span class="n">split</span><span class="o">[</span><span class="mi">2</span><span class="o">]))</span>
                    <span class="o">.</span><span class="na">withName</span><span class="o">(</span><span class="nc">Name</span><span class="o">.</span><span class="na">name</span><span class="o">(</span><span class="n">split</span><span class="o">[</span><span class="mi">0</span><span class="o">]))</span>
                    <span class="o">.</span><span class="na">withShoeSize</span><span class="o">(</span><span class="nc">ShoeSize</span><span class="o">.</span><span class="na">shoeSize</span><span class="o">(</span><span class="n">split</span><span class="o">[</span><span class="mi">1</span><span class="o">]))</span>
                    <span class="o">.</span><span class="na">build</span><span class="o">();</span>
    <span class="o">}</span>
<span class="o">}</span></code></pre></figure>

<p>The adapters are only responsible for translating their own specific format to the common application-api and back. They contain no business logic and validation messages are part of the normal flow.</p>

<h2 id="conclusion">Conclusion</h2>

<p>In this post, I have tried to make the case that by being more explicit in our internal API, and by using domain primitives instead of primitive data types, we not only make our code more expressive but harder to misuse. We also gain a well-secured, well-behaving application that is more resilient to bugs and harder to misuse by its clients.</p>

<p>I have taken the purest, most strict approach as how I handle this problem. As always, this is my opinion and in practice there are some nuances and gradations that one could apply. But we most definitely should get over this <a href="https://blog.ploeh.dk/2015/01/19/from-primitive-obsession-to-domain-modelling/">Primitive obsession</a> thing :-)</p>

<p><strong>References</strong></p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:6" role="doc-endnote">
      <p><em><a href="https://github.com/tripledio/vocabulary-validation-blog-example">Github</a></em> <a href="#fnref:6" class="reversefootnote" role="doc-backlink">&#8617;</a> <a href="#fnref:6:1" class="reversefootnote" role="doc-backlink">&#8617;<sup>2</sup></a> <a href="#fnref:6:2" class="reversefootnote" role="doc-backlink">&#8617;<sup>3</sup></a></p>
    </li>
    <li id="fn:1" role="doc-endnote">
      <p><em><a href="https://www.martinfowler.com/bliki/ValueObject.html">Value object</a></em> <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2" role="doc-endnote">
      <p><em><a href="https://www.manning.com/books/secure-by-design">Secure by design</a></em> <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:3" role="doc-endnote">
      <p><em><a href="https://blog.ploeh.dk/2015/01/19/from-primitive-obsession-to-domain-modelling/">Primitive obsession</a></em> <a href="#fnref:3" class="reversefootnote" role="doc-backlink">&#8617;</a> <a href="#fnref:3:1" class="reversefootnote" role="doc-backlink">&#8617;<sup>2</sup></a></p>
    </li>
    <li id="fn:4" role="doc-endnote">
      <p><em><a href="https://www.martinfowler.com/eaaDev/Notification.html">Notification Pattern</a></em> <a href="#fnref:4" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:5" role="doc-endnote">
      <p><em><a href="https://www.youtube.com/watch?v=fYo3LN9Vf_M">Railway oriented programming</a></em> <a href="#fnref:5" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Guido Dechamps</name></author><category term="validation," /><category term="security" /><summary type="html"><![CDATA[How Vocabulary and Validation work together]]></summary></entry><entry><title type="html">Socrates BE 2022 Un-conference</title><link href="https://www.tripled.io/10/07/2022/Socrates22/" rel="alternate" type="text/html" title="Socrates BE 2022 Un-conference" /><published>2022-07-10T00:00:00+00:00</published><updated>2022-07-10T00:00:00+00:00</updated><id>https://www.tripled.io/10/07/2022/Socrates22</id><content type="html" xml:base="https://www.tripled.io/10/07/2022/Socrates22/"><![CDATA[<h1 id="socrates-be-2022">SoCraTes BE 2022</h1>

<p>A lazy sunny Sunday evening. I just got back refreshed from the <a href="https://socratesbe.org">SoCraTes BE 2022 unconference</a> and decided to share the positive vibes I obtained.</p>

<h2 id="what-is-it">What is it?</h2>

<p>For those of you who don’t know, SoCraTes BE is the Belgian Software Crafters community that
organizes regular <a href="https://www.meetup.com/socratesbe/">meetups</a> at several locations throughout Belgium (Kortrijk, Gent, Leuven…).
The <a href="https://en.wikipedia.org/wiki/Unconference">unconference</a> that took place this weekend was a two-day event
where Software Crafters got together to sharpen their skills and have a good time.</p>

<h2 id="the-conference">The conference</h2>

<p>This year, because of Covid, the conference was held during the summer period, which meant the weather was lovely.
There were 45 attendees in total, including the entire Triple D team. Sadly some usual suspects were unable to attend because of the holiday season.
There were some first-timers and some old-timers, some young and some people with… more experience (ahem).
Since there was no school(Belgian schools are closed in July and August), some people brought their families along, giving the whole conference a real vacation vibe. The next generation of Triple D’ers enjoyed it, although that might have had something to do with the ice cream.</p>

<p><img src="/img/posts/socrates22/welcome.jpeg" alt="Welcome" width="500px" /></p>

<p>Most people arrived Thursday evening at around 18:00. Several arrived earlier, others much later. But, as is in the spirit of
the unconference, there are no rigid, fixed timings, so the conference started on the terras with a La Chouffe in the
evening sun. Greeting old friends and meeting new friends. Catching up after this whole Covid thing. At 20:00, we went to
dinner, and at 22:30, we got together for a short, practical introduction. After which, there was more socializing.</p>

<p>Friday morning at 9-ish (the “time-ish” is a running joke since we hardly ever start on time), despite Erik (our fantastic facilitator!) being up and about at 9:00 sharp, we kicked off the unconference with a general
introduction where Erik explained the spirit and flow to everyone. I was already preparing a code repo for a
session I wanted to do in the bar. But obviously, I was present when we started the marketplace, so I could present a couple of
topics I wanted to tackle. At 11:00, we finished the agenda for the first day, and the conference was in full swing.</p>

<p><img src="/img/posts/socrates22/group1.jpg" alt="Group" width="500px" /></p>

<p><img src="/img/posts/socrates22/group2.jpg" alt="Group" width="500px" /></p>

<h2 id="the-sessions">The sessions</h2>

<p>There were too many interesting sessions and topics to discuss them all here. But I’ll give a quick summary of the
sessions I attended.</p>

<p><img src="/img/posts/socrates22/marketplace1.jpg" alt="marketplace" width="500px" /></p>

<ul>
  <li>Humans in natural state good or evil?</li>
</ul>

<p>A session where the host of the session was unable to attend because he got caught up in another session. And that’s ok.
An interesting discussion still took place. <em>Whoever shows up are the right people.</em></p>

<ul>
  <li>Let’s implement Git</li>
</ul>

<p>A cool session hosted by <a href="https://twitter.com/michelgrootjans">Michel</a> where the group used ensemble programming to implement Git from scratch.
Very instructive.</p>

<ul>
  <li>Let’s BDD poker</li>
</ul>

<p>A session where we mobbed on implementing poker in Kotlin starting from BDD scenarios. Not everyone
knew Kotlin, but that’s just one more learning experience that did not hold us back. Mobbing is an excellent
technique for this. The main exciting discussion here was on the level of detail that tended to creep in the BDD scenarios and
what should or shouldn’t be moved to a unit test.</p>

<p><img src="/img/posts/socrates22/poker.jpg" alt="poker" width="500px" /></p>

<ul>
  <li>Team Topologies applied</li>
</ul>

<p>A session from <a href="https://twitter.com/TimSchraepen">Tim</a> where we discussed the ideas of the Team Topologies book and how
to apply them. A fascinating viewpoint from <a href="https://www.linkedin.com/in/bnathyuw/">Mathew</a> for me was</p>

<blockquote>
  <p>When the level of required communication is greater than the level of actual communication. You can choose to
communicate more. But this only scales so far before it just all becomes distracting noise. Or you can lower the amount
of communication required. This can be done by organizing the teams so that minimal cross-team communication is needed.</p>
</blockquote>

<ul>
  <li>Mob programming the hard parts</li>
</ul>

<p>This session was proposed by myself because I was interested in people’s practical problems when utilizing Mob programming. The group shared some of their experiences, and I shared some of mine.
My key takeaway is this: Senior people can easily forget how much knowledge they have accumulated and how intimidating it can be for a junior to join a group of impatient seniors. Also, when people are stressed, their brain stops working.</p>

<ul>
  <li>Why you should become an IT-manager</li>
</ul>

<p>A session that we held in the open air. As it was a software conference, I was pleasantly surprised that more
than 20 people showed up for a session on management. And we had a lively and thought-provoking discussion.</p>

<p>One of the best quotes from that discussion I’ll shamelessly steal is:</p>

<blockquote>
  <p>As a developer, you have quick feedback from your code. As a manager, everything takes much longer, and it goes slower.
But the impact you can have, the change you can bring about as a manager can be more significant than you can accomplish as a lone developer.</p>
</blockquote>

<p>These were just some of the sessions people hosted during those two days. But the important part for me is that, at
an unconference, I’m as free as a bird (the law of freedom as Erik calls it). I walk in and out of different sessions. Sometimes I decided to attend no
session. Instead, do a little coding, take a walk or chat with others.</p>

<h2 id="the-evenings">The evenings</h2>

<p>After dinner, the group returned to the venue for some lightning talks, board games and football with the kids in the evenings. When the kids went to bed, there was the traditional whiskey tasting available, which paired well with the board games :-)</p>

<h2 id="the-end">The end</h2>

<p>We had breakfast together on Sunday morning, not fully awake due to late-night gaming followed by some discussions.
After that, we had to say goodbye, and everyone went home. Batteries fully charged :)</p>

<h2 id="some-pictures">Some pictures</h2>

<p class="center-img-text"><img src="/img/posts/socrates22/3dprinter.jpeg" alt="3dP" width="500px" />
<em>Some people brought their own, self-printed 3d printer</em></p>

<p class="center-img-text"><img src="/img/posts/socrates22/flow.jpg" alt="flow" width="500px" />
<em>Discussing flow and estimates</em></p>

<p class="center-img-text"><img src="/img/posts/socrates22/outside.jpg" alt="outside" width="500px" />
<em>The great weather allowed for outside discussions</em></p>

<p class="center-img-text"><img src="/img/posts/socrates22/toxicpair.jpg" alt="toxicpai" width="500px" />
<em>Pair programming with a “toxic” pair</em></p>

<h2 id="close-at-heart">Close at heart</h2>

<p>The SoCraTes BE community and its conference lie close to our hearts. The idea of Triple D originated in one of the first conferences.
Over the years, we were able to work together with several of the community members. We are proud to be a sponsor and loved helping organize this great event.</p>]]></content><author><name>Guido Dechamps</name></author><category term="socrates" /><summary type="html"><![CDATA[A short report on the Belgian SoCraTes unconference 2022]]></summary></entry><entry><title type="html">Six tips for successful ensemble programming</title><link href="https://www.tripled.io/05/10/2021/Ensemble-programming/" rel="alternate" type="text/html" title="Six tips for successful ensemble programming" /><published>2021-10-05T00:00:00+00:00</published><updated>2021-10-05T00:00:00+00:00</updated><id>https://www.tripled.io/05/10/2021/Ensemble-programming</id><content type="html" xml:base="https://www.tripled.io/05/10/2021/Ensemble-programming/"><![CDATA[<h1 id="six-tips-for-successful-ensemble-programming">Six tips for successful ensemble programming</h1>
<p>Ensemble programming… what an experience! We’ve been doing it for six months and found lots of positive things but also a few frustrating things. That’s why we would like to give a couple of practical tips to avoid them. They may sound small or trivial, but they made a world of difference for us.</p>

<h3 id="make-the-handover-a-non-event">Make the handover a non-event</h3>
<p>Switching roles happens a lot throughout the day, so it’s important to make it go as smooth as possible.</p>

<p>In the beginning we used a tool like <a href="http://mobster.cc">mobster</a>, which forces you to stop and switch roles. This tool is very useful to remind you to switch roles, but we found it way too intrusive because every time the mobster screen pop’s up it interrupts the current task. We realised that every time this happened we lost a few minutes switching roles, then lost a few minutes to pick up where we left, and more than often this interrupt resulted in switching to off-topic banter making us lose our train of thought completely.</p>

<p>At some point we started using <a href="https://mob.sh">mob.sh</a>, a CLI tool which helped us smoothen the handover. One command and the next driver can continue. This made the hand-over itself a lot faster, however, there was still an interrupt. This made us think about setting up a procedure to make the handover a disciplined non-event which does not interrupt the flow.</p>

<p>We settled on using mob.sh and agreed on using The following procedure:</p>
<ul>
  <li>the driver does a “mob next”</li>
  <li>the navigator (who becomes the next driver) takes over the screen sharing</li>
  <li>the navigator does a “mob start”</li>
  <li>the next navigator restarts the timer.</li>
</ul>

<p>All of this happens without saying anything about this routine. If the mob is having a discussion, the discussion continues during this procedure. If the driver was typing, they finish their line, and switches to a terminal to type “mob next” so that everyone can see this and do their part of the procedure.</p>

<p>It’s important to have a procedure that works for you, we settled on the above because it works for us. You should run a few experiments and come up with your own. The important part is that it can be done silently, without interrupting the flow.</p>

<h3 id="experiment-with-short-cycle-times">Experiment with short cycle times</h3>
<p>Focus is an important aspect of ensemble programming. Keeping a group of people focused on one thing is hard, especially for the people who are not driving or navigating. The urge to quickly do something else is high. This is especially true for remote sessions where everyone is behind their pc. The best way for us to avoid this, was to shorten the cycle time. Initially we started with sessions of 30 minutes. for a 4-person team this meant that you would be driving or navigating once every 2 hours, it also means that 1 hour out of 2 you had to fight to not get distracted too much.</p>

<p>After a while we realised that by shortening the cycle times we increased our focus a lot. We managed to shorten the period to 10 minutes, and even tried 5. Of course, this only works if your handovers are running smooth and without any interruptions, so make sure you fix that before tweaking your timer.</p>

<h3 id="everyone-uses-their-own-setup">Everyone uses their own setup</h3>
<p>Ask any developer which IDE is the best, and you will get different answers. Same goes for keyboard shortcuts, operating systems, cli utilities etc. Stop debating about it, embrace it. Let every developer work on their own machine, using their own tools.</p>

<p>Using git to do the code handover has the advantage that you can easily switch laptops too, so do that instead of passing along the keyboard.</p>

<h3 id="always-respect-the-timer-no-matter-the-state-of-the-code">Always respect the timer, no matter the state of the code</h3>
<p>One of the hardest parts about ensemble programming is letting go of the keyboard. Somehow, you always have the urge to quickly finish that small little thing. The problem with this is that once the timer has passed, nothing stops you from staying on the keyboard for hours. You would think that someone from the team will step in and mention it, but in reality everyone is focused on the task and we all lose track of time.</p>

<p>To avoid this, make sure that the timer goes of on all laptops, not just one and force the driver to stop immediately and start the handover proces. Again, make sure the hand-over runs smoothly without interrupts, otherwise this could get painful.</p>

<h3 id="less-discussions---show-me-the-code">Less discussions -&gt; show me the code!</h3>
<p>When a design choice has to be made, and the team finds itself in disagreement, propose to work out multiple solutions so that they can be compared. It’s always easier to reason about something which is right in front of you rather than something hypothetically. Most of the time, it will be pretty obvious wich solution works best.</p>

<p>The hard thing about doing this is to make sure you work out the proposals far enough so that you can form a conclusion. On some occasions it was hard when switching navigators during this process especially when the navigator turns out to be a proponent of the current solution. To avoid this, let the person who came up with the proposal drive the implementation, it will avoid a lot of miscommunication.</p>

<h3 id="do-retrospectives-every-day">Do retrospectives every day!</h3>
<p>Maybe this one does not have that much to do with ensemble programming, but do retrospectives often, especially when starting out. This allows every team member to drive the process towards something they feel comfortable with.</p>

<p>In the beginning we did short 15 min retrospectives at the end of the day. This allowed us to talk about some of the issues we where facing immediately and try experiments daily to optimise our way of working.</p>

<h2 id="summary">Summary</h2>
<p>For me the main takeaway after six months of ensemble programming is that you should avoid interruptions in the flow as much as possible. Another takeaway is that ensemble programming requires <a href="/12/09/2019/communication-as-a-skill/">good communication skills</a> from the participants. Retrospectives are meant to improve the process but also to provide feedback to each other.</p>

<p>Hope this helps and have fun mobbing!</p>]]></content><author><name>Domenique Tilleuil</name></author><category term="mob" /><category term="programming," /><category term="ensemble" /><category term="programming" /><summary type="html"><![CDATA[Ensemble (or mob) programming is a technique used by XP developers to improve a teams productivity and knowledge by working closely together. This post provides a few tips that we learned after doing ensemble programming for about 6 months.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.tripled.io/img/posts/ensemble-programming/spotlight-mobile_1x.jpg" /><media:content medium="image" url="https://www.tripled.io/img/posts/ensemble-programming/spotlight-mobile_1x.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Working with different environments</title><link href="https://www.tripled.io/14/02/2021/working-with-different-envs/" rel="alternate" type="text/html" title="Working with different environments" /><published>2021-02-14T00:00:00+00:00</published><updated>2021-02-14T00:00:00+00:00</updated><id>https://www.tripled.io/14/02/2021/working-with-different-envs</id><content type="html" xml:base="https://www.tripled.io/14/02/2021/working-with-different-envs/"><![CDATA[<p>Today, most software engineers will have to work with different environments. These could be environments from separate companies, own testing environments, or the typical examples in one company: development, QA, production.</p>

<p>All these different environments bring some hassles and dangers because we often need to switch between these to check certain things and on rare occasions, modify them.
I’m saying on “rare occasions” because modifications should preferably happen through some pipeline and not from a developer’s machine.
As a rule, we want to avoid manual interventions as much as possible. Because almost every ITer knows a story of accidental deletes in environments. 
Let it be deleting secrets on the wrong <a href="https://kubernetes.io/">Kubernetes</a> cluster or <a href="https://www.Terraform.io/">Terraform</a> destroy.
Of course, this never happens deliberately, possibly because of a lack of sleep or some distraction.</p>

<p>So with this in mind, and the incentive for continuous improvements, I set out to find a possible solution.
This post will describe what I found to make handling multiple environments easier.</p>

<h2 id="direnv">Direnv</h2>

<p><a href="https://Direnv.net/">Direnv</a> is a shell extension for Unix like operating systems that allows you to load and unload environment variables based on your current directory.
This functionality sounds kind of dull right? But it can be quite powerful. Since the industry is pushing towards <strong>infrastructure as code</strong>, this is a perfect fit.
If the infrastructure is code, there should also be a git repository containing that code and a folder that we can use together with Direnv.</p>

<h3 id="use-cases">Use cases</h3>

<h4 id="referencing-environments">Referencing environments</h4>

<p>Let’s say you are using Terraform. Then you will probably have a directory for every environment.
Whenever you run <code class="language-plaintext highlighter-rouge">terraform apply</code> in one of these folders, Terraform will apply its state changes to the correct environment.
However, whenever you want to validate anything, like a deployment on Kubernetes or an S3 bucket on AWS, you still have to target the right environment.
Well, remember what I said earlier about loading environment variables per folder? Here is where Direnv comes into play. 
We will use Direnv so when we enter a folder, Direnv automatically loads the env variables bound to that folder. You can configure most CLI tools with environment variables, e.g. <code class="language-plaintext highlighter-rouge">KUBECONFIG, AWS_PROFILE</code>, … Now we can leverage this to point our CLI tools to the right environment automatically.</p>

<p>You can also leverage Direnv to build and deploy applications with <a href="https://www.heroku.com/">Heroku</a>. There you also need to specify certain environment variables to check or deploy applications.
The Heroku token is unique per application, so you could easily make Direnv work with every Heroku repository by setting <code class="language-plaintext highlighter-rouge">HEROKU_API_KEY</code>.</p>

<p>Even when you are not using a tool like Terraform or Heroku, it’s still likely to have a git repository that contains some config files or scripts for specific environments. Or you could make sure that the code repositories developers work in always point to the development environment.</p>

<h4 id="sharing">Sharing</h4>
<p>You can check in the Direnv configuration into source control, so it gets shared with other team members. Then not everyone needs to configure it themselves, and new team members can use it easily. The security implications are low since the file will not be allowed to execute once someone has changed it.</p>

<h3 id="how">How</h3>

<p>You can find instructions on how to install Direnv on their website <a href="https://Direnv.net/docs/installation.html">here</a>.</p>

<p>For mac, it is straightforward if you have <a href="https://brew.sh/">homebrew</a>. Just run <code class="language-plaintext highlighter-rouge">brew install Direnv</code> and then add <code class="language-plaintext highlighter-rouge">eval "$(Direnv hook zsh)"</code> to your <code class="language-plaintext highlighter-rouge">~/.zshrc file</code> or <code class="language-plaintext highlighter-rouge">eval "$(Direnv hook bash)"</code> to your ~/.bashrc file and source it or restart your shell.</p>

<p>Now you’re ready to start using it! In the directory where you want Direnv to control the environment variables, you need to create a <code class="language-plaintext highlighter-rouge">.envrc</code> file. Below you can find an example of a <code class="language-plaintext highlighter-rouge">.envrc</code> file.</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">KUBECONFIG</span><span class="o">=</span>~/.kube/development_config
<span class="nb">export </span><span class="nv">AWS_DEFAULT_REGION</span><span class="o">=</span>eu-central-1
<span class="nb">export </span><span class="nv">AWS_PROFILE</span><span class="o">=</span>development
</code></pre></div></div>

<p><em>example <code class="language-plaintext highlighter-rouge">.envrc</code> file</em></p>

<p>This file will point <code class="language-plaintext highlighter-rouge">kubectl</code> to the development cluster and <code class="language-plaintext highlighter-rouge">aws</code> to the development profile together with the <code class="language-plaintext highlighter-rouge">eu-central-1</code> region.
Since executing this file could be potentially harmful, you need to allow Direnv to run it with <code class="language-plaintext highlighter-rouge">Direnv allow</code> you will have to repeat this every time you make changes to the file in another editor. The way Direnv knows that a file is changed is because of a hash it keeps.
Another way to change the file contents is with <code class="language-plaintext highlighter-rouge">Direnv edit</code> then you won’t need to reallow the file.</p>

<p>I referenced in the <strong>use-cases</strong> that you could put the configuration file into source control. The fact that you need to reallow the file whenever someone made changes is what makes it secure.</p>

<p>Now, whenever you enter the folder, it will print the following:</p>

<p><img src="/img/posts/environments/entering.png" alt="entering folder" /></p>

<p>and when leaving it:</p>

<p><img src="/img/posts/environments/leaving.png" alt="leaving folder" /></p>

<p>After the <code class="language-plaintext highlighter-rouge">.envrc</code> file unloads, any overridden environment variables will restore themselves.</p>

<p>Now, if the file has changed and it is no longer allowed, then Direnv will print the following message if you enter the folder:</p>

<p><img src="/img/posts/environments/blocked.png" alt="blocked" /></p>

<h2 id="conclusion">Conclusion</h2>

<p>You can use Direnv to efficiently couple the <strong>infrastructure as code</strong> folders with their respective environments to make fewer mistakes. Or make sure that your code repositories point to the correct <strong>development environment</strong> with the application’s deployment.
It can also easily be shared between team members so everyone can benefit from it. This way, everyone’s config will be similar, and the chance of users’ errors will be lower.
In a future blog post, I will elaborate on how you can create some nifty stuff in combination with some other shell features.</p>]]></content><author><name>Gert Vilain</name></author><category term="environments," /><category term="devops" /><summary type="html"><![CDATA[Having to work with different environments configs on your pc can be a hassle and dangerous. Let's explore an option that will improve your experience with it.]]></summary></entry><entry><title type="html">Communication is a Skill</title><link href="https://www.tripled.io/12/09/2019/communication-as-a-skill/" rel="alternate" type="text/html" title="Communication is a Skill" /><published>2019-09-12T00:00:00+00:00</published><updated>2019-09-12T00:00:00+00:00</updated><id>https://www.tripled.io/12/09/2019/communication-as-a-skill</id><content type="html" xml:base="https://www.tripled.io/12/09/2019/communication-as-a-skill/"><![CDATA[<h1 id="communication-is-a-skill">Communication is a skill</h1>

<p>Being able to have a productive discussion is an important skill to have. Of course we all try to reduce the boring bureaucratic meetings as much as possible. But we still need to sit together with our fellow team members and colleagues to discuss, refine and agree on how we will build and integrate our software.</p>

<p>As software engineers, we are constantly learning new technologies, new techniques. People their resumes are more often than not a list of hard technical skill that they have mastered. However, engineers rarely take the time to improve their communication skills. Conway’s law taught us the correlation between software design and people interactions. So if we want to develop good software, the interactions of the people that are building it really does matter. A lot. How they communicate with each other is important. It is a skill just like any other. So how can we get better at it?</p>

<h2 id="does-this-matter-for-a-software-engineer">Does this matter for a software engineer?</h2>

<p>In and outside of meetings we are constantly in communication with each other. So you might think that you have mastered this from daily practice and don’t need to spend any time on improving those skills. Communication and collaboration is something that we do every day, so we assume that we are good at it. But I fear that we overestimate our level at effective communication.</p>

<p>No doubt we all have been in some very unproductive discussions where conflicting interests and opinions collide, where a lot of time is wasted with little to show for, except some frustration and possible bad feelings towards each other. Meetings and discussions aren’t productive or efficient by chance. There is a reason people often try to avoid them.</p>

<p>Those inefficient discussions are something that I have started to pay a lot of attention to, in the last couple of years. And once you see the patterns, it is hard to unsee them. It becomes all the more apparent what a blocker they often are for the quality of our software, the speed with which we deliver it, how much time and money gets wasted and how much grievances these unproductive discussions lead to.</p>

<p>So having productive discussions is important. Experience has shown me that it isn’t something that happens from itself. It is something one needs to work on and pay attention to.  You could, of course, spend your valuable time on something else than a blog post on communication. This certainly won’t gain you the same bragging rights as having read the latest shiny object article. But I would argue it is a skill that will have more impact on your efficiency as a software engineer then that new fancy framework.</p>

<h2 id="anti-patterns">Anti Patterns</h2>

<p>Let me start by listing some - what I call - anti-patterns of having a productive discussion</p>

<ul>
  <li><strong>Interrupting each other</strong>: Frustrating for the one who is interrupted and makes it hard to follow the conversation. often also a clear sign you weren’t trying to understand.</li>
  <li><strong>Raising our voice</strong>: The best way of silencing the ‘opposition’. However, when no one no longer objects, that doesn’t mean you made your point. They just stopped caring.</li>
  <li><strong>Getting sidetracked</strong>: Jumping from one topic to another makes it hard to follow and nothing gets finished.</li>
  <li><strong>Going depth-first instead breath first</strong> Discussing details in depth before the bigger global picture is clear</li>
  <li><strong>Not listening</strong> Talking next to each other and not really listening. Just waiting until someone else has stopped talking</li>
  <li><strong>No visualization</strong> People fearing the whiteboard.</li>
  <li><strong>Limited engagement</strong> Only a small percentage of the group is engaged: This is a great tell sign that de discussion has gone off the rails. If a large part of the group is no longer actively listening, this should be a sign that something is going wrong.</li>
  <li><strong>Ego</strong>: Of course. The always present elephant in the room. You are not your solution. Let it <a href="/26/06/2018/LocalHero##ego">go</a>.</li>
</ul>

<p>I’m sure we all know and recognize those anti-patterns, hopefully realizing that they can be a problem. But knowing them does not mean that we aren’t doing them ourselves. Even if we recognize that we shouldn’t.</p>

<p>I think it is the first major important step to recognize the large cost of those anti-patterns. These anti-patterns impact the quality of the software that we create, the speed in which we create it and the quality of the human relations and interactions. Once we become mindful of this, we can start avoiding these anti-patterns.</p>

<h2 id="mob-programming">Mob Programming</h2>

<p>When I recently took Woody<sup id="fnref:Woody" role="doc-noteref"><a href="#fn:Woody" class="footnote" rel="footnote">1</a></sup> Zuill’s <a href="https://www.agilealliance.org/resources/experience-reports/mob-programming-agile2014/">mob programming</a><sup id="fnref:mobbing" role="doc-noteref"><a href="#fn:mobbing" class="footnote" rel="footnote">2</a></sup> course, a lot of what he said resonated with me. Not just on how to do mob programming, but on the whole communication aspect. After all, if a team wants to be able to Mob program efficiently they must be also able to communicate productively. Woody taught us Mob programming through a series of exercises where we needed to interact <strong>disciplined</strong> and pay attention to how we communicate. I found this very revealing.</p>

<p><img src="/img/posts/communication/mob-group.jpg" alt="Mob 3" title="Mob programming workshop" width="500px" /></p>

<h3 id="what-woody-said">What “Woody” said</h3>

<p><strong>Learn to shut up</strong></p>

<p>By adding our solutions or suggestions non-stop to the discussion, we think we’re gaining speed, but actually, we’re slowing down. It is very hard to keep quiet when we “know better”.</p>

<blockquote>
  <blockquote>
    <p>“Clarity comes when you pause. Count to 10.” - Woody  Zuill<sup id="fnref:Woody:1" role="doc-noteref"><a href="#fn:Woody" class="footnote" rel="footnote">1</a></sup></p>
  </blockquote>
</blockquote>

<p><strong>Keep it to yourselves</strong></p>

<p>Let people realize a possible error themselves. Refrain from prematurely adding noise. You may be right, they may be right. Let it play out.  It will often go faster, with less confusion and better understanding for everyone. We don’t need to have a consensus on every detail. Perhaps it is not even important in the big picture. So, keep it to yourself. This is hard by the way :-)</p>

<blockquote>
  <blockquote>
    <p>“Often, we are just adding noise. Can we keep it to ourselves?” - Woody Zuill</p>
  </blockquote>
</blockquote>

<p><strong>Learn to Listen</strong></p>

<p>Listening is not just waiting until it is our turn to speak. Are we really listening?</p>

<blockquote>
  <blockquote>
    <p>“A  good listener makes others better thinkers” - Woody Zuill</p>
  </blockquote>
</blockquote>

<p><strong>Have a parking lot</strong></p>

<p>Do not continuously interrupt the flow with new ideas, concerns or tasks. Postpone the details, move them to the parking lot so we don’t get sidetracked. We want to keep our focus during a discussion. Discussing one issue at a time. It is also pointless to discuss a lot of could and maybe’s.</p>

<blockquote>
  <blockquote>
    <p>“Talking does not expose reality. Doing does.” - Woody Zuill</p>
  </blockquote>
</blockquote>

<p><strong>Respect each other</strong></p>

<p>How would you like to be treated? Treat others in a way you would like to be treated. Don’t let our enthusiasm for a solution make <a href="/17/07/2018/Bully/">Bullies</a>* out of us. Check the ego. Make an environment where people dare to make suggestions, mistakes and say they do not know something.</p>

<blockquote>
  <blockquote>
    <p>“Treat each other with kindness, consideration, and respect” - Woody Zuill</p>
  </blockquote>
</blockquote>

<h3 id="train-communication-in-mob">Train communication in Mob</h3>

<p>Mob programming is not something that works everywhere. You need to get good at it. The team needs to get good at it. But even when you aren’t doing it on a daily basis, there is a lot to be learned from a couple of sessions. Try it out at work, in a meetup, unconference, … Pay attention to how hard it is to “Not add noise”, “Shut up”, “Really listen”. It is a great technique to practice communication in itself.</p>

<p><img src="/img/posts/communication/mob-group-2.jpg" alt="Mob 4" title="Mob programming workshop" width="500px" /></p>

<h2 id="guidelines">Guidelines</h2>

<p>After the anti-patterns, I like to offer some guidelines that can help us in becoming better at good communication, at the risk of sounding fluffy duffy. But these things matter. Once you start paying attention to them you’ll be amazed of their impact and how often that neglecting them is the root cause of problems.</p>

<h3 id="the-soft-ones">The ‘soft’ ones</h3>
<p><em>a.k.a. The hard ones to master</em></p>

<h4 id="kindness">Kindness</h4>
<p>Be gentle and polite. Show concern for others. Value their opinions.</p>
<h4 id="consideration">Consideration</h4>
<p>Be humble. Our own idea is just one idea. Really consider other ideas</p>
<h4 id="respect">Respect</h4>
<ul>
  <li>We can respectfully disagree.</li>
  <li>Don’t attack other people’s self-esteem.</li>
  <li>No bullying other people into silence</li>
</ul>

<p>I took the above straight from the Mob programming book. They are short and easy to remember. But very hard to master…</p>

<blockquote>
  <p>“When we learn how to treat each other well we create a path toward better solutions. So start ‘pretending’ that we are good people”  - Woody Zuill</p>
</blockquote>

<h3 id="actionable-guidelines">Actionable guidelines</h3>
<p><em>a.k.a. The other hard ones</em></p>

<h4 id="dont-waste-time-on-discussing-and-deciding-conflicting-ideas">Don’t waste time on discussing and deciding conflicting ideas.</h4>

<p>The best way to resolve conflicting ideas is to <strong>act</strong> upon them.</p>
<ul>
  <li>See what works by doing it.</li>
  <li>Model multiple solutions out.</li>
  <li>Discuss on concretes.</li>
</ul>

<p><img src="/img/posts/communication/triple-d-mob-yves-2.jpg" alt="Visualize at the whiteboard" title="Triple D on a learning day" width="500px" /></p>

<h4 id="visualize-things">Visualize things.</h4>

<p>Make a drawing, use post-its. Make it clear what we are discussing and where we are in the discussion.</p>

<p>Letting go of the keyboard, or being the first one in a meeting to step up is a big hurdle to take. People seem to think it is not worth the effort, or maybe fear the attention. But visualizing the topic we are discussing can greatly increase the efficiency of the discussion, speed up the process and making sure that everyone is talking about the same thing.</p>

<p>When we are discussing against a visualization</p>
<ul>
  <li>it reduces the cognitive overload</li>
  <li>It isn’t personal. We are discussing a representation, not each other. This makes it often less offensive to disagree.</li>
  <li>it brings focus and clarity</li>
</ul>

<p><img src="/img/posts/communication/drawing-whiteboard.jpg" alt="Visualize" title="Don't fear the whiteboard" width="500px" /></p>

<h2 id="conclusion">Conclusion</h2>

<p>Solving technical issues is hard. But so is communication efficiently and productively. Do not neglect this skill. Just like with everything, it is something that we can get better at by paying attention to it. Good communication is important enough to do so…</p>

<p><img src="/img/posts/communication/triple-d-mob-1.jpg" alt="Mob 1" title="Triple D on a learning day" width="500px" class="img-table" />
<img src="/img/posts/communication/triple-d-mob-2.jpg" alt="Mob 2" title="Triple D on a learning day" width="500px" class="img-table" />
<img src="/img/posts/communication/triple-d-mob-sander.jpg" alt="Mob 3" title="Triple D on a learning day" width="500px" class="img-table" />
<img src="/img/posts/communication/triple-d-mob-yves.jpg" alt="Mob 4" title="Triple D on a learning day" width="500px" class="img-table" /></p>

<p style="text-align: center;  font-style: italic;">Triple D during a learning day. Practising communication skills as well as engineering skills</p>

<hr />

<p><strong>References</strong></p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:Woody" role="doc-endnote">
      <p><em><a href="https://woodyzuill.com">Woody Zuill</a></em> <a href="#fnref:Woody" class="reversefootnote" role="doc-backlink">&#8617;</a> <a href="#fnref:Woody:1" class="reversefootnote" role="doc-backlink">&#8617;<sup>2</sup></a></p>
    </li>
    <li id="fn:mobbing" role="doc-endnote">
      <p><em><a href="https://www.agilealliance.org/resources/experience-reports/mob-programming-agile2014/">mob programming</a></em> <a href="#fnref:mobbing" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Guido Dechamps</name></author><category term="mob" /><category term="programming," /><category term="communication" /><summary type="html"><![CDATA[Developing software, solving technical issues is hard. But so is communication efficiently and productively. Having productive discussions isn’t something that happens automatically. And they play a big role in the way how the software will be designed. Conway's law taught us the correlation between software design and people interaction. So we must recognize communication as a skill that we need to master. Turns out there are quite a few things to be learned from Mob Programming.]]></summary></entry><entry><title type="html">The importance of the dependency inversion principle</title><link href="https://www.tripled.io/07/05/2019/dependency-inversion-principle/" rel="alternate" type="text/html" title="The importance of the dependency inversion principle" /><published>2019-05-07T00:00:00+00:00</published><updated>2019-05-07T00:00:00+00:00</updated><id>https://www.tripled.io/07/05/2019/dependency-inversion-principle</id><content type="html" xml:base="https://www.tripled.io/07/05/2019/dependency-inversion-principle/"><![CDATA[<h1 id="the-importance-of-the-dependency-inversion-principle">The importance of the dependency inversion principle</h1>

<p>The dependency inversion principle (DIP) is a well known principle and one of the five <a href="https://en.wikipedia.org/wiki/SOLID">SOLID</a> principles. It is at the heart of a lot of software design patterns, frameworks and architectures. This article will try to connect some dots and hopes to provide some additional insight into the application of this core principle.</p>

<h2 id="the-principle">The principle</h2>

<p>The DIP principle states the following:</p>

<blockquote>
  <p><strong>High level</strong> policy should not depend on <strong>low level</strong> details, instead, both should depend upon abstractions. <strong>Abstractions</strong> should not depend upon <strong>details</strong>. <strong>Details</strong> should depend upon <strong>abstractions</strong>.</p>
</blockquote>

<p>In essence the principle advocates two things. First it states that important things should not depend on details. Which hopefully makes a lot of sense. It also states that these concerns of different importance should be loosely coupled from each other. This should be done by using meaningful abstractions as the middleman.</p>

<p>This may sound simple in theory but it is often difficult to distinguish the important things from the unimportant ones. Also it requires discipline and insight to separate the two properly.</p>

<h4 id="inverting-dependencies">Inverting dependencies</h4>
<p>Applying the dependency inversion principle starts by <strong>introducing an abstraction between the high level policy and the low level detail</strong>. This abstraction removes the direct dependency on the details, decoupling it and thus allows for easier re-use of the important functionality in the policy. By introducing an abstraction, we allow the low level details, which are typically far more volatile then the high level policy, to be interchangeable, without requiring changes to the high level policy.</p>

<p>We call this <em>dependency inversion</em> because the high level policy no longer has a <strong>uses</strong> relationship with the low level policy but the low level policy now has an <strong>implements</strong> relationship on the abstraction.</p>

<p><img src="/img/posts/dip/introduceInterface.png" alt="Introduce an abstraction" width="600px" /></p>

<p>This implies that the high level policy and the abstraction reside on the same level. Which brings us to our next topic.</p>

<h4 id="where-to-put-the-abstraction">Where to put the abstraction?</h4>
<p>Who owns the abstraction upon which the high level policy depends and why? Where does the abstraction belong? The answer is actually already given in the definition of DIP. When we are ‘inverting’ the dependency, we are in essence going from a high level policy that ‘uses’ a low level detail (the dependency) to a situation where the high level policy ‘uses’ an abstraction and the low level policy now has the inverted relation “implements” (the inverted dependency) towards the abstraction. Since our goal was for the high level policy to no longer depend on the low level, the abstraction belongs with the high level policy.</p>

<p>There is also the cohesive aspect of “reason to change”. Why would the abstraction need to change? Because the one that uses it, requires something different from it. It is the high level policy that has the <strong>uses</strong> relation to the abstraction. Therefore they belong together.</p>

<p><img src="/img/posts/dip/moveInterface.png" alt="Move interface" width="700px" /></p>

<p>The low level policies, the details, are just plugins to our important policies.</p>

<h4 id="dependency-inversion-is-not-dependency-injection">“Dependency inversion” is not “Dependency injection”</h4>

<p>Many developers confuse the dependency inversion principle with <a href="https://en.wikipedia.org/wiki/Dependency_injection">dependency injection (DI)</a>. But these are two separate things. Dependency injection is a technique whereby one supplies the dependencies to an object. The intent behind dependency injection is to achieve separation of concerns between the construction and the use of objects. It states nothing on the relative importance between those objects or if an abstraction is used.</p>

<p>Dependency injection in itself is a form of the broader technique of inversion of control (IOC). IOC in itself <em>can</em> support DIP. But it is not because we use DI or IOC that we are necessarily applying DIP. No framework can help us determining what is high level and what is low level. Nor with defining the proper abstraction to separate the two.</p>

<p>When trying to apply DIP inside our codebase, we can ask ourselves: “Who instantiates the low level implementation of the abstraction if it’s located in an an other module? Using an IOC container, this is an easy problem. The IOC container could create the instance of the low level module and inject it where necessary. So <strong>an IOC container makes it really easy to inject low level details into our high level modules</strong>. But we still need to provide the proper abstractions ourselves. And we are still responsible for  placing the abstractions in the correct location, next to the high level policy.</p>

<p>So is an IOC container required when one wants to apply DIP? Of course not. We just need some sort of “main” module that wires our application together. The “main” is able to access all the necessary objects and wire them together. This is a purely technical affair that we could handle ourselves but it is a solved problem for which we often prefer the use an IOC.  But using a IOC does not guarantee that DIP is applied. It is up to us to define the proper architectural boundaries and policy separations. So DI does not imply DIP and vice versa. Separate things.</p>

<blockquote>
  <p>Using a IOC does not guarantee that DIP is applied</p>
</blockquote>

<h2 id="the-principle-applied">The principle applied</h2>

<h4 id="the-repository-pattern">The repository pattern</h4>
<p>Looking at the repository pattern, as originally coined by Eric Evans, we can clearly see that it’s a fine example of the dependency inversion principle. The pattern states that an <em>abstraction</em> should be created which is free of technical details, and should preferably look a lot like a collection interface. The abstraction should be implemented in the infrastructure layer where all the technicalities of dealing with a persistent store should be hidden. From the domain perspective, we are talking with a collection-like interface to store the aggregates.</p>

<p><img src="/img/posts/dip/repoPattern.png" alt="Move interface" width="500px" /></p>

<p>Placing this abstraction inside the domain layer, close to its consumers, ensures that the domain layer is guarded from any changes to the low level infrastructure code. It also makes perfect sense from a usability standpoint since the repository is defined in the domain language. The repository abstraction should be clean, no technical details should leak through the api.</p>

<p>As a side note, the idea of the repository pattern is to abstract away the persistency details. We obtain domain concepts from a repository. <em>Not</em> low level data where we still need to attach meaning to. If we obtain the aggregate from memory, a relational db, a document db or an event sourced system, those are low level details. A repository is not just a DAO.</p>

<blockquote>
  <p>A repository is <em>not</em> a data access object</p>
</blockquote>

<h4 id="ports-and-adapters-architecture">Ports and adapters architecture.</h4>
<p>When applying the dependency inversion principle on the architectural layers of your application, we’re bound to end up with a <a href="http://wiki.c2.com/?HexagonalArchitecture">hexagonal architecture</a> also called <a href="https://herbertograca.com/2017/09/14/ports-adapters-architecture/">ports and adapters</a> or as Uncle bob calls it: <a href="https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html">Clean Architecture</a>.</p>

<p>This architectural style applies DIP as an additional restriction on the multiple layers of an application. As a result all dependencies point towards the centre where the high level policy logic should reside. Therefore the centre is where we hope to find the domain model, the core functionality of the application. Achieving DIP in a layered architecture is achieved by creating abstract interfaces for the low level details. These low level details are typically called the adapters and sit at the boundary of your system. The abstractions are called the ports and are part of the domain layer.</p>

<p><img src="/img/posts/dip/hexagonal-architecture.png" alt="Hexagonal Architecture example" width="500px" /></p>

<h4 id="dip-in-kubernetes">DIP in Kubernetes</h4>

<p>In the Container Orchestrator Kubernetes we encounter <a href="https://kubernetes.io/docs/concepts/services-networking/ingress/">Ingress</a> which is an API object that manages external access to the <em>services</em> in a cluster. So an Ingress is an abstraction that provides a functionality to services. In Kubernetes, <a href="https://kubernetes.io/docs/concepts/services-networking/service/">services</a> are an abstraction themselves that represent a logical set of pods. So on both sides of the spectrum we have abstractions communicating with each other. These abstractions decouple the details of pods and external access. Allowing the high level policies from K8 to work without being hindered by the details.</p>

<h2 id="conclusion">Conclusion</h2>
<p>The Dependency inversion principle is an important principle that helps us to decouple the importance things from the details. It protects us from a ripple effect from changes inside low level modules. Because it neatly separates different concerns and allows the important concerns to take centre stage, our software can easily be adapted and understood. It enables the core of our software, the important stuff, to endure and survive the frequent changes in the more volatile lower level modules. It is however not an easy principle to apply. It requires thought and <strong>discipline</strong> to apply it correctly and consistently. But the benefits far outweighs the effort required.</p>

<blockquote>
  <p>DIP enables the core of our software to endure and survive the frequent changes of the more volatile lower level parts of the software.</p>
</blockquote>]]></content><author><name>domenique, guido</name></author><summary type="html"><![CDATA[The dependency inversion principle (DIP) is at the heart of a lot of software design patterns, technologies and architectures. This article will try to connect those dots, and hopefully provide some additional insight into this important principle.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.tripled.io/img/logo-alt.png" /><media:content medium="image" url="https://www.tripled.io/img/logo-alt.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Event Storming a restaurant</title><link href="https://www.tripled.io/09/04/2019/event-storming-a-restaurant/" rel="alternate" type="text/html" title="Event Storming a restaurant" /><published>2019-04-09T00:00:00+00:00</published><updated>2019-04-09T00:00:00+00:00</updated><id>https://www.tripled.io/09/04/2019/event-storming-a-restaurant</id><content type="html" xml:base="https://www.tripled.io/09/04/2019/event-storming-a-restaurant/"><![CDATA[<h1 id="event-storming-a-restaurant">Event Storming a restaurant</h1>

<p>I am a big fan of <a href="https://www.eventstorming.com">Event Storming</a><sup id="fnref:eventstorming" role="doc-noteref"><a href="#fn:eventstorming" class="footnote" rel="footnote">1</a></sup>, a technique that was created by <a href="https://leanpub.com/u/ziobrando">Alberto Brandolini</a><sup id="fnref:alberto" role="doc-noteref"><a href="#fn:alberto" class="footnote" rel="footnote">2</a></sup>. Despite its chaotic ‘storming’ nature, Event Storming has the ability to turn confusion into clarity. Because telling a story, on a timeline, is really how people’s brain work. Which is probably why we have user <em>stories</em> and not “user <em>click actions and resulting data flows</em>”.</p>

<p>Most people that use event storming use it for gathering the “Big Picture”. I see it used much less for modelling out solutions to concrete problems. That’s why, in this blog post, I will try to demonstrate the power and usefulness of Event Storming for modelling out solutions. By using some simple building blocks, event storming allows us to model out complex systems rapidly. Without the need for very strict standardization. No BPMN knowledge required.</p>

<p>By explaining the Event Storming component building blocks and illustrating their use, I hope to demonstrate that knowing them, their meaning and their inner relationship, can really help you tackling complex problems. Without the need to get lost early on into technical discussions. <strong>One does not need to be a software engineer to model things.</strong></p>

<p>My ambition with this blog post is to demonstrate two things:</p>
<ul>
  <li>the power of the Event Storming building blocks</li>
  <li>early, in-depth technical discussions aren’t needed</li>
</ul>

<h2 id="the-problem-case">The problem case</h2>

<p>As a problem case, I thought that it would be interesting to model out the workings of a restaurant. Because it is something we all can easily relate to. Also, it avoids technology! We can illustrate and reason about it without the need for any technology getting dragged into it. On more than one occasion I’ve seen technical details dragging a design discussion down into an endless technical debate where people are already fuzzing about the technical <em>details</em> before the process is properly understood, modelled out. So I intentionally try to avoid this here.</p>

<h3 id="welcome-to-our-restaurant">Welcome to our restaurant</h3>

<p>So let’s start with a little background story that illustrates the problems we are trying to solve.</p>

<h4 id="the-wedding-anniversary">The wedding anniversary</h4>

<p>Alice and Bob want to celebrate their 10 years of marriage with a nice dinner at the three-star restaurant “Triple D”. This is a restaurant not only known for the high quality of food and service. But they are unique in the fact that they are also able to serve à la carte. Combining high quality <del>software</del> food and service with great adaptability. So Bob makes a phone call to “Triple D” for a reservation within two months for two persons. The receptionist notes down the reservation. Three days before the date of the dinner, the receptionist of “Triple D” calls Alice to verify if their reservation is still on. Alice confirms that it is.</p>

<p>At the evening of their wedding anniversary, Alice and Bob arrive by taxi at “Triple D”. They enter the restaurant and are immediately greeted by the receptionist. They give their names and the receptionist looks them up in her reservation book. She finds their entry and their appointed table. She then escorts them to their table and takes their jackets. Once they are seated a waiter slowly walks to their table to welcome them. The waiter presents them with the menu.</p>

<p>Alice and Bob start by ordering an aperitif immediately. The waiter leaves to get their drinks and to give them time to make their choice. Alice and Bob look at the menu and discuss what they will have.</p>

<p>The waiter brings the aperitif to their table and serves it to them. They still aren’t ready to order so the waiter leaves again.</p>

<p>After a couple of minutes, Alice and Bob have made their choice out of several dishes. They both will go for matching wines since none of them needs to drive. The waiter sees that they have made their choice and comes over to take their order.</p>

<p>After a couple of minutes, the waiter brings them some appetizers while they enjoy their aperitif and while they wait for the first dish to be served.</p>

<p>The rest of the evening continues smoothly. Alice and Bob enjoy their dinner. The dishes come with an appropriate time between them, leaving room for pleasant conversation, without them needing to wait too long. The waiter makes sure that the correct wines are served and that their glasses are consistently refilled while they are enjoying the matching dish.</p>

<p>After dessert, they order a little digestif and request the check. The waiter brings the check and accepts the payment. After they enjoyed the digestif Alice and Bob collect their jackets and exit the restaurant. After which a waiter cleans their table.</p>

<h4 id="the-problem-scope">The problem scope</h4>

<p>With this little reference story as background, we are going to map out how a restaurant should operate in order to support the above scenario. There are many different actors in the restaurant. More than the one’s Alice and Bob came in contact with. The inner workings of the kitchen, how the bill was composed, to name a few. We also need to remember that Alice and Bob were hopefully not the only customers inside the restaurants. So we need a solution that scales, in which we can serve multiple customers, independent of each other.</p>

<h3 id="the-restaurant-event-flow">The restaurant event flow</h3>

<p>In the real world, to discover how the restaurant really works, we would hold a big picture event storming with all the people working in the restaurant present. The Waiters, Cooks, Dishwashers, Receptionists,… This would show all the different flows that are happening, their timing, inner dependencies and potential bottlenecks. Providing everyone with a global overview that most likely no one really has. All of this simply by using <em>the power of business events!</em></p>

<p>For this blog post, big picture event storming is not the focus. But I would still like to use it to get a global understanding of our restaurant, we are conquering before we are dividing.  At the same time, I like to demonstrate the power of <em>business events</em>. Because it is something that bears repeating.</p>

<p>So below you will find my own simplistic event flow for a restaurant, based on my limited understanding and imagination. It is not complete or perfect, having intentionally oversimplified many inner workings. But it tells a coherent story and we can already see different ‘flows’ appearing.</p>

<p><strong>The reservation event flow</strong></p>

<p>Since Triple D is very famous (ahem…), people need to make reservations.</p>

<p><img src="/img/posts/events-restaurant/reservationEvents.png" alt="Reservation events" /></p>

<p><strong>Customer enters restaurant event flow</strong></p>

<p>From our restaurant perspective, the business starts once people enter our restaurant.</p>

<p><img src="/img/posts/events-restaurant/customerEntryEvents.png" alt="Customer entry events" /></p>

<p><strong>Dining Ordering event flow</strong></p>

<p>Once the waiters see that a table is ready to order, they take their orders and passes them on to the kitchen. The kitchen prepares the different dishes and makes sure that they are sent out to the table together.</p>

<p><img src="/img/posts/events-restaurant/diningOrderEvents.png" alt="Dining Order events" /></p>

<p><strong>Courses served event flow</strong></p>

<p>The customers enjoy all their served dishes. Once a dish is done, the kitchen can serve/prepare the next ones. When they are done, a table requests the bill pays and leaves the restaurant. After which the tables need to be cleaned for the next customers.</p>

<p><img src="/img/posts/events-restaurant/coursesServedEvents.png" alt="Courses served events" /></p>

<p>In the previous example we are able to tell comprehensible stories simply using domain events. We didn’t need to use any other components yet. That is the power of events and why they are the central component that which we will tell our story.</p>

<h2 id="event-storming-components">Event Storming components</h2>

<h3 id="the-domain-event">The domain Event</h3>

<p>The core building block of event storming is, of course, the <strong>domain</strong> events.</p>

<p>Domain events have the advantage that they steer discussions away from technical issues, that they focus on what has happened, without spending too much detail on how it happened. When the discussions occur around domain events then database and UI discussion are pushed to the background. Which is a very good thing. We don’t want to let debates go depth-first from the start because we could waste a lot of time on something that may later seem to be an unimportant detail. We want to conquer before we divide: we aim to understand the problem, see the whole story, before we start splitting things up and start thinking about possible solutions.</p>

<h3 id="all-modelling-components">All modelling components</h3>

<p>Apart from domain events, there are also other DDD building blocks that can take the stage in an Event Storming session. All the building blocks used are:</p>

<table>
  <thead>
    <tr>
      <th>Component</th>
      <th>Description</th>
      <th>Contains</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>users</td>
      <td>Actual persons interacting with ‘systems’</td>
      <td>Free will</td>
    </tr>
    <tr>
      <td>commands</td>
      <td>An order that was given, things someone wants to happen. It doesn’t do anything on its own.</td>
      <td>Data</td>
    </tr>
    <tr>
      <td>events</td>
      <td>A business event that has happened.</td>
      <td>Data</td>
    </tr>
    <tr>
      <td>projections</td>
      <td>A data transformation that builds a read model from events.</td>
      <td>Data Transformation logic</td>
    </tr>
    <tr>
      <td>read models</td>
      <td>Information that is presented to a user to make a decision</td>
      <td>Data</td>
    </tr>
    <tr>
      <td>policies</td>
      <td>Global business rules. “When X happens then trigger Y”</td>
      <td>Orchestration logic</td>
    </tr>
    <tr>
      <td>systems</td>
      <td>Something under our control that executes a command. <strong>Can</strong> be an aggregate, actor,…</td>
      <td>Actionable logic</td>
    </tr>
    <tr>
      <td>external system</td>
      <td>Something not under our control that executes commands.</td>
      <td>Actionable logic</td>
    </tr>
    <tr>
      <td>UI</td>
      <td>The typical portal from the real world to the software systems. The way by which the user can read models and trigger commands in a software world.</td>
      <td>Interface to data and actions</td>
    </tr>
  </tbody>
</table>

<p>Note that these definitions aren’t very formal and precise. This is intentional. One of the powers of the event storming components is that they are not defined too strictly. Event Storming aims to be a very lightweight technique, that is easy to learn and remains flexible. We don’t want to get stifled by heavy standards.</p>

<p>All these components have relations defined between them. As explained in Alberto’s Universal picture.<sup id="fnref:book" role="doc-noteref"><a href="#fn:book" class="footnote" rel="footnote">3</a></sup></p>

<p><img src="/img/posts/events-restaurant/components-overview.png" alt="Picture that explains everything" /></p>

<p>The above components come into play when we move away from trying to understand the problem and we start solving it. The moment we want to model out solutions to the story, that’s when we add the other components. In a modelling sessions these components are typically represented by light weight post-its that we can easily move around or replace. We just need to respect their light definitions and their inner relations. This provides us with a fast and cheap modelling technique.</p>

<p>These building blocks <strong>can</strong> be implemented technically. This means that when we are modelling out a solution through Event Storming process flow, we are also immediately modelling out a different potential software solution. Even if we haven’t referred or included any technologies yet, the modelled solution can map one on one with the implemented one. Which is exactly what we want. The domain should drive the design of our solution, <strong>not</strong> the technologies. Or god forbid, the database…  In a future blog post, we will talk about the relation between the modelling components and a hexagonal architecture. But for now, we will remain technology agnostic.</p>

<h2 id="modelling-our-restaurant-processes">Modelling our restaurant processes</h2>

<p>Armed with the knowledge of our building blocks, we will now model out the flow between the different actors in the restaurant. The customer, the waiter, the cook… I will give a verbose explanation with the first processes. But I hope that after a while the model speaks for itself.</p>

<p>The legend used in the following process illustrations matches:</p>

<p><img src="/img/posts/events-restaurant/eventStormComponents.png" alt="EventStormComponents" /></p>

<p>Since we will remain technology agnostic, there will be no UI. But the other components can be found in the real world. In our restaurant example, they can be implemented as follows</p>

<ul>
  <li>a read model will be data written down on paper</li>
  <li>a projection will be the act of writing summarized data down</li>
  <li>the events will be things that happened in the real world</li>
  <li>the commands are the initiation of an action</li>
  <li>policies are the rules that were agreed upon verbally up front</li>
</ul>

<p>With our building blocks at our disposal, we can model out the flow of our restaurant.</p>

<h3 id="the-processes">The processes</h3>

<p>In the big event flow, there are many different processes at work. For clarity, we’ll distill them one by one, each time with less explanation. The process diagram should make it clear.</p>

<h4 id="the-reservation-processes">The reservation processes</h4>

<p>Let’s start with the process that kicks off the customer experience, the reservation process. From the customer perspective, this is very straightforward. They make a call to a restaurant, some external thing outside of their control, and they try to get a reservation for X persons on a given date Tx. The outcome of this is that the reservation was possible or not. This is the flow from the customers perspective. For the customers, the restaurant is an external system. The details of it do not concern them.</p>

<p>From the restaurants perspective, however, these details concern us of course very much. The phone needs to be answered by the receptionist. A role that is taken by whoever is at the desk at the customer calls. The receptionist will see if there is a table available for X persons on date Tx and respond accordingly. If the reservation is made then the receptionist will add it the bookings overview for Tx. The bookings overview is a projection of all the bookings made for a given day. It gives a quick comprehensible overview.</p>

<p>Each day the receptionist need to confirm the reservations made for z days in the future. That is one of the <strong>restaurants policies</strong>. It is applied to make sure that they use the maximum of their restaurant capacity. Everyone who serves as the receptionist on a given day knows that this is one of their tasks. So the policy triggers them to confirm the reservations with the customers. When a reservation is cancelled they update the Bookings for that day.</p>

<p><img src="/img/posts/events-restaurant/processFlowReservation.png" alt="Reservation flow" /></p>

<p>At the start of each day, the receptionist needs to assign the final tables to the customers. Since they aren’t likely to change any more this can now safely be done. This is again one of the restaurant’s policies: “When the day starts, then the receptionist must assign tables”. The definitive assignments read model is updated. This will allow the receptionist to be able to quickly assign the customers to their assigned tables.</p>

<p>The receptionist policy thus contains the following rules:</p>

<ul>
  <li>When the date is [Tx - z] then receptionist must confirm the reservations for Tx.</li>
  <li>When the date is [Tx] then receptionist must assign the definitive tables for to the booked customers for Tx.</li>
</ul>

<p><img src="/img/posts/events-restaurant/processFlowTableAssignment.png" alt="Receptionist Proces" /></p>

<h4 id="the-dinner-processes">The dinner processes</h4>

<p>There are of course more processes operational in the complete working of a restaurant. But let us jump right into the flows concerning the dinner. Because this is the core of our restaurant, where we make our money.</p>

<p>It starts of course with the customers entering our restaurant. They will be received by the receptionist who will look up their assigned tables and escorted them to their places.</p>

<p><img src="/img/posts/events-restaurant/processFlowReceptionist.png" alt="Receptionist Proces" /></p>

<p>Once they are seated, the waiter that is assigned to their table is triggered to bring them their menus, let them order their drinks and dishes. The waiter places the table’s drink order at the bar and continues serving other tables. When the drinks are ready the waiter is triggered.</p>

<p><img src="/img/posts/events-restaurant/processFlowWaiterDrinks.png" alt="Waiter drinks Proces" /></p>

<p>When the waiter serves the drinks, it is typically also the time that the dinner order is taken. The waiter will place the order for the table in the kitchen. From the waiter’s perspective, the kitchen is an external system. They place their order in, and the dishes will be coming out in the correct order, grouped by a table. But the kitchen of course also has a highly complex flow.</p>

<p><img src="/img/posts/events-restaurant/processFlowWaiterFood.png" alt="Waiter food Proces" /></p>

<h2 id="on-policies">On Policies</h2>

<p>Policies are something that is often not modelled out explicitly. But notice how lightweight those policies are. The complexity of how to perform complex actions, like cooking, resides in the systems. These actions do not need to change when we modify the logic present in the policies. This allows us to easily change the behaviour of an entire system.</p>

<p>For instance, when we modify the policy rule from</p>

<p>“<em>When the customer is done eating, then the customer must pay</em>” to “<em>When the customer has ordered, then the customer must pay</em>”</p>

<p>we radically have changed the way our restaurant functions. We went from a restaurant for dining, where one pays at the end. To a fast dining restaurant where you pay up front, allowing for faster change of customers.</p>

<p>Policies can be simple agreements between people or they can be fully implemented in software. A <a href="https://www.enterpriseintegrationpatterns.com/patterns/messaging/ProcessManager.html">process manager</a><sup id="fnref:process_manager" role="doc-noteref"><a href="#fn:process_manager" class="footnote" rel="footnote">4</a></sup> is a software design pattern that can be used to centralize policies.</p>

<h2 id="on-aggregates">On Aggregates</h2>

<p>The DDD aficionado’s will have noticed that I have tried not to mention aggregates. This was intentional. An aggregate has a definition that’s too strict and this might stifle conversation, make it harder for people to explore a model. Same goes for Actors. That is why you can see “Aggregate” between quotes in Alberto’s universal picture. Remember not to get hung up on formal definitions. In Event Storming, an Aggregate is just a yellow sticky…</p>

<h2 id="conclusion">Conclusion</h2>

<p>I hope to have demonstrated the power of <strong>Event Storming process modelling</strong> to you as a technique that can be used to design solutions, without the need for in depth technical knowledge. Please try them out for yourself. Try to solve an <a href="http://nealford.com/katas/">Architectural Kata</a><sup id="fnref:architectural_kata" role="doc-noteref"><a href="#fn:architectural_kata" class="footnote" rel="footnote">5</a></sup> to familiarize yourself with the technique. The more comfortable you are with the components and the technique the easier you will step up and start designing. Start using it, start having the conversations. There is no need to fear the DDD police! Alberto<sup id="fnref:alberto:1" role="doc-noteref"><a href="#fn:alberto" class="footnote" rel="footnote">2</a></sup> is a really nice guy ;-) .</p>

<blockquote>
  <p>Don’t be afraid to design! Model things out!</p>
</blockquote>

<hr />
<p><strong>References</strong></p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:eventstorming" role="doc-endnote">
      <p><em><a href="https://www.eventstorming.com">Event Storming</a></em> <a href="#fnref:eventstorming" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:alberto" role="doc-endnote">
      <p><em><a href="https://leanpub.com/u/ziobrando">Alberto</a></em> <a href="#fnref:alberto" class="reversefootnote" role="doc-backlink">&#8617;</a> <a href="#fnref:alberto:1" class="reversefootnote" role="doc-backlink">&#8617;<sup>2</sup></a></p>
    </li>
    <li id="fn:book" role="doc-endnote">
      <p><em><a href="https://leanpub.com/introducing_eventstorming">Introducing Event Storming</a></em> <a href="#fnref:book" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:process_manager" role="doc-endnote">
      <p><em><a href="https://www.enterpriseintegrationpatterns.com/patterns/messaging/ProcessManager.html">Process Manager</a></em> <a href="#fnref:process_manager" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:architectural_kata" role="doc-endnote">
      <p><em><a href="http://nealford.com/katas/">Architectural Kata</a></em> <a href="#fnref:architectural_kata" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Guido Dechamps</name></author><category term="java," /><category term="software," /><category term="DDD" /><summary type="html"><![CDATA[Most people that use event storming use it for gathering the "Big Picture". But it can also be used for modelling out solutions to concrete problems. This blog post, I will try to demonstrate the power and usefulness of Event Storming for modelling out solutions. By using some simple building blocks, event storming allows us to model out complex systems rapidly. Without the need for very strict standardization.]]></summary></entry><entry><title type="html">The bully</title><link href="https://www.tripled.io/17/07/2018/Bully/" rel="alternate" type="text/html" title="The bully" /><published>2018-07-17T00:00:00+00:00</published><updated>2018-07-17T00:00:00+00:00</updated><id>https://www.tripled.io/17/07/2018/Bully</id><content type="html" xml:base="https://www.tripled.io/17/07/2018/Bully/"><![CDATA[<h1 id="the-bully">The bully</h1>

<p><em>This post belongs to small series of posts. The main post is <a href="/31/05/2018/Heroes/">Heroes</a>.</em></p>

<p>In this post, I will talk about the hero-bully. This is not the ordinary bully, which may come to mind, i.e. someone that everyone fears, almost nobody likes and who rules by force of intimidation. Rather, what I am talking about here are heroes who are placed on a pedestal by one group and who use the power from their received status to bully those around them that do not follow suit. In this regard, the bully resembles the gunslinger hero. After all, depending on whether you oppose or disagree with them, heroes can become bullies who ‘rule’ by brute force and by the political weight that was given to them. Who would dare to go against the hero of the people?</p>

<blockquote>
  <p>A hero to some, a bully to others</p>
</blockquote>

<p>While they may be feared instead of loved by some or most of their peers, the terrorizing gunslingers may still appear heroes to the people of the town. Their heroes still get the job done and the townspeople (the customers) care about the results. They do not need to collaborate with the gunslingers themselves. Consequently, the bullies remain ‘in power’ by the approval of the townspeople in the one hand, and by intimidating and belittling any potential contenders on the other hand.</p>

<h3 id="bullies-grow-in-teams">Bullies grow in teams</h3>

<p>In the software industry, where virtually all development is a team (group) effort, a bully rises just like within any other group of people. Someone tries to dominate the group and force them to do what they want. Especially in large firms where teams are fixed, it is easier for a bully to rise in power and take root because relations have time to grow and become fixed. Bullying takes coaxing and pressuring over time and must build on perceived status. Conversely, when one only needs to work together for a short period of time, it is not so easy to establish a dominant role.</p>

<h3 id="establishing-dominance">Establishing dominance</h3>

<p>Software developers typically try to establish dominance by demonstrating superior knowledge in some technical field. This could be a framework, an application, a language, a technology… It is of course also possible that bullies are truly experts in their field and do know best. Unfortunately, even if one has not really mastered a topic, one can easily fake it by making a lot of noise, spouting buzzwords and professing that the opposing party is a [insert derogatory term here]. Those without technical knowledge can often mistake decibels for competence.</p>

<blockquote>
  <p>Those without technical knowledge can often mistake decibels for competence.</p>
</blockquote>

<p>Typically, the business has no way to know whether the bully is an expert or simply feigning mastery through excellent verbal skills. The fact that bullies are or appear to be experts and/or get the job done, causes them to place their trust in these individuals, which lies at the basis of the perceived status within the group.</p>

<h3 id="unintentional-bullies">Unintentional bullies</h3>

<p>The truth is that most of us have the potential to become bullies to some, so it is something to watch out for.</p>

<p>For example, if one is lauded often enough, as the expert or hero that saved the day, then ones <a href="/26/06/2018/LocalHero##ego">ego</a>  might start acting up. One can start to assume that they are always right – which nobody ever is. After all, constant public praise is a form of political power as it is a sign of hierarchy.</p>

<p>This type of power can be given officially by the role that you are assigned to in an organisation. For example, Technical Lead, Bla Bla Architect. (The more adjectives the better ;-)  But this ‘power’ can also be obtained unofficially by reputation alone. The latter is difficult because we aren’t always immediately aware of the reputation we have obtained. As such, if you are unaware of the political power that you wield, you may end up unintentionally bullying people.</p>

<p>It is my opinion that the best way to avoid bullying is simply by listening to what others have to say. At least hear them out and see if your ideas can stand up against debated arguments. Do not try to ‘win’ by force. This is not to say that if one truly does know ‘best’, you are not allowed to advocate your point. As a professional, it is your responsibility to give the customer the greatest value for their money so one should definitely speak up. But, a point should be made on sound arguments. Not on insults or decibels.</p>

<blockquote>
  <p>A point should be made on sound arguments. Not on insults or decibels.</p>
</blockquote>

<h3 id="dungeon-masters">Dungeon masters</h3>

<p>A while back Alberto Brandolini identified a pattern he called the <a href="https://medium.com/@ziobrando/the-rise-and-fall-of-the-dungeon-master-c2d511eed12f">Dungeon master</a><sup id="fnref:dungeon" role="doc-noteref"><a href="#fn:dungeon" class="footnote" rel="footnote">1</a></sup>. In short, a dungeon master is often the author of the original software and knows the software better than anyone else.</p>

<p>Now the Dungeon master is a position every one of us might find themselves in if we stay at a job long enough. It is not a position of malevolence per se, but rather a natural evolution in a certain direction, heavily influenced by circumstances.</p>

<blockquote>
  <p>The dark secret of the Dungeon Master is that he knows every trap in the existing legacy software because he was the one to leave the traps around. This isn’t intentional or evil. Knowledge, in the form of accidental complexity, starts accumulating in the head of the Dungeon Master, and silently grows.</p>
</blockquote>

<p>The Dungeon Master becomes dangerous when they couple their ego’s to their ‘dungeon’. This will cause them to become a force that resists change and improvement. Because when you criticize the dungeon, you criticize them. Furthermore, if a Dungeon Master is granted a <a href="/26/06/2018/LocalHero/">local hero</a> status then the DM can become a major obstacle in the never-ending road to improvement. They will harshly attack anyone that criticizes the existing system, i.e. their dungeon, their baby. Armed with the confidence of being the only person with a true knowledge of the complex system, having a hero status, and possibly some minions, they are in a position which allows them easily to block any new ideas. Changes that must be made, bottlenecks that must be fix, software that needs to be replaced… all of these initiatives can be halted by a <strong>bully dungeon master</strong>.</p>

<p>While the Dungeon Master in itself is not a force of evil, the bully is. A dungeon master might become a bully. However, a bully that goes unobstructed long enough will often evolve into a dungeon master by choice because they are drawn to the power the DM yield through their unique knowledge of all the traps and pitfalls in a complex system. This makes it almost impossible to go against them.</p>

<h3 id="conclusion">Conclusion</h3>

<p><strong>Employers</strong></p>

<p>As an employer be beware that those that appear to be heroes to you may very well be bullies to others. Beware that you are not left with a couple self-aggrandizing loudmouths, supported by some meek minions, while the competent, constructive professionals who wanted the best for the company have left you without you even noticing it.</p>

<p>Make sure to hear more than one side of the story and be <em>very</em> careful with whom you grant “special” status.</p>

<p><strong>Software engineers</strong></p>

<p>To my fellow Software engineers, I would ask, again, to let go of your ego. People will respect you so much more do. Achieving something together is so much more rewarding than forcing your will upon others.</p>

<p><strong>References</strong></p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:dungeon" role="doc-endnote">
      <p>In Alberto’s <a href="https://medium.com/@ziobrando/the-rise-and-fall-of-the-dungeon-master-c2d511eed12f">Dungeon master</a> post he introduces the pattern of the dungeon master. And even mentions the minions. Which could possibly correlate with my definition of minions. <a href="#fnref:dungeon" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Guido Dechamps</name></author><category term="Hero," /><category term="software" /><category term="developments," /><category term="teams," /><category term="communication," /><category term="patterns" /><summary type="html"><![CDATA[In my series on heroics within software development teams, there is a type of 'hero' that I classify as the hero-bully. This is not the simple, ordinary bully, which may come to mind, who rules by force of intimidation. A hero-bully is someone placed on a pedestal by one group and who use the power from their received status to bully those around them that do not follow suit. This can even be completely unintentional!]]></summary></entry></feed>