I probably used the term monolith a bit liberally there. But imagine you have a large chunk of your system that is very complex, because it has to deal with something with a lot of variability, in this case, different ways of doing things in different countries.
Naive strategic design here is to separate by domain (billing, invoicing, debt collection). But Bounded Contexts don't need to align with subdomains. That separation is still complex because each context needs to know country-specific things.
Instead, it could be a context for "Belgium billing, invoicing, debt collection", another for "Germany billing, invoicing, debt collection" etc.
How to get there? The constraints on our strategy are that everything is tightly coupled, that we risk breaking everything. How do we limit risk? For example, by not solving for all countries, but just for one.
We copy the whole thing, involve the Belgium experts, get rid of everything that doesn't apply to Belgium, clean it up, create better separation, set up CI/CD for Belgium, get it in prod.
Now we do it again for Germany. We start noticing that some things are in fact reusable, say invoice pdf generation, and most of debt collection. Let's extract that from the Belgium BC, reuse it in the Germany BC.
By the third or fourth time, we're a lot more comfortable, we have discovered where the variability is, we can do other countries a lot faster now.
Or, the whole idea failed with Belgium, but at least none of the other countries were affected.
It may sound like a lot of work, and it is. But what's the alternative? Nobody dares to touch the original monolith, so it just gets worse, and the three previous attempts at rebuilding from scratch have failed.
Duplicating everything is dangerous, if you think of it as an upfront design decision. But it is not if you think of it as a disposable, reversible experiment.
• • •
Missing some Tweet in this thread? You can try to
force a refresh
Reposting this thread about the coffee room conversations where the software design conversations happen. (The thread's order was a little messed up, and I want to be easy to find.)
There is a fallacy about how domain modelling works, and we need to talk about it. With software design, you're not just solving problems, you can reframe the problem itself. 🧵 /1
The fallacy about domain modelling is that we can design software by discovering all the relevant concepts in the domain, turn them into concepts in our design, add some behaviours, and voilà, we’ve solved our problem. /3
This nonsense that tactical #DDDesign isn't important has to stop. It's not even an actual opinion anyone has given proper thought, it's just a fashionable meme people are parroting. None of your strategic design matters if nobody in your org can properly implement it.
If you think tactics don't matter, you might as well wear a t-shirt saying "Ivory tower architect 4 life".
(Yes I deliberately deployed one overused meme to battle the use of another, I'm a sly fox.)
I'm reviewing submissions for a conference I'm somewhat involved it, so here's some advice. 1/n
If the number of years you've been a programmer really is the most interesting fact about you, then by all means, open your bio with that. For everybody else, make your bio about the good stuff. 2/n
"X can be challenging. In this talk, we'll look at some [techniques|patterns|approaches] to deal with X." -> Tells us something about those approaches, because if you don't, it's hard to evaluate if it's going to be worth watching. 3/n
@stijnvnh@cesardelatorre@yreynhout@Indu_alagarsamy I think the naming is sloppy and creates a false dichotomy. (I imagine it exists for historic reasons). The naming suggests that integration events somehow are not messages that convey something has happened in the domain.
@stijnvnh@cesardelatorre@yreynhout@Indu_alagarsamy I agree with the reasoning behind that, but I think the conclusion that people usually draw ("Never share domain events") is unnuanced and doesn't consider other forces. In other words, whether or not to share domain events should be a deliberate tradeoff.
The right time to fix it, is right before the cost of fixing it becomes exponential. 1/
If the thing works and you don't have to add anything, don't improve it.
If you add something, and the addition of N raises the cost of improving it with N, be on high alert. 2/
If you add something and the cost raises with 2N, first improve the system to get that particular impact down to N.
If you add something of N and the cost of improving raises with N², stop the work and do system-wide improvements first. 3/