A few myths about CQRS

I’m happy to see that event driven architecture rises in popularity, I already explained why I believe it makes sense. But when a topic gets more traction, we hear more and more weird things. Let me try to clarify a few myths about Command and Query Responsibility Segregation (CQRS) here.


CQRS is not Events Sourcing (which is not Event Storming)

Some people understand CQRS/ES as a single architecture paradigm. It’s actually two different paradigms, even is they were brought out together .

CQRS is about segregation of the commands and the queries in a system. It is nothing but Single Responsibility Principle (SRP) apply to separate the decisions from the effects. It comes from CQS.

Event Sourcing (ES) is about storing immutable events as the source of truth to derive any state of the whole system at any time.

Both paradigms work well together (Greg Young calls them “symbiotic”). But we can do CQRS without ES, and we can do ES without CQRS.

And just because I heard the confusion a few times, Event Storming is not Event Sourcing. It is not an architecture paradigm. Event Storming is a way to crunch knowledge with the business in an event driven approach, but it is not technical at all. It is a convention to talk with other people using post-its to represent business events.


CQRS is not Eventual Consistency

Eventual Consistency is when the read model is not synchronously updated with the write model.

It could be challenging, but it’s not mandatory in a CQRS system. We can choose to keep things synchronous, when it is good enough. We can go for an asynchronous implementation when we meet performance issue.

Thus Eventual Consistency is about performance, not about CQRS.


CQRS is not noSql and/or 2 databases

When I asked Greg Young what’s CQRS, he asks me in return if I know the concept of a SQL View. A View is nothing but a projection of the data, optimized for reading. That’s the query part of the system.

Sure, we can choose to store the query part in a separate database. Yes, it could make sense to store it in a noSql database, to reduce the impedance mismatch.

But it is CQRS as soon as there is a logical separation between command and queries. The rest is just a technical choice.

vector silhouette of a girl with raised hands and broken chains

CQRS is freedom

CQRS is before all freedom in architecture.
It allows choosing if we need eventual consistency, noSql, synchronous or asynchronous validation, and so on. It’s not an extremely complex topic, only useful for Amazon or Google.

Of course, CQRS is not a silver bullet either, but so far I have seen lots of missing opportunities to use it in several domains. But I still haven’t seen a software using CQRS where they should have go for a simple CRUD system instead.


PS: I just saw Greg has written on the same subject in a  more concise and direct way 3 years ago.

PS2: If you want to know more, I’ll be talking about the synergy between CQRS, ES and DDD, at BDXIO next October the 21st



On Writing (Code) Well

Following an advice from Cyrille Martraire, I just finished reading On Writing Well: a non-fiction guide written 35 years ago. Reading this book helps me to realize there are lots of similarities between writing code and non-fiction.


The arrogant guy

“A simple style is the result of hard work and hard thinking. A muddled style reflects a muddled thinker or a person to arrogant, or too dumb, or too lazy to organize his thoughts.”
On Writing Well, William Zinsser

I like this quote because who has never met a codebase much more complicated that what it needs to be? I was one of these arrogant guys not so long ago.

I was proud to write code that none of my co-workers can understand. It took me a while to accept that my code was bad, and that I overcomplicated it in order to look smart. It took me a while to realize that I had a muddled style.


Another similarity is that it’s more about re-writing than about writing. No writers are able to produce a perfectly understandable story at the first shot. They have to write, and re-organize, and change, and remove things until it is clear enough to be shared.

Refactoring seems absolutely normal for a writer. But for a software engineer, we expect a perfect code at the first try.  We’d like to believe we are so smart that we can build a whole business process in our mind, and write it in an unambiguous way for a computer who doesn’t speak our natural language. But we can’t.


Decreasing the cognitive load

We need to decrease our cognitive load, to focus on the really tiny portion of the whole business process we want to manage. Being able to reason about our code is paramount to high quality. And we can’t reason about our code if our brain is full of things unrelated to the problem.

In the same way, non-fiction writers can’t write a good article if their brain is full of things unrelated to their topic.


