Cyrille Martraire: Domain modeling towards First Principles
This was a talk from the first day, but it required some more processing before writing about it. Cyrille is one of my favorite speakers. He's fast, funny and brings a lot of interesting topics to the table. So many that it's sometimes hard to keep following his train of thought, and writing down some notes at the same time.
A central concept from his talk was what he called the waterline between IT and the business. In a traditional scenario, developers get provided with "work" on a case-by-case basis. They don't learn about the general idea or plan, or even the vision, goal or need that's behind the "work item". They just have to "implement" it. It leads to badly designed code. But it also leads to the wrong solutions being delivered. If only developers could have talked with the people who actually have the problem for which they build the solution. Maybe there's another problem behind it, or maybe the business has provided the developer with a solution, instead of a problem. To higher the waterline means to get more involved with the customers and users, to understand their problems, and work together on a solution. Make sure you get involved.
When looking for the right solutions, investige the problems and use the following heuristic: "Consider the intensional alternative". Cyrille considers "intensional" a pedantic word and likes it. It's opposed to "extensional". Extensional corresponds to enumarating the results. Intensional means defining the predicate which will produce those results. Looking for intensional solutions means you'll end up with a better understanding of the problem. And also an automatable one.
While collecting these intensional aspects of existing business problems, as a developer you will be building a theory about that business. Cyrille warns against the illusion that a domain is simply a lot of information withs if-s on top. Business is messy, so we shoudn't be obsessed with rules. Some parts of a domain allow theorizing, some don't.
This nicely aligns with my own experience, trying to understand a business domain. Domain experts often aren't aware of the inconsistencies, or impossible rules they come up with. Once you bring in some logic, some rules seem reasonable but just aren't feasible. These may be areas where there's manual intervention in an otherwise automated system.
Another interesting concept Cyrille brought up was that of "skeuomorphism". He noticed that software solutions seem to continue building on technology from the past. Software systems often look like they're rebuilding a paper bureaucracy, but now it's digital. You can't really be "disruptive" if you don't think about radically different ways of solving some problem for the user. This was a bit of shock, because I realized that I often use "paper metaphors" to find out a possible solution for a design issue. Then again, maybe there's room for both - a paper metaphor as a design tool, yet a non-paper bureaucracy inspired software solution.
Maaret Pyhäjärvi: Breaking Illusions with Testing
Identifying herself as a "feedback fairy", Maaret talks about testing, in a very broad sense. It doesn't only cover automated testing, but also exploratory testing, and what you're doing with them. Tests don't break code, they break the illusions you have about it. The way Maaret explained testing, I immediately became scared of all the illusions I have about my code and that I should start breaking them.
I like how Maaret used the term "heuristics", like more DDD-ers do, to share with us how she and other testers do their work. It seems it's very common to share heuristics in the testing community. Very interesting! I don't think programmers share them as freely as they should.
Testing an application starts with realizing: you don't know much. So you have to create some sort of a map of what's there (functions, data, the platform, etc.). Start to discover, and never be bored. Always look for the interesting things, and "poke it until it pops".
In general, what you'll find is all kinds of illusions (they could be called "assumptions", I think). In testing an application ("it has high code coverage, so it's tested") but also in the general activity of developing software ("if we have this new feature, we'll earn more money").
Thinking in terms of illusions, I think most development teams are very good at them. We have all kinds of ideas about our code, our way of working, the application, our teammates, the company, etc. But they aren't really tested. It'll be smart to challenge them.
Also, looking at how others approach their problems is very useful. There will be a different perspective that you didn't think of. Learning is not linear, we are not higher or lower on the scale of "learnedness" or something. We learn different things. So, we have to look for different perspectives deliberately, thereby increasing our ability to shatter illlusions and build good things.
One last idea Maaret shared, one that I wanted to remember is: sharing the pain means more knowledge is going to be shared. I found this very relatable, but it's easy to forget. In every team or company there will be someone who "suffers" from the way they (have to) work, but it's not until they share this pain with someone else, that something is going to be changed about it. And that change is only enabled by the fact that people start sharing knowledge, and will come up with solutions, because they have a different perspective.
Eric Evans: Keynote ("Language in Context")
Starting out with the basics (words have meaning within a context; when we make the boundary of this context explicit we end up with a bounded context), Eric discussed two main topics: the Big Ball of Mud, and bounded contexts in the context (no pun intended) of microservices.
Legacy applications are always framed in a negative way, as if it's something to get away from. Personally, I've come to enjoy them a lot. However, there will always be the urge to work around legacy code. The Bubble Context (PDF) can be a great way of creating a new model that works well next to the already existing models. To keep a safe buffer between the new and the old model, you could build an Anti-Corruption Layer (ACL). A fun thing Eric mentioned is that the buffer works in two directions. The ACL also allows the old model to keep functioning without being disturbed by all the new things that are going on in the Bubble Context.
Given that a bounded context may or may not align with an actual subdomain, it may very well be that a legacy context is actually a Big Ball of Mud, with unified models, and simply just a lot of domain knowledge written between the many spaghetti lines that are in there. However, even though it is a mess, and it's getting harder to work with it every day, it may still be what you could call a "Mature Productive Context". The question is: is it still aligned with business views? If it is, we could improve at least maintainability and the cost of change by performing local refactorings. If it isn't, it'll be very hard to change anything. If the basic assumptions of the model change, rework will be very costly.
As a matter of fact, for a project I'm currently working on, we're looking into a module (or context), which requires some heavy refactoring, because it has become technically very hard to work with it. However, the business is still quite happy about it, and it's quite central to its processes.
An important Domain-Driven approach which can be used in the area of legacy code is where you analyze the different subdomains, and find out which ones are generic, and which ones are "core" to the business. As an example, in the aforementioned project there are actually two candidates for context-level improvements. One is related to Sales (which is the heart of this financial application), and one is related to Addressbook records (which is very much supportive to the Sales part). One could say it's even generic, in the sense that an off the shelf solution might be preferable. We wouldn't want to spend a lot of design or development effort there either.
Eric mentioned the term "Quaint Context" as a suitable name for a context that one would consider "legacy". It uses outdated technology probably, and has become hard to maintain. It won't be possible to make big changes there (as mentioned, because these basic assumptions can't easily be changed), so another good name could be "Patch-by-Patch Context".
With a microservice architecture, another option to deal with legacy contexts becomes what Eric calls the "Exposed Legacy Asset" (yet another nice term!). This will be a legacy application which starts to adapt to the microservices environment by producing messages that will be useful for actual microservices in that environment. For instance, database triggers could be used to produce events. The external events themselves don't have to be as low-level as the internal events that caused them.
Eric touches on several other interesting aspects of microservice architecture, but I wanted to briefly mention some other relevant ideas here. Eric looked back at 15 years of Domain-Driven Design and proposed that by now we maybe need a definition of DDD itself. He doesn't want DDD to be just a club, but asks for intellectual honesty. If you try to apply DDD and somehow it fails, you should share this story. If you're skeptical about some aspect of DDD, talk about it. I like how it boils down to focusing on the core domain, exploring models together, and speaking a ubiquitous language in an explicitly bounded context. Nice!
This one was a workshop with limited access, so I was lucky I could attend it. Rebecca had spoken in a previous edition of the conference about heuristics, which triggered my interest in the idea. The workshop was about the process behind it. It had some interesting pointers, like a PDF about the concept and a book by Billy Vaughn Koen: Discussion of the Method. Definitely things to check out!
Rebecca defined "heuristic" as a practical method, a rule of thumb. Heuristics are things you collect over time, when you find out what works best in a certain situation. They may be hints about how to solve a design problem, or how to find out what to do next, or how you should relate to something.
An example of a difficult situation in software development is when you encounter "smelly" code. Something's wrong. It needs fixing, but: do you do it now? Never? Only in certain cases? One could say: if you see a problem, fix it. Another would say: if it isn't broken, don't fix it. Or maybe: never fix it. Don't touch anything at all, because it might break.
We all have some intuitive approach in this matter, and I find it very interesting how:
- This approach changes over time.
- Many people will have many different approaches.
Rebecca suggested keeping a journal, describing and reflecting on how you actually tackle design issues.
We practiced collecting heuristics according to a somewhat fixed recipe. Here's an example:
Question: Should I fix code smells whenever I encounter them?
Heuristic: Only fix them when you're working on the code.
Example: If you're just reading the code, don't improve it just yet. If you dive in and make changes because of a new feature was requested, or a bug had to be fixed, add a test and fix the smell.
You can collect these based on your own work, and when talking to someone else you want to learn from, you can start collecting many more. When finding out which heuristics other people use, it helps to challenge them. Ask questions, find out the exceptions, the many other subtle things that should be taken into account, etc.
I found the workshop very interesting and was happy to learn more about this useful concept of a "heuristic".I feel that writing about technology has always been about exposing my own heuristics, or rules of thumb, and by sharing, maybe I can help others too. I think there's a fundemental issue with writing though: it may only "click" with the reader when their experience somewhat overlaps with the experience the writer had. You have to recognize at least part of what's in the book/article, before you can relate to it, or can "accept" it as something useful.
All of a sudden it became book-writing season. It began in August when I started revising my second book, "Principles of Package Design". Apress had contacted me about adopting it, and they didn't want to change a lot about it. However, the book was from 2015 and although I had aimed for it to be "timeless", some parts needed an update. Furthermore, I had happily pressed the "Release" button back then, but it's the same as with software development: the code you wrote last year, you wouldn't approve of today.
Because Apress has their own pipeline for manuscript to book conversion, I had to take the original Leanpub-flavored Markdown manuscript, export it to HTML, then copy it into Mac Pages, and finally export it as a Word document. That was already a lot of work. Then I started reading the book and collected all the issues, creating post-its along the way. Having every little issue on display was a nice trick. It made progress visible, and made it feel like a project I could finish.
Re-reading my own book was a very interesting experience. I noticed how often I'd been lazy and skipped a proper argument for a piece of advice. I also noticed how some advice wasn't very clear and could easily be misinterpreted.
In that regard, it was very, very helpful to have Ross Tuck on board as a technical reviewer. He pointed out several issues where the reader, given this or that background, could have difficulty understanding a section, or take unintended advice from it. Ross put in a lot of time and effort, so from this place, thanks again!
Besides revising, I've also added several new sections, most notably about the following topics:
- The reuse of code from the Domain layer, with a discussion about Domain-Driven Design.
- Why "final" classes should be preferred, and how composing objects should be the preferred way of changing the behavior of existing objects.
- When to introduce an interface for a (packaged) class.
Because there are many people who have read the first edition, who I don't want to "force" to buy the second edition as well, I've already published several articles that cover more or less the same ground:
Without further ado
So, here we are. The release of the second edition of Principles of Package Design! The book is available on Apress,com and Amazon, but it's also a "regular" book, so your book store should be able to order it as well.
Buy the e-book or soft cover via Apress
Buy the e-book or soft cover via Amazon
Do you want to review the book?
I'm very curious about your opinion. If you've read the book (first or second edition), please let me know what you think of it. It would be great if you could submit a customer review on Amazon.
If you'd be interested in writing a review on your website, blog, etc., send me an email at firstname.lastname@example.org, so I can send you a review copy.
Also, if you see this book in a store somewhere, it'd be very cool if you could send me a picture!