2

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?

Norgul
  • 4,613
  • 13
  • 61
  • 144

1 Answers1

1

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?

Laraleg
  • 519
  • 3
  • 7