28

I have been studying Clean Architecture (CA) by Robert C. Martin and have found it quite useful in promoting architectural standards for large applications. Through implementation of a case study, I have a bit of experience of how it can help build applications that are more flexible, robust and scalable. Finally I have also come into grips with its potential shortcomings (many of which are outlined in this excellent response).

My question, though, is how Clean Architecture relates to Domain Driven Design (DDD) by Eric Evans. While not quite as familiar with DDD, I have noticed many similarities between DDD and CA. So here are my questions:

  1. Are there any differences between CA and DDD (other than their naming scheme)?
  2. Should they be used in tandem, drawing insight from both, or should one be used over the other?

From research, the only thing I was able to find on this was that CA "uses higher level of abstraction on the business objects" sourced from here.

Matthew Knill
  • 403
  • 1
  • 4
  • 8
  • 3
    Clean Architecture is a software architecture. Domain-driven design is a software design technique. – Robert Harvey Mar 02 '20 at 04:30
  • 1
    Thanks for that... While DDD is likely more technique based, I see architecture and techniques outlined in both. [Here](https://khalilstemmler.com/articles/software-design-architecture/domain-driven-design-vs-clean-architecture/) is one of the few sources I found that outlined a comparison between the two. – Matthew Knill Mar 02 '20 at 05:09
  • 1
    May I point out a few issues with that article? 1. `"There's a construct for everything."` -- **False.** This is what causes "pattern-based thinking" in software developers. We need more developers that know how to think for themselves and solve problems, not just folks who can follow incomplete sets of patterns. 2. `"Every developer has a different name for these constructs."` -- **Mostly false.** The vocabulary is fairly standardized, if you stick with the well-known constructs. – Robert Harvey Mar 02 '20 at 14:06
  • Unless, of course, the author is talking about every algorithm and data structure that's ever been devised and the ones that haven't been thought of yet, in which case, of course, there's a construct for everything and folks do tend to give them novel names. I'm not sure what that has to do with a comparison between DDD and CA, though, two concepts that are already very clearly defined. DDD is largely about naming things: what is this business process? How can we describe it in words we both understand? CA is largely about program structure and separation of concerns. – Robert Harvey Mar 02 '20 at 14:09

4 Answers4

41

You are correct that both focus on separating the domain code from the application and infrastructure code. But that is where the similarities end.

In Clean/Hexagonal/Onion (or CHO in short) architecture, the goal of this decoupling is testability and modularity with intended effect being that the "core" of our software can be reasoned about in isolation from rest of the world.

In DDD, the main goal is to establish common language with the business experts. The separation of the domain from rest of the application code is just a side effect of this main goal. It also has some say about the design of classes as entities and aggregates, but that is only within the domain itself. It has nothing to say about design outside the domain code.

In practice, you might find that you use both at the same time. You use CHO architecture to design the whole structure of the system, with the "domain core" being isolated in it's separate modules. And then you use DDD to design this domain core in collaboration with domain experts and possibly by using DDD concepts like Entites and Aggregates.

Euphoric
  • 36,735
  • 6
  • 78
  • 110
  • 1
    I understand that this could open up a whole new ballpark. However, from this, would it suffice to say that DDD is closer to Design Thinking than CHO? – Matthew Knill Mar 02 '20 at 07:44
  • @MatthewKnill I don't know about Design Thinking, so I cannot comment on that. – Euphoric Mar 02 '20 at 08:15
  • No problem [this](https://www.interaction-design.org/literature/article/what-is-design-thinking-and-why-is-it-so-popular) is a great resource if you are interested... – Matthew Knill Mar 02 '20 at 09:40
4

DDD is a paradigm that tries to help you decide how you develop certain kinds of software by applying certain strategies and tactics. It is a fundamental part to understand the domain and create a model of it in your code that uses domain terminology to implement the domain logic. As such domain-centric designs can help with implementation and evolution of your domain logic.

Clean Architecture, as one example of domain-centric architectures, is a certain way to structure your code to achieve certain properties during evolution. In particular the domain layer can be used to implement domain logic as mentioned above. CA tells you where your domain layer is placed within your software design and how dependencies should flow across layers.

DDD merely states you should reflect your domain model in code, it does not tell you how to organize it in layers as CA does. CA does not tell you how you can align it with the domain by using strategic or tactical patterns as DDD does.

Hyggenbodden
  • 137
  • 3
  • Just to clarify, are you saying that CA is more focussed on the finer details of software development whereas DDD is focussed on designing through the use of domain experts? – Matthew Knill Mar 02 '20 at 07:48
  • I am not sure whether finer details is the term I would use. In a way DDD with its tactical patterns is more detailed on how to structure a domain model. But it merely says that it should be reflected in code, not anything about how the code should be organized in layers. Both have a different perspective, not the same on different levels of detail. – Hyggenbodden Mar 02 '20 at 09:18
  • @MathewKnill I updated my answer. – Hyggenbodden Mar 02 '20 at 09:39
0

Domain Driven Design is just a set of principles for modeling the core layer of an application. It is more about strategies, patterns and practices for designing the most important layer of any domain-centric architecture – the Domain/Business Layer.
CA on the other hand, just explain how should an overall system architecture look like.

-1

If you look at it from the perspective of object-orientation, there is really no visible difference at all. Both CA and DDD are procedural approaches, and try to improve on the usual procedural architectures and designs (like the Layered Architecture, etc.) by introducing some constraints that are technical in nature and somewhat arbitrary.

They differ on these arbitrary constraints. CA tries to completely isolate the data from its behavior, while DDD partly acknowledges that the application should be about whatever the business tells us, but then goes into things like data (again), transactions, and technical layers.

You could say, that while DDD is a couple of steps from procedural towards object-orientation, CA goes in the opposite direction and doubles down on separating data and logic everywhere where it can.

There are some projects with requirements where you could borrow ideas from one or both of these things, especially from DDD. However, we have object-orientation, which is superior to both in most circumstances.

Robert Bräutigam
  • 11,473
  • 1
  • 17
  • 36
  • How does CA separate data and logic everywhere? The data in CA is in the entities, which can properly encapsulate that data and only provide access through a public API. I.e. through encapsulation, the entities can ensure that data and logic are bound together. – Jordan Walker Oct 13 '20 at 11:49
  • Take a look at [Uncle Bob's "Case Study Project"](https://github.com/cleancoders/CleanCodeCaseStudy) on this. That is how it looks in real life. Also, while you *could* include some logic in the entities it would be severely limited. 1. It can't really use any technology (that is separated). 2. All the interfaces between layers is data-only, defeating any encapsulation you might try. That leaves you with some trivial stuff like standalone data validations, some calculations that don't need anything else, that's about it. – Robert Bräutigam Oct 13 '20 at 14:15
  • Yeah, that repo is not useful at all, because it has 0 business rules -- there are only two use cases, and they're both queries... That's why the domain is anaemic. To your other points... – Jordan Walker Oct 13 '20 at 16:53
  • 1. That's because it's job is to encapsulate data and corresponding logic, not interface with external technologies -- the single responsibility principle. I wouldn't call that a limitation, just proper separation of responsibilities. 2. The data is still encapsulated because you can't mutate it without going through the object. The data has to get out somehow, otherwise what use is it? If objects are to interact with each other they have to be able to share their data at some level, just in such a way that they each maintain control over the validity of that data. – Jordan Walker Oct 13 '20 at 16:53
  • Encapsulation is not just about write-protection. It is protecting *knowledge*. The data in an object is supposed to be a technical detail, not the API of the object. Objects interact by asking each other to perform some function, not to ask for data. Objects might return the new objects that have some of their data re-packaged, with a different semantic (this is important), but never return their internal data with their own semantic. CA is so alien to this, it is hard to even understand the reasons why someone would call CA even remotely object-oriented. – Robert Bräutigam Oct 13 '20 at 18:37
  • But at some point you have to hydrate those objects with input data, and get the data back out so you can output it somewhere. You can’t _only_ have objects — you have to have primitive types at some point. A program without input/output isn’t any use... The knowledge that objects protect is how to properly manipulate the input data, not merely the fact that they have data. – Jordan Walker Oct 13 '20 at 19:30
  • Valid question, so how can you have output if you can't get data out of an object? Well, just ask the object to output itself. Not output the raw data, but the "end-product" of what is needed. If it is a `WebComponent`, ask it to write HTML to a stream. If it is a `Person` ask it to create you a `WebComponent` to represent itself. At no point can you access "name" or whatever a `Person` usually would need. "Data" is irrelevant. Of course there is nuance, and this is just one simple case, but this is how software becomes maintainable. – Robert Bräutigam Oct 13 '20 at 19:54
  • Think of all the different ways you’d want to render data from a domain object. Not to mention css, js, html attributes and what not. Would you have a method for every possible html display? And email representation? And persistence mechanism? Doesn’t that seem way less maintainable? Also, how would you get the data in there in the first place? And if you can pass data in, why is it unreasonable to expect to get some modified version of that data back out? – Jordan Walker Oct 13 '20 at 20:51
  • The most complex object I ever saw had 3 ways to represent itself. That's 3 methods with 3-4 lines of code at most. Remember there's still abstraction, so there's no css, js or things like that involved. It's difficult to explain how much more maintainable everything becomes, when relevant methods are together. I urge you to sincerely try. Just for fun. It's different, and not always as easy, but it's worth it. – Robert Bräutigam Oct 14 '20 at 07:36
  • I’d be really interested to take a look if you have a repo with an example web application? Or know of any I could look at? – Jordan Walker Oct 14 '20 at 17:29