5 ms·
Domain Driven Design. The book by Eric Evans lays out a bunch of concepts and as a developer that had not owned the architecture of a big domain, it was hard fo
by theptip 4y ago
Domain Driven Design. The book by Eric Evans lays out a bunch of concepts and as a developer that had not owned the architecture of a big domain, it was hard for me to see exactly where they fit. But after reading the book a couple times, and then encountering a few tricky domain modeling challenges, I started to see where these patterns add value. Also, as I started trying to describe the cohesive domain architecture of the system to a growing engineering organization, I also clicked on the advantage of having a standardized set of terminology for the problem, rather than inventing your own. It's nice to be able to link to an existing explanation of what a Repository is for, instead of having to name and document your own ad-hoc architectural patterns (or more likely, end up with you ad-hoc architecture being under-documented).
Things like Repositories, Aggregates, Bounded Contexts, and so on are going to be a net drag on your system if you only have a few 100 kloc of code in a monolith. But they really start to shine as you grow beyond that. Bounded Contexts in particular are a gem of an idea, so good that Uber re-discovered them in their microservices design: https://www.uber.com/blog/microservice-architecture/ https://www.uber.com/blog/microservice-architecture/.
(Edited to clarify the book author)
- shortlived 4y agoThis is the book by Eric Evans?
- theptip 4y agoThat's the one. (I edited in a clarification to my original post.)
- eckza 4y agoIt's a solid book. I was chugging through it a bit at a time, until I discovered Scott Wlaschin's Domain Driven Design Made Functional. I've dropped the Evans book (as it's mired in mid-00's Enterprise Java patterns) and am enjoying this one quite a bit more. Both books are great. Read whichever one aligns with your practice best. I recommend Wlaschin's book for anyone curious about FP, without hesitation. He's great at explaining things from first principles, without veering off into "monad tutorial" territory. https://pragprog.com/titles/swdddf/domain-modeling-made-functional/ https://pragprog.com/titles/swdddf/domain-modeling-made-func...
- theptip 4y agoThanks, I hadn't seen that book -- will give it a read. I'm interested to see how DDD gets applied to the functional programming paradigm, as it seems quite deeply ingrained in OOP to me.
- eckza 4y agoYou'll be impressed, I think. It feels very natural - at least, it does to me.
- cpeterso 4y agoEvan’s book is a bit of an academic slog, but I finally felt like I understood how object-oriented design should work. An easier introduction I recommend is InfoQ’s “Domain Driven Design Quickly”, available in print or a free PDF ebook: https://www.infoq.com/minibooks/domain-driven-design-quickly/ https://www.infoq.com/minibooks/domain-driven-design-quickly...
- eckza 4y agoI have to agree! I'm only about a third of the way through; I didn't realize that there was so much about properly building OO systems that I'd simply never seen in the wild, or heard of before.
- bongobingo1 4y agoIs Wlaschins still reasonable (readable?) if you're not an F# developer (yet?) - but are familiar with FP generally?
- eckza 4y agoVery. My fsharp experience is fairly limited, but I am having no trouble following along.
- danielvaughn 4y agoThe terminology really turned me off because I found it difficult to comprehend. But I loved the idea of ubiquitous language and always meant to return to the book and give it another shot.
- theptip 4y agoIndeed, some of the names are just bad; "Anti Corruption Layer" is actually a quite useful concept for explicitly translating between concepts in different Bounded Contexts (do the translation explicitly at the edge so the mappings between BCs are explicit, instead of mixing terminology), but man I feel like something more snappy could have been used.
- feoren 4y agoI had the exact opposite reaction to this book. It seemed like great stuff when I first read it, but over time, I realized it's really misguided in a lot of ways: - Aggregates are too heavy. You need to make the decision about what is or is not an aggregate way too early in the design process. Boundaries are fuzzy. - Actual concepts don't exist in nicely packaged bounded contexts. Concepts overlap a lot. You need to make the decision about which concept fits into which bounded context too early in the design process. Boundaries are fuzzy. Things are kinda like other things. The definition of "Employee" is not the same in the Scheduling context as the HR context as the Payroll context, yet they do overlap a lot, and you can't just treat them as completely separate things. If you break everything down into tiny contexts to deal with this, you just make Contexts and Aggregates the same. - Repositories are not original to DDD and I think are very likely to foster absolutely horrific SELECT N+1 or even SELECT N^2 or N^3 performance. You simply can't let one bounded context do all its expensive operations in a vacuum; not when you have lots of contexts and lots of operations. In a complex system, most parts need to be planning, not doing. The results of most operations should be a plan that you can compose with other plans, analyze, and possibly even have an "optimization pass" if you need one. - Ubiquitous language is the right idea. If you take nothing else from DDD, take this.
- theptip 4y agoFair enough; YMMV. I've not found that Aggregates need to be designed at the beginning; I've found it works fine to define an Aggregate after you start seeing performance issues with query patterns (i.e. define an Aggregate and forbid direct access to sub-objects when you see pathological access patterns/deadlocking). Personally I've found Repositories to be a good way of enforcing that N+1 queries DO NOT happen. For example, in Django you can have the repository run select_related/prefetch_related and `django-seal` on the ORM query to forbid unexpected queries. This somewhat neuters the flexibility of the ORM, which can be a big cost, but lets you build much more restrictive queries that are guaranteed to perform well. It's a trade-off and I don't think it's a clear win for every use-case, but particularly when dealing with Aggregates I think having a limited number of ways to query is beneficial. (This might mean you're running some sub-optimal SQL queries, over-fetching etc., but for most line of business applications, that's actually a viable trade in exchange for simpler domain interfaces and protection against N+1 queries.) Regarding "planning" vs. "doing", that seems to fit quite well with doing most of your work in POJO/POPO domain models, then only rendering those into DB writes at the edges. I think Repos can help with that. (IME you get N+1 selects when you use ORM models that abstract away the SQL queries and have application code interacting directly with ORM models; if you remove the ORM from your core domain logic and force it to live at the edges in Repos, this is not possible.)