8

I was reading about the clean architecture, and I don't get this part:

Don't use your Entity objects as data structures to pass around in the outer layers. Make separate data model objects for that.

As long as I don't let the entities leak out through an API - that's why I create Presenters -, what's wrong with letting Entities leave the domain inner layer? Why create DTOs for that? Entities are the most stable thing in the clean architecture.

The only thing I should avoid (in the onion model) is dependencies pointing outward.. but the case I presented is pointing inward (API depending on the Entities).

2
  • 2
    "As long as I don't let the entities leak out through an API - that's why I create Presenters" - that's the same as preventing entities being passed in the outermost layers. I think that's what the quote is referring to. The layer just above has to refer to the entities, DTOs can't avoid that. How exactly you go about it all depends on how many layers you actually have, and on where your architectural boundaries are. May 5, 2020 at 1:53
  • The representer is part of the web handler.. just a utility I guess. so after that there's no more layers. But I understood your point. It's about how you structure the code. May 5, 2020 at 7:36

2 Answers 2

4

It’s called the Principle of Least Knowledge or Law of Demeter.

The more things that directly know about an object the more things break when it changes. This is why it’s not good for an object to pass through layer after layer.

Demeter says to only talk to your friends. Not friends of friends. We isolate knowledge to enable change.

14
  • Ok I understand that. But the inner layers (domain) are more stable and the outer (infrastructure) more volatile, by definiton. Would you say that's ok to start a project that you can improve later? May 5, 2020 at 7:25
  • 1
    @LuísSoares nothing becomes more permanent in software than a decision that's been spread around. Make decisions in one place. May 5, 2020 at 10:45
  • Was this meant ironically? DTOs break the Law of Demeter almost by design. The Law essentially says you can not call any methods on objects you got from a getter. You do that a lot with DTOs. Law of Demeter explained May 6, 2020 at 8:30
  • @RobertBräutigam not at all. A DTO should be used to cross one boundary. Not multiples. May 6, 2020 at 8:38
  • @RobertBräutigam: DTOs do not break the Law of Demeter unless you choose to pass it across several layers - which is a decision completely unrelated to the concept of a DTO. There is nothing stopping you from giving each layer its own DTO, which does not violate LoD. Secondly, there are no significant methods to speak of in a DTO, as it is treated as data (hence the D in DTO), not a logical component which represents business logic or behavior.
    – Flater
    Apr 12, 2022 at 9:22
6

I wrote the article you referred to, not because I am an expert in software architecture, but because teaching other people helps me to learn these concepts better myself. So take my answer below with a grain of salt.

A case for separating entities and DTOs

The entities model the essence of the problem that your app is trying to solve. They are the business rules and the business data. Even if you didn't have an app, the data and the rules would be the same. That makes these business rules very stable. They don't have to change every time you switch your database or decide to use a different REST API.

Now you could pass an entity all around your app. It even feels natural to do that because it's a convenient representation of the data that you want to use. The problem, though, is that you will start being tempted to change it. For example, wouldn't it be nice if my entity class had a toJson() method? Why? Because the REST API uses JSON. But then the API changes, and guess what? You have to change the toJson() method in your entity. So much for having a stable core.

That's where the Data Transfer Objects (DTOs) that you mentioned come in. They seem a little redundant at first, but the benefit is that you can change them any time based on the needs of the infrastructure. The entities themselves, on the other hand, still stay the same. You get to keep your stable core. The Use Cases know about the entities, but the entities don't know about anything (except maybe other entities).

A counter argument

That said, I heard a quote once that went something like this: "Don't try a more sophisticated solution until you feel the pain of using the simpler one." I think that applies here. Go ahead and pass your entities (or models or whatever you want to call them) around all throughout your app. Just keep this conversation in the back of your mind. When you start to feel the pain of having to change things that shouldn't need changing, consider separating your entities and DTOs.

In several medium sized projects recently I've actually skipped the entities and just used data model classes with methods like toJson(). I have to admit, though, that I'm starting to feel the pain. I've already changed that toJson() method a couple of times....

2
  • thanks for answering! But you can use local methods in your rest controllers that do the toJson call right? you wouldn't mess with your entities. right? May 5, 2020 at 13:50
  • @LuísSoares, yes, you could.
    – Suragch
    May 6, 2020 at 0:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.