I see one big difference between writers and coders though: feedback loop. When writing non-fiction, it’s hard to know if your content is good before releasing it.

As developers, we have a very quick feedback using automatic unit tests.

continious-feedbackThe developer/writer metaphor

The house building metaphor hurts a lot our industry.
I think a better metaphor would be that writing software is like writing a book.

It’s something to remind our managers next time they want to add writers to solve our deadline issues.

Writing software is like writing a book with several other people, during several months, if not years.


A Craftsman work-life balance

I don’t feel comfortable when I hear people explaining how hard we should work to be “successful”. Mainly because “success” is subjective, it only makes sense in a given context.

For example, Uncle Bob in The Clean Coder asserts that a professional developer must work around 60 to 70 hours per week. 40 hours for his job, the rest of the time to improve his skills.

I deeply respect Uncle Bob, but when he says that I must dedicate 3 hours per day, week end included, from my personal time to improve my craft, I definitely not agree.

Professionals have a personal life

We are valuables professionals with a really limited resource: time.

A company does not own 100% of our time because it fills a pay check. We don’t sell our lives, we sell our skills for a given period of time.

Investing on these skills is important. Learning new things is important. But it is unsustainable to do it only on our personal time. And when it’s done during our personal time, there are different things that can be done to keep an enjoyable life.

cat on beach

How to learn at work and stay efficient?

We can learn new things at work. Of course it does not mean we can play all day long with the last shiny technology when it produces no value for the company.

But we can do pair/mob programming. Whatever the job and the level of the co-worker we are pairing/mobing with, we will learn a lot of unexpected things.

We can explore new languages/tools on tiny internal topic. During a limited time (half a day? A few days?), we can pick an internal subject (improve the deployment script?) and try to solve it using an unknown tool/language we like.

It’s possible to organise 1 hour katas once a week. Or maybe to watch an interesting talk during lunch?

We can also switch a few people in the team on a regular basis. It will reduce the bus factor and spread good practices through the whole company

How to learn at home and keep friends and family?

When we think about it, we tend to realize there are lots of time we don’t use efficiently.

Work commuting is a good example. This travel time cannot be reduce. We can use it to read a book about the last subject we’d like to learn about. In car it’s possible to listen for audio-books or podcasts.

Waiting queue is another example. We wait a lot for: a plane, a train, a meeting, a doctor… It’s easy to keep a book, or better, a pdf on our phone to read instead of passively lose our time.

For sport addicts, what about listening some podcasts during the workout? It is true multi-tasking: the brain can listen to the podcast when the muscles are working on something different.


A crafstman work-life balance

I believe a good work-life balance is essential to be a software craftsman.

Personal life matters, it is the pillar to build a strong professional career. Not the other way around.

If people believe that they have to work 70 hours a week for their whole life to be professional, who will ever want to commit for a life career as a software engineer?




A path to escape the “No time for tests” death spiral.

We all know the “no time for tests” death spiral.

First we take exceptional shortcuts to ship something because “we have to ship it now but we’ll do better next time”. Of course next time we have even less time, we have to add features, we can’t really fix the shortcuts. It takes longer and longer to add features because of the shortcuts we took and cant’ remove. We start to invest a lot into fixing bugs.

That’s the beginning of a painful road for the team in charge, and we all know the end is bad. Some will try to work overtime to manage the mess. Some will burnout, tired of being so unproductive. In this hard time we’ll hear things like: “It has always been done this way, I know it’s wrong, but what can I do, I’m just a developer…”

No need to say I don’t agree, and here is the path I take as a developer every time I face this situation.


Step 1: Fix known bugs with unit tests

To introduce a quality culture in any company, start by adding unit tests every time a bug is identified outside of the development team (by the quality analysis team or in production).

When we talk about unit testing, people usually ask if it’s worth it. What’s the return on investment? How do you know what to test?

If a bug goes out of our team, we can’t afford to let it happen again. It worth it because a regression shows we are not mastering what we are building, and is really annoying for users. We know what to test because we have an exact failing use case.

Use this opportunity to introduce a build server, we want to know before shipping if we have regression.

