to put it more clearly, should the business rules define interface repository methods like "setDueDate(someDate)" on a TaskRepository??
I'm asking this because I'm having a debate with a fellow who would prefer it that way. Whereas as far as I did get it, e.g. regarding Ivar, Bob, DDD community and lots of others, I'd almost always go the way of dealing with entities when it comes to updates. In the above example I'd sure could have an TaskInteractor "setDueDate", but it would ...
1) request the task entity from the repository
2) validate the new DueDate
3) set the DueDate in the task entity object
4) give the task entity over to a general "save(taskEntity)" method of the taskRepository (which does no validations)
this approach also provides a single point of mutability, the entity .. or aggregate root, if you rather have a more DDD oriented point of view.
and if a validation rule would need other properties of the entity to validate against, you already have the entity by hand.
otherwise the repository itself would potentially need to validate, what would be a violation of the clean architecture, wouldn't it?
please correct me, but shouldn't repositories always deal with entities anyway, even regarding the read operations? .. even the above mentioned examples of read methods would all return entities, or (potentially read only) "ViewEntities" if you so will. but these return type classes would still all be part of the business rules and get defined as entities, even if they are simple(r) value types or read only views (where you perhaps would do JOINS in the database, or map reduces etc.).
I'd love to hear your thoughts on that.
regards
Andreas
"Overall, I think it's better if the repository interfaces deal with whole entities."
Aren't all entities business rules!? .. if "special" or not.
(remote facade/ [web] transport layer) DTOs aren't part of the "inner core" EBI, unless you mean the interactor requests and responses. but in this case the gateways must not have a dependancy to them, do they?
So you'd need seperate classes to shove the interactor request data into. what would one call them if not entities!?
"I think having the whole entity as a parameter would result in having more dann datalayer abstraction in the gateway. The Entity always has a lot of properties which should perhaps not be updated.
Ingoring this would result in datacollisions and unexpected behavior.
For Example a "Remind me in 5 minutes" could result in loosing subject changes other persons have done."
- do just a field update of the changes values
- don't do "last write wins", have some kind of concurrency control, maybe "Optimistic concurrency control" (e.g. by leveraging revisions, HTTP ETags, see: http://en.wikipedia.org/wiki/Optimistic_concurrency_control)
Another way I can think of to solve this, would be to run a separate integration test, injecting the real database implementation instead of the memory based version. But as I don't write any code without a test forcing me to, I won't have done any implementation for the real database implementation yet.