What is the difference in class coupling if you use these 3 types of usages:
Case 1
use UserRepository
...
UserRepository::getUser();
Case 2
App::make('UserRepository')->getUser();
Case 3
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
...
$this->userRepository->getUser();
Is there any reason to prefer one over the other?
EDIT
I feel as though the constructor option is the best way to go, but I find myself in question when I need to include 3 services and 3 repositories in the controller which then very soon escalates to 6 parameters in constructor.
EDIT - Case 4
What about when you're using a facade instead?
EDIT - Case 5
What about when you specify it as \UserRepository
?
First of all, the idea of the Repository is to have an Interface (UserRepositoryInterface) and classes that implement it (MySQLUserRepository, RedisUserRepository). It gives you a quick way to change the storage of users through your DI container by calling an interface:
public function __construct(UserRepositoryInterface $userRepository)
{
$this->userRepository = $userRepository;
}
And changing it to any implementation in the DI container.
Let's say you have a Controller with 10 actions.
Case 1 Is not the OOP way, because the call doesn't go through the DI container at all.
Case 2 is actually OK, but you'll have to call the App facade in every action. It's not really beautiful.
Case 3 gives you only one place to create/change/configure the class.
E.g. you need to do something like:
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
$this->userRepository->excludeAdmins();
}
A lot of repositories in constructor is actually ok, however if the code fills gross to you, you can extract it to a Service class.
UPDATE By Service class I mean a class that doesn't extends anything and contains the business logic.
Further reading: https://m.dotdev.co/design-pattern-service-layer-with-laravel-5-740ff0a7b65f
Case 4. Facades, in my opinion, are suitable for something more global. Why would you want to populate each repository with a facade? Too time consuming.
Case 5. Didn't get the question. You mean put it to the root namespace? What does it change?