jenkins.jpgStep 2: the tester strikes back with test first

Most people arguing against unit tests have this experience:
1> They write some unit tests
2> It is incredibly painful
3> They stop testing with the conclusion that unit tests are incredibly painful
(The official explanation is most likely: “It takes too much time to write tests”)

Truth is: writing good code is incredibly hard, writing bad code is freaking easy.

Testing our software do nothing but reveals the nature of our code. It reveals how it behaves when we try to use it. When the code is hard to test, the code is bad, that’s what we need to accept to overcome this step. No need to blame the tools or the methods. What we need is to learn how to improve the code in terms of decoupling and maintainability.

When it comes to an important piece of code, write the test first. It will lead to more testable code, because nobody likes painful things.


Step 3: Test Driven Development as a rule of thumb

After a few months, if we do not observe any improvement, it is interesting to understand why? In my experience, it may be due to a lack of experience with unit tests (tools and/or methods) and/or a lack of discipline.

But if we observe an improvement due to step 1 and 2, it’s easy to argue that to improve even more, we should not ship any use case not covered by unit tests.

The good news is that our industry already uses an efficient method for that. It’s called Test Driven Development, and we can find tons of documentation online about it.

tdd.jpgStep 4: Less stress and better work

Be disciplined, don’t give up on TDD, and within a few months the results will be clear. The team will feel more confident and less stressed. With less stress, fewer bugs will be shipped, and we’ll have more time to improve, and to drink beers.

No overtime required. Only good habits, discipline and continuous improvement around good practices.

It is important to communicate at this stage. It may take several years to reach such a result. We should remember where we come from, what we did to improve and share our story with other teams.


It’s even better when we’re not alone

Some help by someone who already took a similar path is gold, because she will point out what’s wrong in the code and how to improve it.
She will also be familiar with tools and can avoid silly mistakes we all do when discovering these practices.
She mights also know how to manage tricky managerial issues.

It is with this kind of expertise that such a path can be achieved in a few months, instead of a few years.


That’s what a developer can do

This path is not a myth, this path is not a theory.
This path I followed 3 times already, and every single time it helps me to gain confidence, credibility and to be proud of my work.

That’s the kind of things we can do, as developers, to change the way it has always been done.


Many Thanks Nelson Da Costa for the review.


Usable Software Diagram

“Who is the user of software design”?
Some Software Usable Design practitioners think that the user is the developer.

I think the answer is not the same in every Dimension.


The user of software design is the developer

Specifically in the Artefact dimension.
Maybe it was the first answer to come in mind, because the question was initially asked by some developers.
The developer uses the design to build a mind map (with abstraction and static representation) of the software. With this map, she is able to navigate through the codebase in order to achieve a feature or to fix a bug.
She will technically explain to the machine how it should behave, but other humans will need to understand these explanations. A good design will give a frame to help the developer to put responsibilities in the good place.developer-512

The user of software design is the final user

Specifically in the Runtime dimension.
If a user has to read our documentation, it is a failure and an opportunity for improvement.
The software design must be crystal clear for the user at Runtime, because she will also build a mind map (with dynamic representation) of the software.
Not the same map than the developer, because it has different purpose. But still the user will navigate in the UI thanks to this map, in order to achieve what is useful to perform her job.


The user of software design is the business

Specifically in the Decision dimension.
And the whole purpose of DDD is to bring back this reality as soon as it is forgotten in the Artefact or Runtime dimension.
Again, the business build a different mind map (with business use cases), and uses it in order to take decision. The goal is to improve the business using the power of software.


Navigating with our own map

The map metaphor is really powerful, and Eric Evans himself uses it a lot.

I also like this talk by Simon Brown about the Art of Visualizing Software Architecture. He compares the drawing of an architecture with the drawing of a map. His point is that we need to know for who is our drawing, and why. Because any representation is an abstraction of the full system, and we need to understand what will be done based on our drawing to choose the good abstraction, at the good level.

