Can someone please clarify the following topic? I haven’t found enough complex answer to this, just some basic examples of how this should work, so I am asking here.
Let’s say we have an entity Invoice. The Invoice has some private props like date issued, payment date, Items, etc.
By the principle of DDD the Domain should care only about itself and never about the world around. In case of Invoice it means, you can issue it, you can add item, you can probably change the payment date etc.
But is responsibility of the Invoice to care about extracting data from it? I mean, e.g. in Doctrine you would create getters for all of the properties and it would be definitely fine. But I believe this is not something you want to do in DDD – I think the Invoice should care only about it’s state and modifying it and not about providing hundreds of getters for all of its properties.
So my question is – what is the best way, to extract data from Entity to e.g. DTO? Is it really getters? Or should you use maybe the reflection? Entity => Transformer (using Reflection) => DTO?
By the way, when you are converting Entity to DTO, should you use the third, transformer, class, or invoke some method on Entity to convert itself into the DTO (like $Invoice->toDetailDto()
)? I think that calling ->toDetailDto
is violation of Single responsibility, but on the other side, it solves the problem with accessing private properties of Entity without using Reflection and without hundreds of getters.
Advertisement
Answer
Can someone please clarify the following topic?
This is not your fault — the literature sucks.
By the principle of DDD the Domain should care only about itself and never about the world around
Yeah, about that… it’s kind of a lie. Pouring information into an object is pointless unless there is some way of getting the information back out. (Analogy: /dev/null is an awesome database if you don’t need to get information back out of it again.)
“How do I get information out of you?” is part of the contract of the object; that part of the contract might be questions that you ask the object to get information, or it might be that the object sends information “somewhere else”, and you can look there.
For example, the cargo shipping demonstration, the Cargo “aggregate root” includes a number of methods for copying information out of the object.
For something like a DTO, part of the riddle is figuring out whether the domain model interface should include a dependency on the DTO definition. Most commonly, the answer is no: dependencies normally point toward the domain model, rather than away from it. But “no” isn’t the only possible answer; if the DTO definition is stable (because, for example, it is defined by some industry standard), then you aren’t any more likely to run into problems there than you are with using Strings or numbers.
Reflection… it can be the right choice. If nothing changes, or if everything always changes in lock step, then reflection is fine. When you need to change the implementation of the domain model and keep the definition of the DTO stable so that you don’t break clients, it may get messier, depending on how many different places in the code apply reflection to the domain model, and whether or not you can find them all when the time comes.