RE: [domaindrivendesign] Re: Entities accessing Repositories?
- That's an interesting viewpoint ("I would not have a domain object reference a repository"). I guess it depends on what is meant by "reference". I recently implemented a method on a domain object that <<uses>> a Repository, and felt it was perfectly natural.
I have a class of domain object, HumanResource, in my application, and a HumanResource needs to be responsible for answering its collection of Assignments (to Positions). As an aside, an Assignment is a relationship between a HumanResource and a Position, and I think "relationship objects" like Assignment are a special kind of Entity that deserve further recognition and discussion. But I digress.
From the perspective of HumanResource.getAssignments(), I have basically two options: return the value of an instance variable, or return the result of invoking a method on some other object. While it is true that O/R mapping solutions make it easy to transparently "hydrate" the collection of Assignments, and bind it to the HumanResource's instance variable (if I choose that option), there are reasons why I don't want to do that. First is heap consumption: I don't want the collection of Assignments to be strongly referenced when the HumanResource is strongly referenced. Second is keeping the collection up-to-date in the implementation of the Assign Position use case, if legacy code has not been coded to involve the HumanResource in the chain of responsibility.
So I choose to implement HumanResource.getAssignments() as return AssignmentRepository.getAssignments(this). To me, that feels like a perfectly natural layering and allocation of responsibility. I *want* clients of HumanResource to ask *it* for its collection of Assignments, instead of violating encapsulation and bypassing HumanResource altogether. HumanResource gets to decide how to answer the question. Once and only once, protected variation, etc. When in comes to balancing performance and maintainability, instance variables are the "joints" of the domain model. At my company we're focusing on these joints as points for configurability and optimization.
> -----Original Message-----
> From: j2eeiscool [mailto:siddiqut@...]
> Sent: Monday, March 14, 2005 3:12 AM
> To: email@example.com
> Subject: [domaindrivendesign] Re: Entities accessing Repositories?
> I face a somewhat similar situation. I did a research of the archives
> and came across this post from Eric Evans
> "But then there is the question of how you implement this reference. I
> would not have a domain object reference a repository. To me,
> repositories are essentially a higher layer than the entities
> and value
> objects that express basic domain concepts. This is where
> comes in. We need support from the technical framework to set up a
> reference from the Customer to a collection of Users without putting
> lots of technical detail in the Customer object. All the O-R mapping
> tools I've seen provide this capability. Proxies are also a
> solution to
> this problem."
> I think he is talking in terms of JUST Entity Domains and not
> policies/strategies. I am also not sure whether this applies to just
> this specific problem or in general.
> Eric, your comments on this pls.
> --- In firstname.lastname@example.org, Anders Engström
> <aengstrom@g...> wrote:
> > Hi.
> > I have a quick question for the group:
> > Repositories are considered to be part of the domain model, together
> > with entities, value objects and services.
> > I've always considered the different domain component types
> to represent
> > a "micro level" layered application where services accesses
> > to find entities to work with. Entities should have no
> dependencies on
> > either services nor repositories.
> > Does this make sense? I often come upon situations where it
> feels like
> > the problem could be easilly solved if I allowed an entity to access
> > "it's own" repository.
> > Best Regards //Anders
> > --
> > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
> . . . . . .
> > . Anders Engström aengstrom@g...
> > . http://www.gnejs.net PGP-Key: ED010E7F
> > . [Your mind is like an umbrella. It doesn't work unless
> you open it.]
> Yahoo! Groups Links
- Hi Randy,
I kinda agree to your viewpoint. If the entity domain is not supposed
to access repository, someone else (Service or Strategy/Policy domain
classes) has to do it and pass the results to the Entity to execute
it's business rule/validations. This does not seem very object
oriented to me.
Details on my side:
I have a Report Period entity which aggregates a collection of
Surveys. Based on the change of year (an instance field in Report
Period) the Report Period has to recalculate its Collection of
Surveys. For doing this it queries the repository to figure out the
new Set of Surveys.
If Report Period were not to access the Repository directly, possibly
the Service Layer could lookup the Surveys and pass it to Report
Period for the rehash. But this looks so anti-encapasulation to me.
- In your case though, and this may just be ignorance on my part, if
the year changes do you not have a different Report Period?
Anyway its a great example of a situation that I do not think you can
deal with easily without acessing the repository from an entity. As
an example I don't think NHibernate has any way of handling this, you
can't say "when X changes consider Y invalid and re-retrieve it next
time"...though maybe if we asked nicely they would add it.
If we had to do this on the project I'm workin on then we probablhy
would access the repository from the domain, though I think I'd maybe
consider the implications of one property changing the very essence
of the object before changing our design.
Anyway the key point for me is that not accessing repositories from
the domain is a good thing to aim for (or at least I think it is),
but if its resulting in you sacrificing domain quality or is giving
you bad performance then of course you have to rethink.
--- In email@example.com, "j2eeiscool"
> Hi Randy,
> I kinda agree to your viewpoint. If the entity domain is not
> to access repository, someone else (Service or Strategy/Policydomain
> classes) has to do it and pass the results to the Entity to executepossibly
> it's business rule/validations. This does not seem very object
> oriented to me.
> Details on my side:
> I have a Report Period entity which aggregates a collection of
> Surveys. Based on the change of year (an instance field in Report
> Period) the Report Period has to recalculate its Collection of
> Surveys. For doing this it queries the repository to figure out the
> new Set of Surveys.
> If Report Period were not to access the Repository directly,
> the Service Layer could lookup the Surveys and pass it to Report
> Period for the rehash. But this looks so anti-encapasulation to me.