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
    "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. – Filip Milovanović May 5 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. – Luís Soares May 5 at 7:36

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.

| improve this answer | |
  • 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? – Luís Soares May 5 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. – candied_orange May 5 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 – Robert Bräutigam May 6 at 8:30
  • @RobertBräutigam not at all. A DTO should be used to cross one boundary. Not multiples. – candied_orange May 6 at 8:38

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....

| improve this answer | |
  • 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? – Luís Soares May 5 at 13:50
  • @LuísSoares, yes, you could. – Suragch May 6 at 0:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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