Keynote by David Snowden
An inspiring talk about complexity and modeling, using the Cynefin framework to understand the nature of your domain (Complex/Complicated/Simple/Chaotic) and how to model and measure success according to that nature. What stood out to me was the idea that complex domains - like ecosystems, financial markets, large organizations or even "society" itself - can't be analyzed and fully understood like complicated domains. Thus, they can't be "modeled", since every abstraction will miss crucial behavior. Changes to the system will always have unforeseen side effects and insight in the behavior and side effects of changes can only be gained by running small, parallel "experiments" and checking their outcome. Parallel experiments are needed to avoid falling into the trap of the Hawthorne effect, where improvements in a system come from the introduction of change and observing the outcome than from the change itself.
Domain Language Throughout Tests, combining DDD and BDD
In a series of evolving code examples Kenny Baas showed that your behavior-driven tests - especially the browser tests - become much more understandable, if the Selenium commands that normally drive browser tests, are encapsulated in method/class names that express the domain language.
Also, I liked his heuristic of when to use the Gherkin style of writing BDD tests: If you need to communicate the behavior of your system back and forth with the domain experts, use Gherkin because it's mostly "natural language". If you don't need to communicate as much, use a BDD testing tool where you specify the behavior in code.
From Legacy Chaos to the Promised Land of DDD
A case study how a team of developers at Statoil improved their server-side legacy code to become more structured and domain driven. Interesting ideas for me were:
- Different people have different learning styles when it comes to coding practices: Some like detailed instructions beforehand, some like 1:1 sessions with experienced developers, some like fending on their own without "interruptions" and having a code review afterwards. Try to get a feeling or ask people how they would like to learn.
Feature toggles are a very helpful tool and can also be used for switching from legacy parts of the code to refactored bounded contexts while still allowing for switching back to the working old code in case of an unforeseen emergency.
From Front to Back: Homomorphic event sourcing
I was in a food coma while listening to this talk, so I fear I can't do it justice, but I'll try to give my summary.
When frontend and backend are developed independently there has to be a contract on how they communicate, how the domain commands and domain events on the frontend and backend are mapped. Usually, listing the possible inputs for the backend and the possible outputs for the frontend is manual labor, but when using the domain language, some of that test-case writing can be automated.
If you look at the domain commands and domain events of the backend, they can be seen as a kind of state machine or formal language. This state machine description can be used to generate unit tests for the backend contract and test stubs for the frontend contract, using the quickcheck library.
Find Context Boundaries with Domain Storytelling
In Domain Storytelling, you listen to the domain experts explaining the typical scenarios of their domain, while documenting the actors, events/commands and domain objects you discover in an easy to understand iconography. The resulting diagram is a mix of icons, arrows and text. Actions read almost sentence-like. Also, there is no branching involved, if scenarios need different handling, then it's better to draw different scenarios. "Three examples are better than one abstraction".
The talk introduced a way to find context boundaries with the help of the domain storytelling. Indicators that there might be a context boundary are:
- One way information flow
- Difference in language (e.g. the same thing has two names)
- Different triggers (e.g. "on demand" vs "at regular intervals")
In the workshop on day 2 we tried to model the domain of reserving and buying movie tickets in various scenarios: At the counter, on a web site, through an online app. The main lesson I took from the workshop was to avoid language and processes that are too "technical" (button, click, request, response) and think more in domain terms: reserve ticket, show seat plan, lock seat temporarily, etc. The other lesson I learned was that domains and processes that look simple on the outside, might still contain lots of complexity, as soon as you try to describe them.
Keynote by Eric Evans
In this talk the author of "Domain-Driven Design: Tackling Complexity in Software" himself talked about exploring a "supporting subdomain". This was a good example on how to sharpen your "domain thinking" skills and overcoming "Legacy Blindness", a state where you no longer see the quirks of your chosen model for a domain. The supporting domain Evans used as an example was "Times and Dates", which already has at least one solution that is widely used, in this case the Java Data and Time API. He showed his differing approaches, most of them functional, written in Clojure. The two exploration recipes were "Find awkward examples and hard-to-express edge cases in the current model" and "Produce variation".
The seemingly simple example inspired me and my colleagues to talk about other seemingly "simple" domains like "Money" and "Currency" during our after-conference beer and we discovered the intricacies there as well.
Modeling for failure
This talk was about building software systems that mirror and document real-life processes, with the treatment steps in an emergency room and the enrollment in a drug detox program as an examples. My takeaways:
You have to think about the big "state diagram" of the process and allow for transitions and their reversal that are not obvious from the first description of the process. What seems linear often is not.
"If your system has to be kept in sync with the real world, treat the real world as a very unreliable, slow external service."
There are endless debates among developers as to what constitutes "readable code". Is terse, functional code readable? Are interfaces and type hints "visual debt" or essential for getting an idea how different parts of the code fit together? (I'm firmly in the "type hints and interfaces are useful and necessary" camp.) This talk gave the debate another angle: Instead of measuring the time to read the code (where terseness wins), measure the time it takes to understand the code. While understanding is still subjective, it helps getting the idea across that you're writing code for a Target Audience first and for the computer second. The target audience are your fellow developers, some of them might not have as much experience as you. Some of them might not have the same first language as you. Some of them might not have a full understanding of the domain. When writing code, try to empathize with target audience and write accordingly. When reviewing code, give feedback on parts that you found hard to understand. When receiving such a code review, be open and friendly to people who have different ways of understanding than you.
My very personal takeaway: I always liked to store intermediate results in variables that make clear what this result is about. Recently, I've shied away from this practice, because it wastes memory and CPU cycles and the resulting code looked more "functional". Now that I realized that the intermediate variables might help understanding, I will no longer treat them as "smells" but ask myself if they help understanding or not, before removing them.
Accessibility at DDD Europe
The organizers put real effort into making the conference more accessible: In my application I mentioned that I can't stand for long periods of time and they sent me a personal email offering to help me queueing for food and registration. At the conference, the staff pointed out to me where the elevators are, I saw a "quiet room" (a good feature for people on the autistic spectrum or just introverts like me that need to get away from big crowds) and gender-neutral toilets. All these efforts made me feel very welcome and included.
The conference confirmed my belief that software development is only partially about code and mostly about understanding the world and empathizing with people (stakeholders, domain experts, users, other developers). I'm quite satisfied with the ideas and tools I got at this event that will help me and my awesome colleagues to become better developers.
A big thanks to my employer, Wikimedia Deutschland, for making this possible.