Pergunta

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

Foi útil?

Solução

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.

Outras dicas

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

Licenciado em: CC-BY-SA com atribuição
scroll top