I was inspired to such an extent by Evans’ Blue Book, that I got passionate about Domain-Driven Design. I was still in the United States when, four months in advance, I registered to the Strategic Domain-Driven Design workshop conducted by Alberto Brandolini (aka ziobrando) and organized by Avanscoperta. I definitely wanted to attend.
Then, taken from the day to day activities, I lost the sense of time, when mid-October, I received an email from Avanscoperta that reminded me of the upcoming course. I felt like someone had given me a weekend at the spa!
What does it mean to develop software?
One of the first interactive activities proposed by Alberto, was to define software developer role using other “professions” as a metaphor. The most popular professions identified by the class were the architect, and the craftsman, while ziobrando proposed roles that were not immediate but very suitable:
- the artificer: when we have to manipulate code written by someone who “no longer deals with the project”;
- the Fifth Beatles: that is the one that everyone blames when there is an issue, while is invisible when everything work as expected;
- the cartoonist: we often have predefined deadlines, and we have to be creative in using our art to maximize the result in the remaining time.
The artificer is the metaphor that impressed me most. I have recalled the times (many times) when I was asked to work on existing applications and solve challenging problems without any kind of test support. And thinking back about those situations, I wonder how I didn’t end up as Dylan did in the 17th episode of the second season of Gray’s Anatomy!
This chat has led Alberto to present and explain his model of software development, whose skillful illustration is shown below.
This model represents software development as a cocktail of four components: build, learn, decide and wait/nothing.
Build: this could be considered the simplest, and less enjoyable part of software development. This phase starts when we know exactly what we need to do, and how we have to do it. This is the most deterministic and plannable part of our work, which best fits a waterfall approach. If it was not for the other components, each software project could be managed following the same deterministic approach as building construction.
Learn: when we start a new project our ignorance is high. We ignore what the customer really wants, we do not know the best way to solve the problem, and which architecture is the most appropriate. Usually, during the lifecycle of a project we gather inputs that allow us to learn and clarify key aspects, while our ignorance decreases. Note that people maximize their learning when are unstressed and not afraid, because stress and fear are learning inhibitors. Moreover, learning is not linear in respect of time. For this reason, development team must feel free to invest time to deepen the most critical aspects of the project, whether technical or not technical.
Decide: we take decisions continuously, whether they are related to a pattern to use, the usability of an interface, or system architecture. The previous section highlights the fact that we often have to make decisions even if there is lack of information or we ignore some of the factors that, instead, should be considered for being able to take better decisions. Therefore, we must try to put ourselves in the state in which our decisions are reversible. Further, we must try to postpone relevant decisions as far as possible. That is when our knowledge is the best possible, and decisions are still valuable to the project.
Waiting/Nothing: we often spend our time waiting for someone or something. Maybe we wait because we lack information or test data. Or we wait someone else to finish a development in order to start our task. This is clearly a waste of time that we can, and we must optimize. Fortunately, there are precious tools, eg. Lean and Kanban, who can help us to address these issues. The resolution of this kind of problem lets developers focus on the real challenges of project, and to address them to the fullest.
Each company mixes these four components in its own way. Obviously, there are more effective proportions then others. This made me think of Negroni (my favorite pre/dinner Italian cocktail) cause using the same ingredients you can serve the best cocktail ever, or the worst undrinkable mix!
Strategic DDD in a nutshell
Before going toward the most interactive part of the course, Alberto made a brief introduction to the strategic concepts of DDD, highlighting when it is valuable pursuing this methodology.
DDD requires commitment in terms of time and effort from the development team and business. For this reason it makes sense to apply it only to those projects with high added value: complex and/or evolving domains, i.e. for those domains where it is very challenging to find the right solution at the first attempt. In these cases, the effort required by the constant refinement of language and models, both peculiar of DDD, is justified by the increased capabilities to pursue the ever-changing business needs.
For such complex projects, the real challenge is to be able to align our code with our domain understanding, and both with the real domain which is constantly evolving. If we can keep the code, the understanding we have, and business expectations aligned, we have the chance to respond quickly, and effectively to the market trends and new business requirements. Otherwise our project is going to fail as soon as the external changes are sudden enough to not let development team be able to fulfil new business requests in the available timeframe. DDD provides two very powerful tools to keep valuable alignment: Ubiquitous Language and Bounded Context.
As the name itself says, Ubiquitous Language requires a single omnipresent language within the project. The language has to be the one of domain experts and not of technical experts. Also the code should reflect that language: in this way the code will effectively communicate its intent, and will be more easy to understand and maintain it. Ultimately, less translation between the language used from business and technical people, extremely improve the effectiveness of communication.
Unfortunately, it is not possible to expect that everyone within an organization uses the same terms with the same meaning. Even with “trivial” terms, same word can be interpreted in very different ways in different contexts.
To solve this problem, it is essential to use Bounded Context. A Bounded Context is a linguistic boundary within which every term has only one well-defined meaning.
DDD requires developers to use a clear business oriented language which has to be reflected also in the source code. This assumption led me to the following question: if we are working with domain experts who speak Italian, should we “program” in Italian? The answer is much more articulate than you might expect! Analyzing the topic with ziobrando, it came out different shades.
Even if the programming languages are Anglophones
for, getter, setter, etc.), it should not be an impediment for using the
terms of Ubiquitous Language. Therefore, a method named such as SetIndirizzoSpedizione
(“indirizzo spedizione” means shipping address) is acceptable if you can increase
code comprehensibility w.r.t the related domain.
What if the business speaks Italian but developers don’t? In this case we should find a solution that keeps in place an effective communication with domain experts, and, at the same time, allows developers to easily understand the code. For example, we could build a shared glossary of terms that contain translations of the language used by business experts and by developers.
This leads to another question: is there a translation for each concept expressed by the business? For example, there are business concepts that can be expressed in Italian, and cannot be translated in English due to cultural/laws diversity.
In DDD this “linguistic” problem had yet to be addressed systematically. Note that Eric Evans is American, and probably he has always worked with teams and domains where English was the only language used.
Again, the continuous knowledge increase within the developers team, and the adoption of a single and not ambiguous language using terms that represent business concepts, are essential for the success of a project. What tools do we have to reach these ambitious goals? To answer this question, ziobrando presented a tool invented by him: Big Picture EventStorming.
Big Picture EventStorming
As mentioned in the subtitle of ziobrando’s book, Introducing EventStorming, EventStorming is “An act of Deliberate Collective Learning”. In particular, it is a tool that allows you to explore/model a whole domain/business and to share knowledge. If we assemble in the same room people who have the knowledge, who make the right questions, and someone who facilitates the discussion, we can holistically model an entire business process which can be used as a tool to better prioritize activities, and take decisions.
To explain how EventStorming works, and to let us savor what it could mean to participate in a real modeling session, Alberto engaged us in a role playing game: he chose the Italian primary train operator, Trenitalia, and he assigned to each of us a role to play (stationmaster, passenger, etc.).
Prior to start this real modeling session, we had to arrange the logistics in the room with two simple components:
- an almost unlimited modeling surface, in our case at least ten meters of wall!
- a tons of orange sticky-notes, on which to write the events of the domain, with verbs in past tense, and temporally ordered on the available surface (from left to right).
Without going into the details, for which I recommend to participate to Alberto’s workshop, after four hours of work we managed to shape a slice of Trenitalia’s business, including the views of all the actors involved.
Beyond the impressive visual impact, which nevertheless gives satisfaction, the exercise allowed us to:
- have a clear value chain and business processes understanding with the narration made through domain events;
- capture the definition of specific domain terms. We utilized sticky-notes with rows, and we placed them below the modeling surface;
- highlight all the critical nesses of the system (fuchsia sticky-notes), whether due to misalignments between business areas, customer experience or something else;
- propose possible improvements to the system (acid green sticky-notes… btw, initially I thought was a sort of yellow… and for that I felt color blind throughout the workshop!)
- identify clearly who are the people involved in the various streams (small yellow sticky-notes);
- identify the external systems with which our business is interacting (big pink sticky-notes).
All the information, visible at a glance, allowed us to easily spot issues/opportunities to be addressed with the highest priority. The choice was done with a vote in dot voting style (small blue stickies). The most interesting aspect is that there has been consensus when we were requested to vote on the critical issues. This is due to the power of sharing. An EventStorming session inevitably leads to a strong alignment in understanding business priorities.
This clustering of choices created strong engagement and commitment of all participants to solve the identified problems.
Since the discussion may raise some conflicts between the participants, it is crucial to have a facilitator who can help with the comparison and maximize the contribution of all participants.
EventStorming is definitely a powerful tool to have in your toolbox.
Process Modeling EventStorming
During the second day of the workshop, Alberto changed the focus of our analysis. Having now clear the business priorities, as a result of the previous day, we selected a problem and we have thoroughly analyzed it with the aim of designing the software needed to solve the problem itself. To do this we relied again on EventStorming. In particular, in another variant named: Process Modeling. The scope of such modeling can be an epic or a feature.
We relied on the same components: wide surface for the modeling, and orange sticky-notes representing domain events. This time with a different goal: find, and design, the solution to a specific problem. To do this we started by creating a skeleton of domain events related to the problem under examination, and then we tried to connect the events by building a consistent narration using the following elements:
- users, small yellow sticky-notes, or people interacting with the system;
- commands/decisions/actions, blue sticky-notes, taken by users in response to some need or stimulus (see read model below);
- system, large pink sticky-notes, which modify their state following user actions;
- domain events, orange sticky-notes, generated by systems as a result of state changes;
- read model, green acid sticky-notes, built from events.
In turn, the read model, can be further stimulate the user to take other decisions and then modeling can continue following the same pattern.
An exception to this flow is the reactive logic that can be present in the process. For example, the system can send automatically an email after a ticket sale, or a ticket controller must do the fine after a failed verification. These examples are both policies which must be identified in the modeling process. The difference between the two, is that the first will be implemented in the code while the second is a rule which the ticket controller must apply autonomously and which is still part of the process.
To make more efficient the modeling, we first analyzed the simplest case, that is, where the interaction between the user and the system is more linear. For example, thinking about purchasing an online train ticket, we should analyze the case when there are available sits, user pays with a valid card, etc.
During the modeling of the simple case, we marked potential alternatives (e.g. invalid credit card) with fuchsia sticky-notes. As soon as we completed the analysis of the simple case flow, we came back on our steps to analyze the most significant alternative. This process can be repeated until you cover the most significant scenarios. To do this kind of assessment it is always useful to have a Product Owner, or any domain expert, who participates in the modeling phase.
An important aspect we captures during this session was the value created or lost for all users involved in the various steps of our solution. This is very important to verify that the solution identified to solve the original problem, as a whole, increases the value to the system.
Another very important aspect of this session was the attention we paid in refining the language used. This was essential to define clearly and unambiguously concepts during the modeling.
The second day ended with a closer look at Context Mapping and the relationships that may exist between the different contexts in a domain: Partnership, Shared Kernel, Customer/Supplier, Conformist, Anticorruption Layer, Open-Host Service, Published Language, Separate Ways and Big Ball of Mud. You can find many details on this subject in Eric Evans’s book DDD Reference, and many other online resources.
It is impressive to note how the DDD remained the same in its core concepts, while the way developers build applications and the available technologies have drastically changed. This is definitely due to the robustness of the approach and the attention given to the creation of a model that is infrastructure and technology agnostic.
CQRS and Event Sourcing definitely deserve an in-depth practical examples, and my next post will be on these topics.