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

WYSIATI

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.

life-without-biases-part-2-where-do-they-come-from

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.

hero

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.

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 this post. Thanks man!

 

 

 

Patterns, Principles and Practices of DDD

Patterns, Principles, and Practices of Domain-Driven Design was written by Scott Milett and Nick Tune. It gives a holistic view of DDD, from strategic to tactical patterns, and provides many examples to explain the concepts.

This book was presented to me by Bruno Boucard in this way : « It’s a very complete and modern view on DDD, and very few people have read it .» I agree, and it’s a shame.

millett_patterns_principles_and_practices_of_domain_driven_design

Why have so few people read it?

The more I read about DDD, the more I wonder if it is wise to explain all the DDD concepts, including examples, at once. It produces huge books (this one is 792 pages) contributing to the idea that DDD is complicated. It could discourage newcomers just by its size.

Also concepts and examples  do not deteriorate at the same rate.

Explanations about strategic and tactical patterns were quite the same as in the Blue Book. A few building blocks were added by the authors like Domain Events, but nothing really new emerges. It stays worthwhile to write about it, this content can stay up to date for many years.

DDD implementations on the other hand evolve a lot. The emergence of CQRS/ES and NoSql storage, the hexagonal architecture, and other practices have changed the way we implement DDD solutions in the last decade. These solutions did not exist in the Blue Book, and we can hope in 10 years it will be outdated by better alternatives.

domain_driven_design

But is it always good to have examples?

It is really hard to show examples, because DDD is contextual. It is courageous to show examples anyway, but I would not push them into production. I don’t blame the authors though, they wrote disclaimers explaining it is short examples for learning purpose.

My point is, it was interesting to write such a complete book, and I find it’s a shame it will be half outdated when we’ll find better way to implement DDD. Maybe it would have serve the authors to write better examples in a dedicated book, and keep another book to stay focus on concept explanations.

wooden_fence_png_by_camelfobia-d5kka26

Why you should read it anyway?

It is still a must read to have a modern understanding of DDD. It covers everything from integrating bounded contexts to implementing an event sourced aggregate and much more.

If you’re already familiar with DDD, it will improve your knowledge. If not, it is a very good start, even if you don’t grab all the subtleties at first.

 

 

Another article kindly reviewed by Brian Gibson.

 

The Technical Debt Myth

We assume that less design effort allows producing features faster, in the short term.  Less design effort generally means less abstraction, and tighter coupling, in order to produce working code faster.

But we tend to overlook the fact that it slows future modifications, even of unrelated features, because of tight coupling. We usually call this fact « technical debt », the term was first coined by Ward Cunningham. A better name was suggested by Steeve Freeman: unhedged call option.

option

Financial debt vs. Unhedged call option

Financial debt is predictable. You know how much you get, and how much you will pay back. A debt could be useful from a business perspective. A cash boost at the right time can create a major competitive advantage.

An unhedged call option also comes from the financial world, and is a really risky operation because it has unlimited downside. The buyer pays a premium to decide later if he wants to buy. The seller collects the premium, and will have to sell if the buyer decides to buy. It is not predictable for the seller.

Transpose to software, the difference with the concept of debt is the predictability in the amount of work required to fulfill our engagement.

When we write crappy code (tightly coupled and without tests), we collect the premium: we immediately get benefit from the new feature.

But as soon as we have to maintain or evolve this codebase, the option is called, and we have to pay an unpredictable amount of time (thus money) to achieve our goal.moneystack

Why? Who?

Every time this kind of tradeoff is required, we should ask who is asking for this, why, and who is going to pay it. Fun fact: those who ask for it (and directly benefit from it) are not often those who will pay it.

The sales team for example may ask for a quick hack because the customers « really, really need it yesterday ». But it may be paid by the production team, because next time the customer will want something, we still have to produce it quickly, without any regression. That’s where we will support more pressure, and may do some overtime.

In the end everyone will be impacted, because more pressure means more bugs, more regressions, and finally unhappy users. No company can survive unhappy users forever.

That‘s why good design matters. We want to produce current and future features in a sustainable and predictable way. sustainable_development_and_you

But what‘s good design?

We all try to do our best, but some of us lack knowledge and/or feedback. Plus, good design is contextual.

But regarding of our context, good designs have common points. It allows to think clearly about our software, and to evolve it easily. It allows to know where we should add/modify/fix a feature. The evolution-ability gives us an option on how to add/modify/fix this feature.

Software must be able to evolve because we know we don’t know what the software will be. We must design to be able to discover (as explained by Dan North in the 3 ages of innovation)

Decoupling is then required because we need to think about small parts in isolation, without side effects.  This kind of good design allows producing predictable software: robust, resilient and without regression when it evolves.

If we use shortcuts, and couple our code in order to rush it into production, we must be aware there will be an unpredictable amount of time to pay to get back into a predictable state.
It does not mean we should never do it, but we all have to understand this trade-off before asking for a “debt”.

decoupling

What about speaking of predictability?

The more shortcuts you take, the less predictable your software will be. If you pay more for well design software, you get the opposite effect.

Unfortunately it is hard to judge, as we usually think we design software well. A good way to know if we are on good track is to rely on how predictable is the software we produce. Are the customers happy? The production team? The sales team? Do we have very few regressions? Do we produce features at a regular speed?

If not, we should consider investing more on design and refactoring, before entering into a vicious circle of unmanageable software.

Order Or Chaos Directions On A Metal Signpost

The technical debt Myth.

That’s why the comparison with a financial debt is sub-optimal. Money debt is predictable, whereas software debt is not. Unhedged call option is a better name, but still comes from the financial world.

Maybe we should stop financial comparison and speak of predictability instead. I find it is a better description of the consequences of shortcuts in the design.

 

 

Thanks Brian Gibson, always here to help me to improve!

 

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