Closed hochleitner closed 3 years ago
Hi @hochleitner Thank you for your feedback.
...maybe just misunderstood in the whole ADR architecture.
The book covers ADR and a simplified Clean Architecture. ADR just says, that the Action delegates all the non HTTP-specific tasks to the Domain layer and the Responder builds the Response. ADR itself does not define how to structure your domain layer.
...many things become very similar and start to violate the DRY principle
I have heard this question many times in the context of repositories that use the DataMapper pattern.
There is no DRY violation because you always have a different bounded context, different interfaces, different queries, different tables, and different columns and different data to insert / update. Every use case is different. Therefore, I do not see any problem here that could be solved.
How do you suggest handling this? Is it wise to create, say an AbstractRepository
The Repository pattern is a well-documented way of working with a data source. In my example I use persistence-oriented Repositories because I don't need the Unit of Work pattern.
Today I would never use and recommend inheritance anymore. That's why I use final by default. There is also no need to reinvent the ORM wheel again ;-)
When you still need a more generic solution, you may try the collection-oriented Repository pattern.
Thanks for the clarification. I'll definitely have to read up more on my design patterns.
About inheritance: Is this a personal choice or why wouldn't you recommend it in these cases? When looking at slimphp\Slim-Skeleton I can see that they're using an abstract Action
class. Or would you say that it's different for Actions compared to Repositories because of the underlying pattern?
Inheritance is "bad" from a theoretical and practical perspective.
To build reusable classes, I prefer Composition over Inheritance because of the Dependency inversion principle from SOLID.
In practice, I have found that inheritance is increasingly difficult to maintain. A tiny change in a base class can break a lot of code. Huge class hierarchies are also hard to maintain and refactor.
Thank you, that helps a lot with some of the upcoming decisions.
Also, thanks again for the excellent skeleton and the ebook!
First off, thanks for the excellent slim4-skeleton as well as your e-book. It's been a tremendous help in building a RESTful API for a research project. There's one thing though that I didn't find covered or that I maybe just misunderstood in the whole ADR architecture.
We have multiple Domains: User (very similar to the skeleton), Task, Session and a few more. There are of course the associated actions and also repositories to it. What we soon discovered is that down in the repositories, many things become very similar and start to violate the DRY principle. Meaning: a
UserCreateAction
has to perform an insert of a new user in itsUserRepository
the same way as aTaskCreateAction
will insert a new task in theTaskRepository
. This seems fine at first to me because the domains are different but the DB queries with the repositories are pretty similar.insertUser(UserData $user)
does the same asinsertTask(TaskData $task)
in terms of the underlying query.How do you suggest handling this? Is it wise to create, say an
AbstractRepository
class, that contains just aninsert(AbstractData $data)
method andUserRepository
, as well asTaskRepository
, will then just call this to perform the actual DB operation? This in turn would then also need anAbstactData
class where all the specified domain data classes inherit from.Does this make sense, or this something that is absolutely not desirable in an ADR approach? If not, how would you approach this issue?