News for hackers. Stuff that matters.
Re:Domain-Driven Design by pydry on Monday September 27, 2021 @03:20AM (#28667988)
I noticed something similar. A minimal PR to introduce DDD on our code base ballooned the codebase by something like 1,000 lines, smattered all over the code base. I think it would have ballooned it by about 12-15,000 in total in the end if we'd used it everywhere. That would have been fertile breeding ground for bugs.

The ideas made sense on logically complex code that required frequent refactoring, but the strict separation between all the different layers simply led to a lot of code in most instance. Far too much.

We also couldnt agree on where the limits of the bounded contexts really lay. Most documentation on this issue is a mere handwave saying "you figure it out" or "it'll become clear when you do these exercises with the business" (it didnt), which is odd given how vitally important it is and how damaging it is to bound the wrong things.

Re:Domain-Driven Design by dm3 on Monday September 27, 2021 @03:41AM (#28668091)
> We also couldnt agree on where the limits of the bounded contexts really lay. Most documentation on this issue is a mere handwave saying "you figure it out" or "it'll become clear when you do these exercises with the business" (it didnt), which is odd given how vitally important it is and how damaging it is to bound the wrong things.

This is the hardest part of software design. No wonder there are no clear cut rules on how to do it. You have to be both a domain and implementation expert to get the boundaries right on the first try.

Re:Domain-Driven Design by pydry on Monday September 27, 2021 @04:25AM (#28668353)
Yeah, it is tricky. I've rewritten many a code base because I drew the original boundaries in the wrong place and their logical locations only became clear in retrospect.

I'm not so convinced that it's something you can get just by better communicating with "the business" either.

This is partly what infuriated me so about the extreme amount of code required to follow DDD patterns - 3-4x the amount of code means 3-4x the cost of that rewrite if you get the boundary wrong.

Re:Domain-Driven Design by dm3 on Monday September 27, 2021 @05:06AM (#28668578)
I find the original tactical DDD patterns as useful as the gang-of-four OOP patterns these days. Modern languages made the latter irrelevant. Modern DDD practice emphasizes getting the strategic aspects of DDD right: language and boundaries.

Doesn't matter if your code has a type named `Aggregate` in it. Matters if you get your consistency boundaries right.

> I'm not so convinced that it's something you can get just by better communicating with "the business" either.

I don't have a good answer for this. I personally try to keep my modules small so that there's not more than a ~week worth of stuff to redo if understanding of business (or business itself) changes. I often fail too.

Re:Domain-Driven Design by pydry on Monday September 27, 2021 @05:34AM (#28668747)
>Doesn't matter if your code has a type named `Aggregate` in it. Matters if you get your consistency boundaries right

I tended to find a lot written about the former and very little written about the latter.

In fact I found essentially zero practical or actionable advice about getting the boundaries right beyond just "it's important to get it right". DDD doesnt appear to have a coherent opinion beyond that.

Not in the books nor in blog posts written about the topic.

It reminded me a bit of how scrum had a lot to say about standups (the color of that shed was well defined) but very little to say about refactoring.

Re:Domain-Driven Design by ratww on Monday September 27, 2021 @08:06AM (#28669644)
I've found that separating around "abstraction levels", to use Clean Code lingo, really helps for defining good boundaries. This is really super-emphasised in Clean Code, but I find this the most important concept in the book.

Examples:

Are you writing to disk? Printing to the screen? Saving to the database? This is a different "abstraction level" than your data processing, those things should be separated by a boundary.

Are you doing hardcore math to procedurally generate a terrain? It shouldn't be on the same layer you push the triangles to the screen.

It's also about isolation: you want to control the Framebuffers in your 3D renderer? Don't let the Framebuffer class with OpenGL calls ever leak outside the renderer, even though there's encapsulation. Just use a data class to communicate between renderer/non-renderer code.

--

However, the part that is not really discussed on these books is that we should be vigilant not to "over-abstract". Sometimes you have a certain level of abstraction distributed over two or more classes, only to mirror some kind of external structure or mental mode, but in reality you want the code for those things to be together in the same class/method.

One example I run across a lot in 3D renderers is wrapping internal 3D library concepts like "vertex buffer", "context" and "framebuffer" in separate abstract objects, even when they really don't need to be abstract.

For example: "Open GL renderer" will only ever be able to call "OpenGL vertex buffer", "OpenGL context" and "OpenGL framebuffer", while Vulkan will only call the Vulkan equivalents. This means you don't need a "framebuffer" abstraction, you can have it on the same layer as the renderer. You might need a data-only, non-abstract "framebuffer" class to control it from the outside, though.

Re:Domain-Driven Design by pydry on Monday September 27, 2021 @09:52AM (#28670620)
>However, the part that is not really discussed on these books is that we should be vigilant not to "over-abstract".

To be fair, I've never really seen any process/paradigm address this. I've mostly done it based upon gut feel - sometimes abstractions seem like too much of an imposition. Other times it feels critical.

DDD just says "do way too much. all the time".

I imagine one day there will be an abstraction calculus but software engineering aint there yet.

Re:Domain-Driven Design by dm3 on Monday September 27, 2021 @10:01AM (#28670730)
This is a bit different. You are talking about a domain where the developer is usually the domain expert. You know very well what "procedurally generated terrain", "3D renderer", "database", "screen" and "framebuffer" are. Even if you don't - good and unambiguous definitions are usually just a couple internet searches away.

Now imagine you need to encode behaviours for a system where domain experts use terms and jargon you've never heard before. Even worse, users of the same system coming from different departments use the same terms to mean different things. How do you draw the boundaries there? That's what the GP finds disappointing - there is no single guide or reliable process to jump into a new domain and get the boundaries right.

Re:Domain-Driven Design by amw-zero on Monday September 27, 2021 @09:47AM (#28670578)
That's not how lines of code work - more lines can be more clear and easier to write. There are extremely concise mathematical proofs that require extreme amount of time to produce, whereas a more verbose proof takes a simpler approach but one that involves less thinking.

Same with programs.

Re:Domain-Driven Design by amw-zero on Monday September 27, 2021 @09:46AM (#28670569)
If there were a way to produce bounded context boundaries by following a general pattern / algorithm, what would that be? I fail to see how they can be created usefully without lot's of conversations with domain experts plus elbow grease. It's the part of software that remains entirely art and not science.

Why is that a bad thing?

Re:Domain-Driven Design by pydry on Monday September 27, 2021 @09:59AM (#28670714)
My impression was that it would:

* Try to mininimize the overlap between bounded contexts - loosely coupling domain models.

* Default to "too large" to begin with and institute a pattern for breaking down a bounded context into two smaller contexts.

I tend to find any process that defaults to "have more conversations/interactions" defaults to wheel spinning without some sort of specific plan about what those interactions would entail.

Re:Domain-Driven Design by amw-zero on Monday September 27, 2021 @10:33AM (#28671101)
> Try to mininimize the overlap between bounded contexts - loosely coupling domain models.

What if this doesn't lead to a more accurate representation of the domain? What if two contexts are just coupled in the business, for good reasons?

> Default to "too large" to begin with and institute a pattern for breaking down a bounded context into two smaller contexts

This is exactly the ambiguous advice that you are rallying against. How do you know when to break down a context?

It's like, building any system involving many actors and actions is hard, that has nothing to do with software. We're just digitizing the same patterns and behaviors that people have used to run companies for hundreds of years.

People want a playbook to be followed to arrive at a "perfect" domain model or architecture. I'm sorry, that sounds pretty farfetched to me. It reminds me of how we first started thinking about computability theory, when David Hilbert proposed that we should be able to devise an algorithm that could decide the truth or falsity of any logical statement (the Entscheidungsproblem). Hilbert was one of the smartest mathematicians to ever live, and he was very confident that this could be done.

Well, Alan Turing, Kurt Gödel, and Alonzo Church (not slouches in their own right) all smashed that idea with various proofs. The truth can often be counterintuitive. I am sorry that the world is complex, I also wish it weren't so.

Re:Domain-Driven Design by pydry on Monday September 27, 2021 @11:45AM (#28672107)
I think you misunderstand. I said that I thought that DDD would proscribe something along these lines. I am not endorsing this as a fully complete, usable process, I am saying that something like this is both possible and necessary for the paradigm to function.

It's a critical topic that is right at the heart of DDD. I researched up and down on this topic and unlike 'where to use a factory" the DDD community refuses to go into even as much detail on this topic than I just did with my half baked comment.

I am not trying to "complete" DDD here. I think DDD should largely be consigned to the trash heap.

Re:Domain-Driven Design by corpMaverick on Monday September 27, 2021 @11:14AM (#28671655)
> This is exactly the ambiguous advice that you are rallying against. How do you know when to break down a context?

This is a very important question. I will bite and give a guidance because no one is willing to give advice here. If you development team grows over 10 SE. Then you need to split it. So your bounded context has a complete team on it becoming experts in the subject as well as experts in the software implementation. Each team should be able to work independently of other teams.

Re:Domain-Driven Design by amw-zero on Monday September 27, 2021 @11:30AM (#28671894)
Forming your bounded contexts based on technical complexity and team configuration is certainly not advocated by DDD.

Is "larger than 10 software engineers" a rule that domain experts would suggest? Would that be in the ubiquitous language?

Re:Domain-Driven Design by pydry on Monday September 27, 2021 @12:09PM (#28672504)
How exactly does DDD advocate forming bounded contexts?

I ask because only ever heard personal opinions in answer to this question. I researched it heavily and found nothing. As far as I can tell it doesnt.

Re:Domain-Driven Design by amw-zero on Monday September 27, 2021 @01:24PM (#28673518)
I've been replying to you in other threads. There is no answer to this question, it is an art. I understand that it's frustrating, but that doesn't make it any less true.

As far as what the goal of the art is - the goal is to avoid linguistic and semantic ambiguities in the ubiquitous language. There is even a section entitled "Recognizing Splinters Within a Bounded Context" where specific examples are given:

* duplicate concepts * false cognates

If you have truly duplicate concepts across contexts, this is a symptom of the lines not properly being drawn, and perhaps a new, shared context is missing.

False cognates are the bread and butter of bounded contexts though - these occur when two areas of a business use the same exact word for something, but they mean slightly different things _depending on the business context_. The example in the book given is the notion of a "Charge," which customer invoicing and bill payment departments might both use. But each department only cares about certain pieces of data of a charge, so if one "Charge" model were created, it would be more complicated because it had to worry about all the different ways that the teams use it. And even worse, sometimes they are used in _conflicting ways_. That is a semantic collision, creating ambiguity in the model.

This is what a bounded context is meant to address. Each department gets its own model, each with its own version of Charge. The code and data is fit for the specific business purpose it's serving, instead of having a one-size-fits all model that gets the job done, but is more complicated to use in all contexts.

Honestly curious, have you read the book? I still don't think it will give you what you're looking for in terms of a prescriptive formula for "doing DDD right," but there's quite a bit of guidance in there.

Re:Domain-Driven Design by pydry on Tuesday September 28, 2021 @07:00AM (#28681344)
I'm familiar with the idea that "duplicate concepts" indicate that you should have a separate bounded context, from, I think Martin Fowler's blog? This is actually partly what I was referring to when I said hand waving.

It's conceptually similar to answering the question "How do I know where the borders of Germany lie?" by saying "ask the first person you see if they speak German".

It also conflicted with a process I followed, which was to essentially create a team glossary and agree to semantically disambiguate terms which had multiple different meanings (e.g. linux user/website user instead of just user) and even just "ban" the usage of terms which got overloaded too much.

(I discovered that semantic collisions didn't just present problems in code, it often prevented you and your team from having coherent conversations).

This could, of course, then put everything we touched as a team into the same bounded context. Or not...?

>The example in the book given is the notion of a "Charge," which customer invoicing and bill payment departments might both use. But each department only cares about certain pieces of data of a charge

It sounds like they're essentially saying (not explicitly, but via assumption), that your software should follow conway's law.

Nonetheless, this example screams "bug alert" to me, since assumptions made by departments (and, as a consequence software systems) about what they should care about are where the really nasty bugs lie - frequently driven by misunderstanding between departments about terms (e.g. what counts as a user).