To reduce coupling, functionality related to user group management should be factored out of the User class. Some of the relevant code is already encapsulated in the UserGroupMembership class. UserGroupMembership however should be replaced by (or become) a pure value object.
Proposed design: introduce a UserGroupManager service that offers the following methods:
- getExpliciteGroups( UserIdentity )
- getAutomaticGroups( UserIdentity )
- getEffectiveGroups( UserIdentity )
- getFormerGroups( UserIdentity )
- addToGroup( UserIdentity, $group )
- removeFromGroup( UserIdentity, $group )
- getGroupLink( $group, UserIdentity|null )