Separating logic per class and being able to use dependency injection I use Laravel, but hopefully this doesn't matter. I have a user and user's state. Say, simple integer or a string. I want to run some logic depending on user state in my service class.

So, the first approach is pretty simple:

&lt;?php

class UserStateManager
{
    public function __construct(UserRepository $userRepository)
    {
        $this-&gt;userRepository = $userRepository;
    }

    public function handle(UserRepository $userRepository)
    {
        $user = $this-&gt;userRepository-&gt;find(1);
        switch ($user-&gt;state) {
            case 'new':
                $this-&gt;handleUserNewState();
                break;
            case 'banned':
                $this-&gt;handleUserBannedState();
                break;
            // ...
        }
    }

    private function handleUserNewState()
    {
        // Do some logic
        // Here we have access to userRepository which was injected in UserStateManager constructor
    }

}


Pay attention that I injected UserRepository in the constructor.

So, using this approach I keep UserStateManager dependencies injected, without creating them manually.

But now I want to put every state handler to a separate class. Like, to have UserNewState class with handle method.

The problem is that in this case:

public function handle(UserRepository $userRepository)
    {
        $user = $this-&gt;userRepository-&gt;find(1);
        switch ($user-&gt;state) {
            case 'new':
                (new UserNewState)-&gt;handle();
                break;
            case 'banned':
                (new UserBannedState)-&gt;handle();
                break;
            // ...
        }
    }


if I create UserNewState object I cannot inject dependencies into this class since I manually create it using new operator. Passing lots of dependencies in the constructor (like new UserNewState($this-&gt;userRepository, ...)) is not an option, ugly solution.

So how to deal with this case? Because it's very common: on the one hand I can separate logic into several methods inside one class, on the other hand I cannot separate logic into many classes.

The problem is dependency injection and creating these class manually. And I reckon that DI is a good thing.

Of course I can create dependencies inside UserNewState class, directly in the constructor:

public function __constructor() {
    $this-&gt;userRepository = new UserRepository;
}


but this is not testable. Even though I don't test my apps, I just want to follow best practices.
Without knowing exactly what those classes are supposed to do, I assume it's supposed to work something like (new UserNewState( $this-&gt;userRepository ))-&gt;handle( $user );. That doesn't look that bad to me.

What other dependencies do you envision your separate State classes are going to need besides the repository?

But perhaps something like a UserStateHandlerFactory is something you could be looking for?

class UserStateHandlerFactory
{
  private $userRepository;

  public function __construct( UserRepository $userRepository ) {
    $this-&gt;userRepository = $userRepository;
  }

  public function create( User $user ) {
    switch ($user-&gt;state) {
        case 'new':
            return new UserNewState( $this-&gt;userRepository );
            break;
        case 'banned':
            return new UserBannedState( $this-&gt;userRepository );
            break;
        // ...
    }
  }
}

class UserStateManager
{
  private $userRepository;
  private $handlerFactory;

  public function __construct( UserRepository $userRepository, UserStateHandlerFactory $handlerFactory )
  {
    $this-&gt;userRepository = $userRepository;
    $this-&gt;handlerFactory = $handlerFactory;
  }

  public function handle()
  {
    $user = $this-&gt;userRepository-&gt;find(1);
    $this-&gt;handlerFactory-&gt;create( $user )
                         -&gt;handle( $user );
  }
}


However, I don't know if that makes things much cleaner though. It just looks like another layer of indirection; hiding away, what ultimately has to be done anyway: pass dependencies into the handlers.