Reputation: 13816
First, a small introduction, to help you understand where I'm coming from: I was not sure how to title this question, either like it is, or as Repository tracking changes of the Unit of Work.
I have two interfaces, ChangeListener
and ChangeSubject
, which are coupled:
interface ChangeListener
{
public function onSubjectChanged(ChangeSubject $subject, array $data);
}
interface ChangeSubject
{
public function addChangeListener(ChangeListener $listener);
}
and I also have a repository and a unit of work (WIP, I'll leave out some parts):
interface UnitOfWork extends ChangeSubject
{
public function commit();
public function hydrateChange(array $data, ArrayService $arrayService);
}
interface Repository extends ChangeListener
{
public function commit() : \bool;
public function commitCount() : \int;
}
Now, in my implementation of the UnitOfWork
, let's call it Book
, more precisely in the method hydrateChange
, I notify the repository of the change, which is easy:
$repository->onSubjectChanged($this, $newHydration);
The problem is now that, within the repository, I need to know the book's id. But the repository's handling method receives a ChangeSubject
, which does not have an id (which the Book
has).
How to properly design such a system?
If PHP had generics, it would have been possible. A hacky solution, which I don't like, is using instanceof
.
Upvotes: 0
Views: 225
Reputation: 18034
You misunderstood a few of the concepts. If you get the following right, you should get back on track:
Don't implement unit of work in your domain objects. The unit of work is just a technical helper that keeps track of changes. So the unit of work references the business object, e.g. to note "the book with ID 32 changed", but it isn't the same as a business object.
Make concrete repositories for your aggregate types. A BookRepository
should contain methods like GetById(BookId)
, GetByAuthor(Author)
and the like. Note: In languages with generics there may be an opportunity to extract generic parts, but in PHP, it's best to work on the concrete aggregate types like Book
.
I suggest you learn more about the unit of work and repository patterns. Make sure you fully understand them before you try to use them. Also make sure you understand the different repository variations (e.g. command style repository vs collection style repository) to make an informed decision for your project.
Upvotes: 2