title: PHP: Design pattern for managing types of entity
body: <p>I have <code>User</code> entity. I would like to have multiple "types" of this entity, with different managers and repositories. All <code>User</code> entities of all types would share only <code>UserInterface</code>. Now, I'm looking for a good method of organizing everything. First thing that came to my mind is to create something like this:</p>
  
  <pre><code>interface UserTypeManagerInterface
  {
    public function addUserType($name, RepositoryInterface $repository, ManagerInterface $manager);
    public function hasType($name);
    public function getRepository($type);
    public function getManager($type);
  }
  </code></pre>
  
  <p>Then in places where I would like to manage multiple types of <code>User</code> at once, I would inject this, and in places where I would like to manage a specific type of user, I could inject only specific repository and manager objects, for its type.</p>
  
  <p>Seems like a pretty clean approach, but at the same time, when I would like to create a test for a class using <code>UserTypeManager</code> I would need to mock <code>UserTypeManager</code>, then this mock would need to return other mocks (repository and manager).</p>
  
  <p>This is doable of course, but it made me thinking if this can be avoided. The only other thing that I can think of, which would allow for avoidance of above complexity during testing, would be something like this:</p>
  
  <pre><code>interface UserTypeManagerInterface {
      public function addUserType($name, RepositoryInterface $repository, ManagerInterface $manager);
  }
  
  /**
   * My class managing multiple types of user.
   */
  class ManageMultipleTypesOfUsers implements UserTypeManagerInterface {
      // ...
  }
  </code></pre>
  
  <p>So I would just add all repositories and managers to all classes implementing <code>UserTypeManagerInterface</code> interface. So objects would use directly what was given to them.</p>
  
  <p>This way testing would be much cleaner, because I would need to mock only the one manager and one repository to test class <code>ManageMultipleTypesOfUsers</code>, but this feels sooo much like over-engineering. ;)</p>
  
  <p>Is any middle-ground here even possible?</p>