Software design is used to navigate in the understanding of a software system. For this navigation to be efficient we want:
– a consistent level of abstraction
– abstractions align with our dimensionimages
Usable Software Architecture Design
A Usable Design needs to be navigable.
A good visualisation for our Software Architecture will let us know if our design is usable or not in terms of navigability.
Taking into account the dimension will help to build useful and navigable abstractions, because it implies a specific user in a specific context.

Don’t fall into the trap of mixing scale, or dimensions, in the same drawing. It will only result in a messy diagram that we’re used to see in our enterprises.

Instead choose one scale and one dimension to build understandable diagrams for one purpose.


Micro-service and bounded context clarification

One micro-service should cover one bounded context” asserts Vaughn Vernon.

It leads to an interesting tweeter discussion with Greg Young, Romeu Moura and Mathias Verraes.  Greg and Romeu disagree. I say it depends of the context.

To know if one can cover another, we must know what a micro-service is and what a bounded context is. I find their definitions are fuzzy, and I think this discussion is a proof of that. I’ll try to clarify my point in this article.

Disclaimer: the following definitions are based on my current understanding of DDD strategic patterns, I don’t claim they are the only true definitions.


Micro-service definition

We believe we know what is a micro-service until we take a look at the Wikipedia definition.

In contrast to SOA, micro-services gives an answer to the question of how big a service should be and how they should communicate with each other. In micro-services architecture, services should be small and the protocols should be lightweight.”

This definition is symptomatic of our industry: we explain something by something else we don’t understand either. Do we share a common understanding of what is “small” and “lightweight”? I don’t think so.

A better explanation is the second property in the details of the Wikipedia page: “Services are organized around capabilities, e.g., user interface front-end, recommendation, logistics, billing, etc.

To be fair, this property has lots of symmetries with how we define a bounded context.micro-services1-297x250

Domain definition and problem space

To understand what a bounded context is, we need to define what a domain is. It is a theoretical representation of a business, in the problem space. And it can be divided in sub-domains.

For example in the well-known business of Amazon,  the core domain is about selling stuff online, and there are different sub-domain more or less generic like shipping, billing, advertising and so on.

We are in the problem space because we have no idea (yet) about how we should implement Amazon’s business , it is just a theoretical description of what they do.

DDD patterns that are applicable to the problem space (figure 1-4 page 10 of PPP of DDD)

Bounded context definition and solution space

A bounded context is a projection in the solution space to define boundaries in the system implementing the domain. Bounded contexts are important because they allow to define an ubiquitous language, valid within their boundaries. A product in a billing bounded context has not the same meaning than in a shipping bounded context.

When it is badly done, we obtain a big ball of mud, e.g. a huge system without boundaries where an update in the billing part may cause side effect in the shipping part.

We are in the solution space because it is an actual description of how we implement the domain. A bounded context does not necessarily matches exactly one sub domain. But having too many bounded contexts overlapping between different sub-domains is definitely a design smell.

solutionDDD patterns that are applicable to the solution space (figure 1-5 page 10 of PPP of DDD)

One micro-service should cover one bounded context?

Now that we defined micro-service and bounded context, we can try to decide if one micro-service should cover one bounded context?

And of course, we still cannot decide, because we still lack the (business) context. In some business context, a micro service might fit a bounded context. In some other, several micro services will be in one bounded context. The only thing we can suppose is that a micro service overlapping different bounded contexts has something wrong.

As usual in any DDD discussion, context is king.


For more thougths on bounded contexts and micro-services, there is this excellent podcast by Eric Evans.





Time-Aware design

I already advocated how an Event Driven Architecture allows our code to be more aligned with our business. Mike has the same conclusion, focusing on Practical Event Sourcing.
But why such a system is by design more aligned with the business?onceaponatimeBecause it tells a story 

Good code must tell a story.
It must tell a story to the business experts to help them take their next decision. It must tell a story to the developers to help them grab the flow of the system. It must tell a story to the users, to help them use the software.
A story is nothing but a succession of important Events.


Because it stores root causes instead of consequences

Storing the root causes of a decision is more interesting than storing its consequences. It’s always possible to derive the current state of our system by re applying the root cause and subsequent Events.
But if only the current state is known, it is harder to find what happened in the past.


