4 ms·
My organization was in the hype about DDD for years, so I practiced it for quite some time. I would say many parts of it is overrated. But there's still great p
by namelosw 6y ago
My organization was in the hype about DDD for years, so I practiced it for quite some time. I would say many parts of it is overrated. But there's still great parts. Here's what I learned:
1. It's a specific version of Model-driven Architecture. And the idea is very close to Hexagonal Architecture, Clean Architecture
2. There are a lot of cases when it's not worth it. If you don't have the vision to evolve your system for more than 3 years just forget about it.
3. Strategic design is more important than tactical design. You can adopt the former without the latter. If you only adopt the latter it doesn't help.
4. You don't have to adopt Microservice combined with DDD.
5. Start with coarse-grained Bounded Contexts if you're not experienced. Incorrectly fine-grained Bounded Context is simply painful.
The Good:
1. Ubiquitous languages. Even if you're not doing DDD it's a very good idea to keep in mind.
2. Strategic design. Microservices usually creates more problems than it solves, the idea of splitting Bounded Contexts helps to ease some pain of building Microservices.
3. The Aggregate. If you're doing tactical design, pay most attention to the Aggregate design.
The Bad:
1. Tactical design, the jargons like the Repositories, Domain Service, etc. IMO It's better to do the strategic stuff only, draw the Bounded Context, and let the autonomous teams do the implementation and forget the tactical stuff. They'll be motivated, feel fulfilled, and willing to improve the architecture of the fraction for themselves. In contrast to the Wizard vs Grunts (the Model Scientist vs Implementation Engineers) relations that are often seen in the financial industry.
2. The tactical jargons IMO are transient. They'll probably be starting to die out in a decade, just like most of the patterns described in the 'Patterns of Enterprise Application Architecture' from Martin Fowler.
The Ugly:
1. Don't expect you'll build models that aren't leaky. For example, your seemingly perfect model will still include tech infrastructures like Stream<User> or Flux<User>, unless you are using advanced languages like Scala and can parametrize them as TMonad<User>
2. Although it claims to help you to build pure models, the platform you're targeting will most likely still decide your model - if you're doing a traditional HTTP request/response Web project, your model will likely be a request/response one. If you think you're dreaming that you can use the same model for a real-time WebSocket project, or even a conflict-free collaborative project, good luck. You can build a real-time model in the first place, but it would be much more expensive.
3. The Repository pattern and the Aggregate pattern are like a trade-off to each other. The Aggregate wants to be rich and contain more domain logic, while the Repository stops them from being rich. As a comparison, the Active Record is much easier to be rich compared to the Repository, but it defeats the goal of being infrastructure agnostic. So if you're convinced you're going to do Web-only you can switch to Active Record + Aggregate rather than Repository. Just like 'Rails IS your application' according to DHH.
- valenterry 6y ago> 1. Don't expect you'll build models that aren't leaky. For example, your seemingly perfect model will still include tech infrastructures like Stream<User> or Flux<User>, unless you are using advanced languages like Scala and can parametrize them as TMonad<User> I'm a Scala dev and I know monads, but what exactly is TMonad<User>? Like `[T: Monad](users: T[Users])`? > 2. Although it claims to help you to build pure models, the platform you're targeting will most likely still decide your model I think that is a crucial point. In fact, the platform _is_ very often part of the domain and should be part of the language in DDD. It's one of the reasons why no-code solutions fail and why there is often a mismatch between developers and product-team - the latter does not see these things as part of the domain, but they are and if you don't describe them as it, there quickly is a mismatch between dreams and reality.
- namelosw 6y ago> I'm a Scala dev and I know monads, but what exactly is TMonad<User>? Like `[T: Monad](users: T[Users])`? Pretty much like it. There's a popular pattern called Tagless Final which lets you parametrize it and then swap the implementation in the last step. In this way the model layer wouldn't know the underlying implementation is Future, Promise, or Flux. Sometimes it's useful because the developer finds it's painful to migrate from libraries to libraries.