The most surprising thing to me about DDD is how bounded contexts (BCs) is a linguistic boundary, and how we talk about things is dependent on where we are in the system. It feels very human, which intrigues me greatly.
To craft a metaphor; the software system is a like Europe and each BC is a country like Spain, France, Italy, and Germany. Each country can be said to have its own culture and language. During trade or tourism, the countries interface in a more limited common language/interaction. But when in Rome, do as the Romans do.
The most thrilling thing for me is seeing how one tests in hexagonal architectures. I am attracted to testing and I really love seeing how folks approach testing. The core (domain) remains the same, but observable side effects come from what you plug in. Want to send an email given some scenario? Plug in the production code. Want to test it? Plug in a module to create test assertions.
I think the underlying principles of DDD and Hexagonal Architecture are sound, but man, they make it so complicated. A good serving of KISS always helps.
- Keep your domain models separate from infra implementation stuff
- Architect your applications in sensible layers
- Decouple stuff that doesn't strictly belong together
This stuff should not need lists of XML config to get right, it's portable to any language or framework, and not just web applications.
> Keep your domain models separate from infra implementation stuff
this is a corollary of the S in SOLID -- domain models and infra implementations will have different reasons to change at different times, so they should be decoupled
> Architect your applications in sensible layers
> Decouple stuff that doesn't strictly belong together
Agreed, but this isn't prescriptive enough, if you put 5 opinionated stakeholders in a room, they may argue over 25 different incompatible ideas of "sensible". Parnas suggests arranging things into modules so that changes or difficult decisions are isolated to single modules. Basically the same idea as S in SOLID. The D in SOLID suggests a concrete way to decouple things (interfaces!).
> This stuff should not need lists of XML config to get right
agreed. the key idea is to think about the dependency graph between modules. XML config & dependency injection & so on are some techniques for managing dependencies, but it is less important that figuring out a clean module design and module dependency structure that decouples the application.
Many possible candidate dependencies between pairs of modules should be banned as they would erode the architecture and add unnecessary coupling between things that need to change in response to different forces. With some extra knowledge about the purpose of each module, it should be possible to write a small validation tool that can inspect module dependencies and automatically fail the build if someone proposes to add a bad dependency.
> This stuff should not need lists of XML config to get right
I'm "doing" DDD in "hexagonal monoliths" for years now. And have never touched a line of XML.
The XML is caused by Java (more specific its Maven build system). You'll hardly touch any XML when you build your projects in Go, Ruby (not rails!), Rust or many other languages or platforms.
You can use gradle with Java (no XML), and even if you use maven, your pom.xml won't have much to do with your application logic, so I'm not exactly sure where this idea comes from that you need XML to do DDD in Java.
Why I emphasized the not rails! part was to avoid confusion about DDD, Hexagonal and Rails. I'm convinced Rails cannot and will not be usable in a DDD setup, or Hexagonal architecture. Well, maybe if Rails is the "HTTP interface", but you'll be fighting tooth and nails to make it not use a database.
I haven't used Rails before, so I may be missing something, but is this necessarily the case?
If I remember correctly the blue book isn't too keen on modelling your domain in your database, but rather build it out of POJOs and then build a separate layer. But at the same time it's open to using DDD with a logic paradigm, which is eerily similar to a relational database. If, after you've done the necessary work with the domain experts, you have determined that Rails is the right tool for a job, I think you can safely call it a paradigm and carry on.
I'm quite certain that with some effort, and possibly some stretching of definitions, one can "do DDD with Rails".
But at that point you are going against the grain. You are both missing out on some good parts of Rails and spending a lot of time to work around or against what Rails wants and needs: Rails is very opinionated, don't forget that.
From https://en.wikipedia.org/wiki/Active_record_pattern#Criticis...
> Another critique of the active record pattern is that, also due to the strong coupling of database interaction and application logic, an active record object does not follow the single responsibility principle and separation of concerns as opposed to multitier architecture which properly addresses these practices.[citation needed][clarification needed] Because of this, the active record pattern is best and most often employed in simple applications that are all forms-over-data with CRUD functionality, or only as one part of an architecture.[citation needed] Typically that part is data access and why several ORMs implement the active record pattern.
And a Rails without ActiveRecord, while technically possible, leaves you with a Rails that is hardly workable -if at all- and brings a lot of pain. Your application will live in ActiveRecord models, spread all over:
I can’t speak from experience, but the article you linked seems to make sense.
Rails appears to have very little to do with object oriented programming, except as an implementation detail. My point is that although Evans strongly recommends OOP for DDD in the blue book, it’s not a requirement.
If the first design phase of DDD, where you sit down with the domain experts, you might discover that what you are building is really just a CRUD app. Then it’s probably wise to actually use a CRUD framework, Rails or otherwise. You’re still using DDD, and you’re not even going against the grain or missing out on framework features.
When you make your database your model you delegate “decoupling from persistence” to the authors of your RDBMS. They have already decoupled it for you in that you’re not opening files and writing data, your INSERT statement is just stating facts about your domain.
I’ve explored the pattern of putting the entire domain model in the database in the form of constraints, triggers and queries that return JSON. The controllers just map URLs to queries, validate the input and just pass the result of the query to the client without looking at it.
It’s extremely powerful and productive. You never have to think about N+1. It’s more like logic programming than anything else. The downside is that SQL and associated tools aren’t terribly ergonomic, and it’s hard to find developers who are comfortable working like that.
I think part of the point is that if you are a Rails shop first, then trying to strap DDD on is only rarely going to work. If you are a "right tools for the job" shop who decide to do DDD as a primary tool, then there might be cases where it is what you choose.
Even if you are a Rails shop first, you can use DDD to determine if it's wise to take on the project in the first place. If it turns out that the domain cannot be expressed as a CRUD app, maybe refer the client to someone else. Then you will officially have used Rails with DDD, even if you haven't written a single line of Rails code for the project.
Much of DDD is really tech independent, and takes place before a single line of code is written. This is probably also where it's the most important. You're going to have to learn the domain first or the project will be a world of pain regardless of what architecture you choose.
Yes, incredible what years of Java Enterprise can inflict to the brain :-). It reminds me of the whole dependency injection circus where in the end it's just the equivalent of passing a function constructing an instance to another function in FP.
except the container can do whatever mumbo-jumbo you may want/need, like declarative transactions, declarative permission checks, logging, publishing events to external systems, etc.
and then you have async constructed dependencies, for example when you need to ask some server for configuration first, before service can be started, and with a good DIC the whole app will just wait automatically and you don't have to worry about any of that anywhere in your app (aka you are abstracted from this)
what you have said is not technically wrong but it also over-simplifies what DI is and it brings to the table
EDIT: that said, I agree in general, that java projects are over-engineered
Most of these things can be done with higher-order functions too.
I think that if Java had had lambdas earlier, Spring and other such frameworks might look very different. You can see that already, Spring is adding (experimental?) support for more declarative styles of configuration instead of the rather slow and hard-to-debug reflection magic: https://github.com/spring-projects-experimental/spring-fu
Yes but unfortunately I don't see how it invalidates my point.
a) you either replace DIC with custom hard-wired functions (composed using any-order custom helpers) and then it's still hard-wired at one place
b) you reinvent DI with functions but it's still some magic, late-configurable, easy-to-plugin container (aka the circus which I think you were referring to and which I have said it's actually useful and worth)
Yes, you do need a certain level of indirection to achieve the things you mentioned without polluting your code with non-business concerns such as transactionality. But the key differences are:
1. Application startup is faster because you avoid reflection.
2. It's type-safe because you avoid reflection, so you get compile-time errors instead of startup errors (or worse, startup errors only in certain configurations).
3. It gives you more inspectable behaviour. You can see how the entrypoint of the application wires together components. A lot of this can be hidden, spread out over multiple places and hard to understand otherwise.
Also, I'm not the person you originally replied to, didn't call DI a circus, and actually think that DI is a useful concept per se (that some FP purists maybe under-appreciate): It could just IMHO be done in a cleaner way (and a more deliberate way, not everything needs to be wrapped in 5 layers :)) with functional constructs instead of reflection hell. :D
It's not just keeping things separate, though. It's getting the dependencies in the right direction too. I'd argue that's actually the most important part. A lot of people would look at the decoupling in a hexagonal app (or something along the Clean Architecture lines - they're very similar) and say that you don't need that much decoupling, but the patterns are very powerful; deciding to opt into that power early is a good choice to make more times than you'd think.
It helps to separate DDD strategical parts from DDD tactical patterns. The first is really intuitive and broadly applicable, while on the second you get bombarded with a flood of information, opinionated approaches and OOP-y design complexity.
There's maybe 20 companies in the world that benefit from this kind of architecture. Everyone else is just being an architecture astronaut or inventing for invention's sake.
I disagree, the company I work for is big but not massive and yet even using this kind of approach on a single product in our suite has been really beneficial. Its not as complicated as you may think, its just about keeping the code clean. Its allowed us to refactor technical implementations with much less risk and makes the code easier for people to follow. Sure it maybe a bit of a mental shift, but its not like you wont find benefits in it. (And I disagree with the insinuation that its more complex or slowing down development, I actually find the opposite is true).
Well - apparently mine is one of them. Most of software we do, was built on some variation of DDD. Most of it is not very huge - maybe couple hunderds LOC.
Spliting it in managable hunks, that can be modfied independently and do not depend on framework, libraries and other 3rd party code minimizes headaches greatly, when customers want to overhaul some part of the business processes.
From time to time, someone says "it's to complex" which tipically means "Framework I like has this opaque feature which saves me two hours of work and you don't allow me to use it". Yet in the long run math is clear.
Of course it is tool and should be used for the right job. If something is CRUD, just use your favourite CRUD generator and do not pretend you need rocketship.
you make a good point to keep things simple, "solve the problem you actually have not the one you wished you had". But, many of these ideas can have advantages even in small scale contexts. In some contexts they're not wins (e.g. extreme performance requirements might be prioritised over cost of future change) but in most situations where the cost of abstraction is negligible they're not a bad idea.
e.g. i've seen a gigantic technical mess created in a small company with less than a dozen staff -- that required a year of engineering effort to remediate -- because the application code of the company's product was not written to decouple the product's internal domain model from the external format controlled (and changed) by the first customer.
You're a 100% right with that example, I just think it's important to pry these apart as separate issues. The issues you faced should've been solved by a simple data transformation at the system boundary. "Don't let external data formats permeate through your codebase" is, to me at least, basic engineering intuition. There's no deeper meaning to be gleamed from that, the team lead displayed gross incompetence and now you have to clean up his mess.
On the other hand, these "clean architecture" blogs paint this ungrokkable colossus as a northstar -- they contrast it with issues like yours, and present this as the cure to every problem you've ever had in software. I just don't think that's true. None of these blogs ever highlight the loss of understanding. As you approach this style of engineering, you have so many layers, dependency injections and "oh and btw also this" style cross-cuts that no single use-case i.e. codepath can be understood by single person. You're just writing small units of code and hurling them at the codebase, hoping they enter the black hole's orbit and do what you want them to. I like to think that's why Uncle Bob uses huge, unexplorable celestial bodies for book covers :)
P.S. as a counterpoint to your example, I work at a company that's infatuated with the idea of microservices, with little consideration of the tradeoffs involved. A while back I had to add a feature to a new microservice that had been a few months in production. After a couple of weeks of wading through the ports and adapters, DDD-inspired architecture, I realized two things: one, this "service" is just exposing CRUD operations on a single database table with zero business logic in the middle. And two, the Data/ORM adapter layer of the architecture does not work. The migrations are never executed, the DB entities are never mapped, and SQL queryies never fire. Looks like nobody used it since it was first deployed :)
Messes are obviously bad but I dont think these patterns are the answer. They typically balloon the amount of code in exchange for nothing more than a bit of consistency and the ability to write some fairly hollow unit tests.
Hexagonal works where you have a big solid core of complex stateless business logic but thr fact that it's very common to NOT have this and hexagonal presents itself almost as a panacaea makes me hate it a little bit.
can anyone suggest links to reading about DDD & hexagonal architecture that clearly spells out: which context each pattern applies to ; what problem each pattern aspires to solve ; what advantages and disadvantages applying the pattern can have. bonus points for suggesting alternative patterns or linking to case studies / post-mortems / war stories / peer-reviewed empirical software engineering research of how these things turned out in practice.
When it comes to DDD, I highly recommend the book Domain Modeling Made Functional and the lectures the author has given based on the book: https://www.youtube.com/watch?v=9QlhkQl0DSw
Those two resources where the ones the led to really get and appreciate DDD. One thing I really liked about them is that all the examples are in F# (the functional part of the title) and so manages to make it clear how DDD and OOP are decoupled and how DDD doesn't necessarily imply OOP.
Sadly not a blog post, but i can recommend this book [0] by Scott Wlaschin. Just finished it today, the last four chapters show how easy it is to incorporate changing business requirements.
I presume you haven't read the "blue book"? Because that covers many of what you ask.
In addition, the canonical (but not clearest, IMO) source on Hexagonal architecture is by the "inventor" himself: https://alistair.cockburn.us/hexagonal-architecture/. Several links in that article are dead now, but some still work and point to excellent discussions and articles.
If you are looking "war stories" or "case studies" especially in a setting where management or colleagues need some convincing, this article of how Netflix employs it might help https://netflixtechblog.com/ready-for-changes-with-hexagonal.... I've -depressingly, actually- found that often people are easier convinced by an argument "BigCorp™ does it too" than by "its good because of X".
Recently a more practical post landed on HN. It includes CQRS, which might make it more convoluted than what you need, but even with that, it has some really nice "lessons learned" and "best practices": https://herbertograca.com/2017/11/16/explicit-architecture-0...
This book doesn't cover hexagonal architecture but I found it clearer and less verbose than the blue book. The first half of the book is on strategy and emphasizes its importance. It's a way of thinking that you can use with any architecture. It also makes it clear that only a subset of your system is suitable for DDD (not the CRUD bits for example).
https://www.wiley.com/en-us/Patterns%2C+Principles%2C+and+Pr...
Much though I dislike the author, I actually recommend the Clean Architecture book as an on-ramp for this stuff. CA is very similar to Hexagonal Architecture, and the book is more specific than any other source I've yet come across. It's written exactly with the goal in mind to tell you, clearly and unambiguously, what you should do and why, with as little room to manoeuvre as possible. That does make it a bit polemic, but when you're learning that's what you need.
It's also worth looking at Vaughn Vernon's books on DDD. The problem there is that what you end up building if you follow them to the letter ends up looking a lot less like the sort of applications that teams are used to building (which is good! The value is proportional to the level of surprise) so getting buy-in at the right stage of the process to do it properly can be hard. You need to get in at the conception stage, so if your team is used to having ideas dropped on them even partially formed, the struggle is entirely non-technical. If you try to sell DDD as "how to structure the code we're going to write now that the problem has been thought through" it's not going to work.
It’s not a book, but I found this talk quite useful to help people grok DDD - “What I talk about when I talk about Domain-Driven Design” https://youtu.be/6nrRfCkeAKU
For me an important insight of hexagonal architecture is to treat the database as either an implementation detail or a first class citizen. If you need a reliable store of data to provide your application, it doesn't matter externally how it looks. If you need to run crystal reports or support OLAP, you had better treat it as a consumer with its own stories and functional tests. Of course there can be public and private parts of the database, treated differently.
The problem I see is especially in small / mid level companies' contexts, directly trying to jump to DDD usually ends up with a really weird, half-assed implementation. On top of that, it's usually hard to get people up to speed with this kind of architecture. If you're new in the domain, changes take longer as well. You can't go back to the white board every time, re-model your domain and do big changes to it every week.
With classical MVC + Transaction Scripts you can go quite a long way, as boring as it is it can scale up to 500 people working on it. When the time comes, you will have waay more knowledge to your domain and would be able to go with this kind of approach while going towards service oriented architecture or while implementing those boundaries within your monolith like Shopify does.
Otherwise you just waste your time for the things that don't give any benefit to you in short / mid term at all. On the long term nowadays it's really rare people stay at job that long or if that time comes your company will have enough money to throw money into the problem.
The bigger problem I saw wasnt getting people up to speed but:
* The patterns dictated by DDD typically ballooned the amount of code sometimes by up to 4x - usually due to all the added indirection.
* This meant some architectural mistakes took 4x as long to fix. If you misplaced your bounded context borders in particular you were fucked.
* It reduced programming to a bit of a religious exercise where instead of having productive discussions about benefits and trade offs we argued about the "right" way to do DDD.
In my experience DDD works best when using minimal frameworks where you are free to implement most of the architecture. If you are using an opinionated ORM like Django or Rails, applying DDD can easily lead to adding layers of abstraction for the sake of it.
Ultimately, DDD is just another tradeoff, and it comes with a hefty price tag that imo is not worth it for small companies. It's not going to magically prevent your developers from delivering buggy or unstable software, and it's not going to teach your product team how to write proper requirement documents.
I've worked on a project with similar setup: Gradle packages for API, domain and infra and it was one of the nicest developer experiences I've had for backend. Better than classic monolith, in which people sometimes put stuff wherever without respecting the boundaries or microservices, which were pain to develop when multi-service communication was involved.
The cherry on top was when one of my junior collegues told me that he was struggling, since the project did not let him use dependency, that did not make sense.
I've been taking some time recently to do an exploration of programming, by reading programming history and ideas about different paradigms and domains. I started focusing on how our abstractions get destroyed at the boundaries of programs.[0] I was surprised to discover a link between Hexagonal Architecture and functional programming.
Both try to drive towards a functional core. With HexArch, you'd need an imperative shell to interact with the world at the boundaries. With pure FP, the boundaries are manned by I/O monads and effects manager in the underlying runtime. [1][2]
Unfortunately, they only seem to implement read use cases in that example. I'd love to see how they implement writes with this architecture, as that is where things are getting more complex.
Either they'd make the entity model e.g. a managed (JPA) entity model, thus violating the hexagonal architecture approach, or they'd have a separate model for persistence, but then they'd have to synchronize all changes between the actual model and the persistence model, which depending on the size of the model may be come unwieldy, as they'd loose all the comfort of dirty checking in a managed object graph.
I disagree partially. I do agree that modeling your domain in programming language objects and then transforming those objects into data stored relational tables (OR Mapping) is not a great design. However, DDD can also be done where the relational database is the model of the domain, and the application is merely a set of functions that execute SQL and transform the results. So based on the application two approaches for persistence are possible:
1) Model the domain in the programming language, and store data as opaque blobs.
2) Model the domain in relational tables, and use the application logic to extract and transform the data.
While I can get behind hexagonal architecture quite well, the more I use DDD the less I like it. It feels like doing DDD correctly is immensely difficulty, time consuming, makes code harder to read, etc... .
While everyone seems to want to do DDD, I've seen so many different approaches to it that always seem to slow down the projects as time moves on, because it becomes a constant struggle with the architecture. And for what? Benefits like a clear domain language that can be shared with the business does not require DDD. Most (if any) projects feel like they are ill fit for DDD.
"Ah, but that means you're doing DDD wrong!", I can already imagine a few people say. But I'd like to see one agreed upon approach to DDD that works when things start to get complex, rather than another super simple example that's supposed to sell you on the idea.
All these architecture and workflow methods (Agile, scrum, TDD, DDD, Kanban, even 12-factor) have a few useful and logical concepts at their base. Then people create a dogmatic religion around them, often without even understanding the why.
An experienced and reasonably intelligent person usually has no difficulty in figuring out which concepts are most relevant for a given project to increase its changes of success. In reality, that person just ends up fighting adherents of the chosen corporate or hive-mind dogmatic religion or finds themselves surrounded by people in pure ignorance of matters beyond throwing code over the proverbial wall.
You should not "follow" agile or DDD. You should understand its concepts and apply them when suitable, as part of a broad toolkit – as with anything in life.
> In a nutshell, DDD says that the most important thing about software is that it provides a useful model of a problem. If we get that model right, our software delivers value and makes new things possible.
> If we get the model wrong, it becomes an obstacle to be worked around.
This was painfully true at my last company, and we failed to prioritize naming and modelling. I regret I did not know enough to point out explicitly what was wrong. It could have saved a lot of confusion and on-boarding costs.
I still haven't applied this book fully, but I've certainly taken good ideas from it.
The main point is that language you use to talk business should be used to write code. I don't get how using ubiquitous language can slow down the projects.
> clear domain language that can be shared with the business
It does not work like that. Business share their lanaguage with you, not other way around.
Most important thing in DDD is Domain Expert. He's the cental point of strategic DDD. If you don't have one, then you either have CRUD app (which you shouldn't use DDD for - stick with ADM) or you can just use something called "DDD Lite" which is often referred to as "OOP done right".
Also, main problem w DDD (or any architectural approach) is that you have to make biggest architectural decisions when you basically have the least amount of knowledge about the system/problem.
>I don't get how using ubiquitous language can slow down the projects.
It doesnt. Ubiquitous language is more or less just a reworking of system metaphor from XP and was a fine idea even then but DDD took the idea, barely tweaked it and layered a bunch of quite horrible design patterns around it.
Ubiquitous language and bounded contexts are the best parts of DDD by far but theyre also the least original and the least well developed concepts and honestly DDD doesnt have much of anything interesting to say about either one of them beyond what they are and that theyre important.
I think this is the impedance mismatch between the intellectual and the practical all over again.
More and more, when I find myself at odds with people it’s because one of us is trying to intellectualize a situation that cannot be safely intellectualized. Not that we have changed, but that my perspective has changed.
In disciplines with more physicality, “exercises” are used quite often and routinely denoted as being an artifice. Not all instructors do and not all students listen, and so YouTube is full of videos of martial artists getting their clocks cleaned for mistaking forms for sparring, sparring for fighting. Consultants recording/cleaning up construction or landscaping disasters created by ignoring the rules - or failing to think outside of the box. You could spend the rest of your life watching these kinds of videos and not see half of them.
I don’t want to do TDD all day every day. It’s infantilizing. But I’m a better developer for having done it, and when I feel the consequences starting to add up, I will do it again for a time, to knock the cobwebs off. You probably feel the same about DDD.
DDD is about building maintainable software by trying to separate the business domain from the application technology. If there is no separation and/or the software is not easy to maintain(more than just being tired of looking at it year after year), then try something else.
It’s a shame that Domain Driven Design and Data Driven Design have the same acronym, while being basically polar opposites (some people call the latter Data Oriented Design for this reason).
To me, Domain-Driven is sort of an extension of Object-Oriented fundamentalism that used to reign, especially in the Java world. You make a class or a micro-service for every concept in your world.
It’s a great way for a huge team of programmers to write a massive amount of code that doesn’t do very much (there are always exceptions, of course!) - with elaborate contortions to model and name everything just right. You might wind up needing things like Dependency Injection frameworks, mocking frameworks for tests, etc.
Data-Driven is the idea of leaning in to the fact that fundamentally, your software is a program, running in computers. It is going to turn some input into some output. You design along the axis of what data you need, how it is represented, where it needs to go, what transformations need to be applied, what output needs to be produced, and what needs to be stored. It tends to look more like functional programming, although you can certainly also apply mutating transformations, usually for efficiency.
IMHO, the latter is a great way for smaller teams to produce modest amounts of code that accomplishes a great deal.
I don't agree at all. They're very orthogonal concepts, and DDD has very little to do with OO. For an example, see Domain Modeling Made Functional.
Yes, if you do DDD in Java, you should probably follow OO principles. If you end up with a lot of classes "that do nothing", you've probably done something wrong along the way or you've applied it to something very simple where it didn't make sense to do so.
I agree very much that DDD is an extension of OOP in many ways, but very much disagree that DDD (or OOP) is synonymous with "lots of code". OOP (like any principle) is easy to misuse/abuse when doing it for the sake of it, and so personally I'd discourage OOP (and by extension, DDD) for anyone who isn't confident that it fits their model of thinking, nor if they're unaware of the pros and cons... but good OOP (what little of it exists) is very powerful as a way to translate business logic into code. Most non-technical people do not talk about data, and do not think about programs as data transformation, they think about their domain, and they are best served by code that represents their understanding of the business, not some developers decision about how their business is best represented using data.
Essentially, I'd describe DDD as high risk, high reward, and so for most businesses, it's not the right decision. However, if you have a talented and experienced team that deeply understand both the business and programming, then DDD is a great opportunity.
Scott Wlaschin has been on a "crusade" for years to decouple DDD from OOP and show that doing DDD in a functional language (he uses F# for all his examples) is not only possible, but preferable. He might not change your mind, but it will make you look at DDD from a new angle.
> they are best served by code that represents their understanding of the business
Genuinely curious why you think this is? To me it seems a massive leap?
Trying to steel-man this, if:
1. The people who know best about the domain are not technical and don’t know algorithm thinking
2. The technical people are not capable of understanding the domain enough to separately discuss what the code does and how it does it
This is basically the consulting scenario, which is where DDD came from (?) Then it would make sense - when the team leaves and the next guy comes in with no clue how it works, he can read it out to the domain expert who will roughly understand what it’s doing.
On the good teams I’ve seen, the domain experts and the people coding are the usually same people, the “domain vocabulary” is CS, and the team is looking for maximum leverage (trying to do with 10 ppl what others do with 100 people).
So it’s quite a different scenario than 100 ThoughtWorkers getting dropped into some vertical they know nothing about and being expected to model a bunch of existing business processes.
Everybody within a business should be using the same language and concepts when thinking about the business, because it's important for effective communication: daylight between what people are thinking about is where problems creep in. The role of any people of any discipline within a business is to use their expertise to shape _how_ they think about the shared _what_.
Code is just one tool (of many) that a business will use to achieve its goals. There's a mythology in a lot of businesses around the genius of technologists because we understand the complex system that we built that everybody else in the business is too dumb to understand, but in reality it's because technologists are uniquely permitted to decide they're better than everyone else and diverge from the shared thinking because it's easier than reconciling business concepts with technology -- which is where the actual hard part of software engineering is!
If you walk into any business that has been around for a few years and has allowed their technology team to do whatever they want, you'll probably find a completely incomprehensible system that the business hates because it has diverged so far from how they think and what they want that they can't effectively do their jobs.
People come and go, the only constant in a business is the business.
An example that comes to mind is a business that has customers who pay for membership, and so they're called "members" within the business. However, the development team decided they knew better and implemented "user" accounts which can have a "subscription". Then, later, the business decided to introduce a subscriptions product... and so the problems began.
I’m not sure I understand this comment — aren’t the two different things?
DDD is a business-to-software paradigm to decide what software to build, defining the relevant terms — what the data is, how it’s used, etc.
DOD is a framework for turning that map of relationships into a technical implementation, as you can see from the inputs to DOD being the outputs of DDD.
I see it as frontend (DDD) and backend (DOD) in a compiler chain of business needs to technical system.
> It’s a great way for a huge team of programmers to write a massive amount of code that doesn’t do very much
Yea. I often hear the excuse "it's for many lines of code written by large teams" but what's often ignored is that all this code is not doing much actually.
DDD seeming as an extension to OOP is no co-incidence. An intro page[0] for author Eric Evans shows:
> Eric Evans is the author of “Domain-Driven Design: Tackling Complexity in Software,” Addison-Wesley 2004.
> Since the early 1990s, he has worked on many projects developing large business systems with objects with many different approaches and many different outcomes. The book is a synthesis of that experience. It presents a system of modeling and design techniques that successful teams have used to align complex software systems with business needs and to keep projects agile as systems grow large.
> It’s a great way for a huge team of programmers to write a massive amount of code that doesn’t do very much (there are always exceptions, of course!) - with elaborate contortions to model and name everything just right. You might wind up needing things like Dependency Injection frameworks, mocking frameworks for tests, etc.
Damn. Talk about calling out my team. Like, perfectly describing our current project.
And, as expected, even correct unit tests will randomly fail.
I never found domain driven design to be an extension of object oriented design or microservices. Its mainly a way of organizing your code so it doesn't turn into a big ball of mud at some point.
To craft a metaphor; the software system is a like Europe and each BC is a country like Spain, France, Italy, and Germany. Each country can be said to have its own culture and language. During trade or tourism, the countries interface in a more limited common language/interaction. But when in Rome, do as the Romans do.
The most thrilling thing for me is seeing how one tests in hexagonal architectures. I am attracted to testing and I really love seeing how folks approach testing. The core (domain) remains the same, but observable side effects come from what you plug in. Want to send an email given some scenario? Plug in the production code. Want to test it? Plug in a module to create test assertions.