Because it is a « free » logging system

Why do we use logging at Runtime? Because we try to guess the story.
If by design we track every important Event, the logging system is « free », in the sense that no more infrastructure is required to support logging.
Events can be used retroactively by the business to look for interesting correlation in the data.


Event Driven limits

There is no free lunch though.
Event Driven systems have very low coupling, which improves maintenance, but hurts navigability. When interactions between classes are done using Events, navigation is harder to follow the flow of a use case.
It will be hard to build a team of developers used to this design, as it is not mainstream. The team will need training, to perform the required mindset shift.
Also it is often implemented with no-SQL storage, a less mature technology than SQL storage.


Event Driven Architecture introduces Time in design

We know we lack the representation of time in software despite of its fundamental impact. Even if it has limits, Event Driven Architecture is a way to fill this lack by introducing time at the heart of the software.
It facilitates the alignment of our code with our business, and with the runtime.
It allows less friction between the different dimensions.
It is a Time-Aware design.



Thanks Gautier for your suggestion to replace TimeFull by Time-Aware.




The force of Time in software

Disclaimer: This post comes in an unusual form. Carlo had the kindness to review it, and his feedback was so valuable that I actually decided to add it in the post.

To be clear, I know I’m still an alchemist. But I try to show which kind of insight “physics of software” has bring to me. Very far from being perfect, even probably far from being pertinent, but still a little bit much better to me than my previous understanding of software design.

My hope is to make physics of software (like DDD) more accessible to people less informed like me.

Carlo‘s comments will appear in blue.badge-alchemistI recently tried to explain why Time can be considered as a dimension, like Decision, Artifact and Runtime. But this dimension has some particularity : it impacts the 3 other dimensions. It’s hard to find principles or practices being part of this dimension only.

Could it be better then to consider Time as a force instead of as a property?


I tend to see things quite differently here:

  • Decisions / artifacts / runtime are spaces, not dimensions. Each of those is a multi-dimensional space.
  • Just like in newtonian physics you have a 3D space and then you have time, and time is the axis along which any change happens (movement happens in time, waves require time, etc) so in the (newtonian) physics of software you need time to complement each space. As you already know I tend to see two different kind of time in the artifact – runtime space.
  • While I understand the wish to go Einstein and model software after a single “spacetime” notion, at this stage I don’t see the value of doing so. It doesn’t mean it has no value – just that at the scale I’m working right now I don’t see the value and I lose useful concepts. Just like most engineering is done at the newtonian level, and only when needed we move to quantum mechanics or to relativity, so I suppose it will be appropriate for software. At this stage we don’t even have newtonian physics so it’s hard to say 🙂
  • I really have an hard time considering time a force, because I still need time to understand the effect of any force. You apply a force and something happens -> in time.isaac%20newton

We are software Alchemist

Carlo explains how close we are to alchemy when talking about software design.

Instead of a scientific approach, we tend to have philosophical debates on what could be the best options to design software, using terms we barely understand.

We talk about “code smells”, describing how we feel about code. We are looking for the “philosopher’s stone”.  How do we define “too much coupling”, in a non ambiguous way ? We can’t, still we argue for hours on this topic.


Force in software

In science, to define a property (let’s say thermal conductivity property) we need to understand the forces altering the object (let’s say temperature gradient). Then we can precisely define, in a given context (a piece of wood under standard pressure) what is its thermal conductivity property.

We do not have  this precision in software yet, but we could look for forces and observe how our design reacts under given conditions.star-wars-and-the-forceTime as a force

Like gravity in physics, Time in software impacts all the dimensions.

Time applying to the Decision dimension is the acceptance that we can’t foresee the future. The best known strategy is : adapt to survive. Practices around lean management emerged to cope with this fact. Flat hierarchies are pushed because it allows a company to adapt faster.

Time reveals the adaptability of our business model.

In the Artifact dimension, applying Time shows if your code is supple enough to cope with new requirements. It is the difference between make it work, and make it clean. It could work quickly, but it will take more thinking to make it clean, ready to evolve, and protected against regression. This is where we’ll need low coupling and automatic testing.

