Given the following code snippet in a Laravel Controller:
$this->userRepository->saveByProject(
$this->fileRepository->saveByProject(
$this->metricRepository->saveByProject(
$this->projectRepository->saveByUser(
$request->attributes->get('user'), $request->all(), $id
),
$request->input('metrics')
),
$request->input('files') ?? []
),
$request->input('contact') ?? []
);
As you can see, each first parameter should be a ‘Project’ (an object that implements the interface ‘Project’).
Doubtful Point
The doubtful point is the method ‘saveByProject’ in each repository. In userRepository for example, it saves the user and the relation between user and given project, and returns the project with the related user. I hope you understand the construction. You know this works too for files (FileRepository), etc.
Pros and Cons of the Solution Above
Pros:
- Less dependencies in ProjectRepository
- Less procedural, because it’s one statement
- Readable, but other than “logical”
Cons:
- Multiple repositories with method ‘saveByProject’
- Less readable in comparison with method chaining
Alternative : Method Chaining
Pros:
- More readable
- FileRepository and other repositories know nothing about Project
Cons:
- ProjectRepository has many dependencies (see code snippet below)
- ProjectRepository has many methods
Code snippet:
$this->projectRepository->saveProject(
$request->attributes->get('user'), $request->all(), $id
)
->saveFiles($request->input('files')) // call FileRepository
->saveMetrics($request->input('metrics')); // call MetricRepository
//etc.
Each save* method calls the right repository, but handles saving the relation with the project by itself, and returns the project.
2