Question Details

No question body available.

Tags

domain-driven-design clean-code clean-architecture hexagonal-architecture

Answers (2)

August 8, 2025 Score: 1 Rep: 34,805 Quality: Medium Completeness: 80%

So I was reading Eric Evans DDD book and one point that was not clear to me is which Layer (in case of using Clean Code) should be responsible to

Chapter 5 has most of the details provided by Evans

you create a factory to build something whose details you want to hide, and you place the FACTORY where you want the control to be.

So in the common case, your factory methods are going to be implemented within the domain model, and therefore the interfaces declared are also going to be within the domain model (otherwise you end up with dependencies pointing the "wrong" direction between layers).

(This assumes, of course, that you want an "object" responsible for building things, vs just invoking a bunch of "named constructors").

Where things get a bit more interesting: when you want to pull the information out of some data model that your "outer" layers understand, that your domain model shouldn't be coupled too

json -> aggregate

That's normally going to be done with two pieces, one that knows how to extract information from the outer data model (the json document) and another that the other that knows how to assemble that information into an domain object. The latter part is the factory we described above, but the former parts, and its interface are not going to be of the domain and won't normally be declared or implemented there.

The other place where things can get a bit twisted: when you are dealing with reconstitution of an object in the middle of its lifecycle. Unique identifiers and other lifecycle metadata are usually copied from your persisted representations, rather than generated anew; and depending on how you manage your unique identifiers, you may need to handle reconstitution and creation separately.


That all said, there's nothing particularly magic about "factories" vs "services" or other abstractions

  • make sure the dependencies point the correct "direction"
  • when the consumer is "inside" and the provider is "outside", the service provider interface will normally be declared "inside".

Also, a caution: you can get very deep into the weeds making this part of the design "better" without actually reducing your long term maintenance costs. Invest your time wisely.

August 8, 2025 Score: 1 Rep: 87,101 Quality: Medium Completeness: 50%

In clean architecture the interfaces are devices that allow you to maintain the inward direction of references where you need some thing from an outer layer.

eg. (simplifying to three layers) Application needs to load an Entity from some Infrastructure

Application can only reference itself and Entity, not Infrastructure. So we add an Interface in Application and reference that instead.

Infrastructure can reference Application, so it can implement the interface.

Or, with a slightly less pure approach, you could allow for skipping over layers and put the interface in the Entity, since, in a single app, everything will need to reference it anyway.

In your case you have to ask yourself "Where am I using and implementing the Factory?"

Put the interface in the layer which uses the Factory, OR Entity. Put the implementation(s) of the factory in a Layer below the using layer.

Your example code follows the reference direction rule, but I would consider it slightly flawed because

  • The factory implementation is in the Entity layer.

    But you can imagine many implementations, some of which might not be pure logic, or not used by all applications. If you put all pure logic functions in Entity your Entity layer will end up bloated.

  • The repository and factory Interfaces are in the Entity layer, but used in the Application layer

    This is a practical approach for interfaces which will be shared by all components, or where the interface logicaly has to have a particular structure. But we can imagine other use case components that use factories with different interfaces, so a more pure approach would be to put the interface in the application module that uses it, or in its own shared application layer module.

My suggestion is to abandon the folder structure with layer names. The layers are only conceptual, you don't want to be moving files around when you decide that some module really should be in layer X instead of layer Y. Solidifying the layers as file structure just makes things painful.

If you hadn't made the folders in this case, your app would follow clean architecture, you just have a bunch of modules which all follow a direction of reference. If some nerd comes along and says "Your factory should in in Interface!!" you can just say "Ok I'll change that! (in my mind!)"