Time reveals the adaptability of our code.

To have a stable Runtime over Time, we need to be scalable, secure and resilient to hardware failure. It is hard to achieve, because it requires the software to be able to react depending on how it is used. It is a complex dimension, due to interaction between software and hardware.

Time reveals the adaptability of our runtime.


This entire section is interesting, but it’s still coming from the “alchemic” perspective. It is all very reasonable, but it written in the style of all the (alchemic :-)) stuff to which we are constantly exposed. “Time reveals the adaptability of our code”. That’s true, and if you write it in this way, it seems like time is taking an active role in that, like it’s actually going in and do stuff. But it’s not. In a scientific perspective, you won’t be able to formalize, prove, replicate the “agency” of time. If you try to be more precise, to decompose things, you’ll see that changes happen in the decision space (over conventional time), and that those changes are the forces impacting your artifacts. Conventional time is “just” the dimension that allows changes to happen in the decision space. That process can be semi-ordered or largely chaotic. But the agent is not time. The agent is change.


The adaptability property

To start from a force and try to find properties in software seems already a bit clearer to me. Not perfect but at least we can better describe what we are talking about. Adaptability in reaction to Time makes sense in the different dimensions of software. Maybe we could find some way to measure it ?


Ok, this is close to the perspective of the physics of software, it’s just that I would say “adaptability in reaction to change” (not “in reaction to time”) and then investigate the nature of change (which is something I’m actually working on). See, once you begin with change, you have something you can further decompose. Is that change a creation of something new? Is that something similar to something else we had? It’s ordered / planned change? Is it a modification of something we had? Which kind of modification? In physics we have many properties that in software are collapsed under “adaptability”. Plasticity, extensibility, malleability, flexibility, compressibility, elasticity, etc. A real physics requires this level of decomposition. But (and this is the real point here) if you only have “time” as a force, you can’t decompose further. If your force is change, then yes, you can. A first step was in my ncrafts talk, that is more about “planned growth”.adaptability-4-638The predictability property

Thinking about it, I realize it was my problem when speaking about Technical Debt. What’s technical debt ? How can we define « too much » technical debt ? It explains why I need to speak about predictability instead. Again it is not perfect, but it is less ambiguous. And Time is definitely a force helping to reveal the predictability property in the different dimensions as well.

Ok, I would say something like above. Predictability is interesting – it’s about having a reasonable model for changes, and it’s what I mean when I talk about planned vs organic change (terms that I’ve taken from urbanism). I still see time as the dimension that allows changes to happen one at a time 🙂 and not as the force.predictabilityThe philosopher’s stone

We have been looking for the philosopher’s stone for too long in our industry. It would be healthier to have a more scientific approach.
We are still very far from it, but looking for forces and properties may be a good start to improve the state of the art of software development.



Thanks a lot to Brian Gibson and Carlo Pescio for the review.

Please read Carlo’s post for more explanation about Time in the physics of software.


Coding in N dimensions

I discovered this year Carlo Pescio‘s work on the physics of software. He has a scientific approach of software design. This video from DDD Europe is a good way to discover his work.

Combined with the amazing talk from James Coplien, it gives me a lot of things to process since january to improve my understanding of software design.


Designing in 3 dimensions

Carlo speaks of the 3 dimensions in software: Runtime, Artifact (Codebase) and Decision (Business).

He explains there are interesting symmetries between these 3 dimensions. For example, a change in decision requires a change in codebase, to produce a change in behaviour at runtime.
We understand the consequences of developing hard to change code: we make the business hard to evolve. Immutable business decisions are utopian, so code must be able to adapt.

It resonates with James’s talk about symmetries in design.


A fourth dimension?

We often forget to represent time when speaking about design, as James explains.

It is a shame because use cases (what matters to the business) involves Time. We should add it to the three dimensions already exposed.

There are symmetries between Codebase and Time for example. Designing software for a one shot use is really different from designing software expected to run for the next decade.


Developer maturity

