I’m learning DDD and trying to implement Repository using Google Datastore.
I find recreating DDD entities from datastore quite tricky. I’ve read there are frameworks to map my DDD entities to datastore entities, but I would like to learn low-level API first.
I though, the repository could set the state of an entity using setters, but this is often considered anti-pattern in DDD.
An alternative would be to use builder pattern, where builder instance is passed to the constructor of an entity. However, this introduce to the entity a functionality (restoring entity state) that is out of its responsibility.
What are good patterns to solve problem?
(Answer mainly coming from my comment in OP, but I think better to elaborate in an answer)
Setters are fine. The problem is the “user” of the domain entity shouldn’t access through those getter/setter. The domain entity should have a business meaningful interface, so that the application logic is built base on this. Setters should be something in the implementation level, which is used to create the implementation object (in repository etc)
I believe it is better to illustrate using an example.
This is the incorrect way for setter which consider to be anti pattern
However the more correct way is:
Repository is creating and accessing through impl, so that it have access to the getters/setters. However, your application logic is facing the interface only, and you are not implementing your logic using setters/getters (which is the anti-pattern)
The above way is enforcing through proper declaration of interface. However, if you think you can rely on the self-reputation, you can simplify the story by having both the business-logic-related methods and setters/getters directly in Impl, omitting the interface. And during your implementation, you should know that you should only use the business methods of entity (not getters/setters) during your business logic implementation.
And, it is not a simple rule-of-thumb to consider setters to be anti-DDD. In some case, for example, storing a free text comment in an entity, providing a setter as business-logic-method does not necessary to be a wrong decision.