Flavius
Flavius

Reputation: 13816

Program to an interface and the Observer Pattern

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.

enter image description here

Upvotes: 0

Views: 225

Answers (1)

theDmi
theDmi

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

Related Questions