These dimensions could be useful to estimate our maturity as developer. It is relative to the number of dimensions we take into account when designing software.

Here are a few typical focuses related to each dimension:

Runtime :
We focus on technologies when thinking in the runtime dimension. We want to make it work, as quickly as possible. We are concerned with performance and optimization to have fast execution.

Artifact :
When focusing on code, we are interested in the organization of our code. We may apply GOF patterns, solid principles and other technical practices to keep our code easy to maintain.

Decision :
From a business perspective, we focus on features. What it will bring to our users? Why it will be impactful for the company? We want to satisfy the customers buying our product.

Time :
Time is interesting because it brings practices in the 3 other dimensions.
Time in the Runtime includes failure recovery, availability and logging.
Time in Artifact includes version control, and practices to avoid regression.
Time in Decision is about long terms vs short terms, and foresee what the market will need.


Maturity will improve with time

The difference may be huge between a mono dimensional and a multi dimensional developer.

The good news is we can (and must) improve with time, by learning in these different dimensions. It is normal to focus only on a few of them at first, but opening our mind to other dimensions will improve our skills as software developer.

We already have different names for these multi dimensional developers, depending on the dimensions they value. We call them Craftsmen, fullstack programmers, 10x engineers, DevOps or DDD practitioners and so on.

Do we give these names, because calling them “developer” suggests a mono dimensional person?



Thanks Brian Gibson for the feedback.


Make the implicit explicit

It is really hard to manage, or explain what we can’t see.

Based on this statement, we should continuously look for ways to reveal the important implicit concepts in software. It is our chance to explain what software is to people who don’t look at lines of code all day long. matrix


Questions like « How do I introduce -whatever practice or concept- in my daily work ?  » have the same answer. We have to make explicit whatever we want to introduce, and reveal the consequences of what is  lacking.

We have to explain which problem is solved, and how.

As long as an implicit problem is not explicit, nobody will care, it is human nature. Thinking Fast And Slow explains it very well with WYSIATI : What You See Is All There Is. We are naturally biased to neglect what we can’t see.


Make the design explicit

There are several ways to reveal a design, from high level design (modules and contexts) to low level design (Class and Functions). It starts with manual diagram, but it is mostly revealed by unit testing and living documentation.

Manual diagrams are an explicit representation of what we think our software should look like.
Living documentation is generating the representation from our code, giving information on our actual code, to know if it’s aligned with what we think it should be.
Unit testing is both a design and a testing tool. Code that cannot be tested easily was poorly designed.

We could also use static code analysis with products like Sonar or NDepend, to track cyclomatic complexity or coupling.

These tools among others help to reveal our design, not only what we think it is, but also what it actually is. Based on this feedback, we can sense and act to improve the software. Without this information, it’s almost impossible to know what could be improved, because we have potentially no idea of what is wrong in the first place.


Make the predictability (debt) explicit

Missing code coverage, voluntary design shortcuts, build breaks and defects are interesting metrics to track to reveal our software predictability. We can also track less technical indicators like overall team and customer mood.

We could unlikely keep our software predictable without revealing the consequences of low predictability.


Make the domain explicit

Our code should be aligned as much as possible with our domain.
Good alignment between code and domain means that a domain problem becomes a code problem.
The alternative is to deal with domain problems AND code problems, which could be really different.

If we’re not aligned with our domain, we’ll bring technical problems instead of business solutions.

We should reveal our domain in our code, using meaningful names for the business (Ubiquitous Language), and protecting domain centric code from infrastructure with hexagonal architecture (for example).  hexagonal_architecture_sketch

DDD core concept

Make the implicit explicit is a core concept of DDD. And it resonates a lot with the idea of WYSIATI .

It is a key to improving our collaboration with non-IT people, because they can’t understand something invisible to them.

It is a key to improving our software design, because we are not able to manage what we can’t see.

Make the implicit explicit is hard because it is endless work, but it is required to have stable foundations in a DDD project.




As usual Brian Gibson helps me to improve the language in thos post. Thanks man!



IP Blocking Protection is enabled by IP Address Blocker from LionScripts.com.