2

Suppose I have two entities: User and UserGroup.
They have a one-to-many relationship => each UserGroup virtually contains 0 to n number of users.

If I want to retrieve the users for a UserGroup where in my business layer would be a better class to put that method?

  1. In UserManager, add method: GetAllUsersForUserGroup
  2. in UserGroupManager add the above method.

Guess 2 is better. But I'm not sure.
Thanks.

UPDATE
Guess I couldn't completely explain what I meant.
Yes we can have User, Users, Group, Groups, etc.

But I'm not trying to find out what different patterns, etc can be applied to implement the business. my question is: do you put GetAllUsersForUserGroup(int UserGroupID) in UserManager or in GroupManager? Do you think GetAllUsersForUserGroup(int UserGroupID) should be defined in a class that is managing users or in a class that's managing user groups?

DocZerø
  • 8,037
  • 11
  • 38
  • 66
Kamyar
  • 18,639
  • 9
  • 97
  • 171

5 Answers5

4

Of course it's difficult to give an opinion without knowing exactly how the managers and the clients of the managers are structured and what methods they already offer.

Assuming the managers are simple DAOs with CRUD operations for the basic entity operations I'd think about having a higher level UserRepository or UserService object providing more 'business' like functions such as an

IList<User> FindUsersByGroup( UserGroup group );

In summary though, there's no right answer as logically you could argue either way - I'd base my decision on keeping the managers as simple as possible, avoid object bloat, keep an eye on how you see the application evolving in the near future and refactor if necessary it maintainability becomes an issue.

Tom Carter
  • 2,938
  • 1
  • 27
  • 42
  • Thanks. I am aware about your suggestion and I have implemented it in my layer. What I want to find out is: Where would you put `FindUsersByGroup` method? in `UserBLL` or `UserGroupBLL`? What entity do you think this method is more related to? – Kamyar Jun 08 '11 at 07:55
  • @Kamyar - not quite sure what your asking - if UserBLL/UserGroupBLL are domain objects containing business logic then neither - they shouldn't be responsable for find functions - delegate that task to a repository object. If UserBLL and UserGroupBLL are in fact just DAOs then like I said in my answer you could argue for either - my personal choice would be UserGroup assuming User does not know about UserGroups – Tom Carter Jun 08 '11 at 08:10
  • they're DAOs. I'll define it in `UserGroupManager` as you confirmed. Thanks, sorry for the ambitious question. – Kamyar Jun 08 '11 at 08:16
2

You could also use a Factory Pattern.

eg:

public class UserFactory
{
 public static List<User> GetUsers()
 {
 }

 //Optional method to get users in group from user factory
 public static List<User> GetUsersInGroup(int GroupID)
 {
  return UserGroupFactory.GetUsersInGroup(int GroupID)
 }
}

public class UserGroupFactory
{
 public static List<UserGroup> GetUserGroups()
 {
 }

 public static List<User> GetUsersInGroup(int GroupID)
 {
 }
}

If the User Group table has the user, and group ID's I put put it in the UserGroup factory.

WraithNath
  • 17,658
  • 10
  • 55
  • 82
2

As @Tom Carter said, it's hard to figure out exactly the best answer for you because there are a lot of details missing. I think that most "manager" classes can actually be removed using good OOP.

Your UserGroup class could then look something like this:

public class UserGroup
{
    private List<User> _Users;

    public ReadOnlyCollection Users
    {
        get { return _Users.AsReadOnly (); }
    }

    public void AddUser (User User)
    {
        // Perform your business logic here inside the object itself
        _Users.Add (User);
    }

    public UserGroup ()
        : this (null)
    { }

    public UserGroup (List<User> Users)
    {
        _Users = Users ?? new List<Users> ();
    }
}

This helps build a rich object and keeps the business logic inside of your objects and keeps you from having to resort to creating a bunch of "Manager" classes.

Jim D'Angelo
  • 3,952
  • 3
  • 25
  • 39
1

Do you think GetAllUsersForUserGroup(int UserGroupID) should be defined in a class that is managing users or in a class that's managing user groups?

This method should be defined in a UserManager / UserRepository class.

  1. A Manager / Repository class is usually designed to have a set of similar methods to work with objects of a concrete class, for example a User class.

  2. These methods include methods to Create / Request / Retrieve from Database / Cache / Local collection one or more objects of the class by some specification.

  3. A method to Get Users by UserGroup specification is one of there methods.

The most simple implementation if all users are stored inside the group:

class UserRepository
    function GetUsers(Group as UserGroup) as IEnumerable(of User)
        return Group.Users
    end function
end class

or if all users are stored inside one collection:

class UserRepository
    private readonly UserCollection as ICollection(of User)

    public function GetUsers(Group as UserGroup) as IEnumerable(of User)
        return UserCollection.Where(function(U) U.Group.ID = Group.ID)
    end function
end class
Lightman
  • 1,078
  • 11
  • 22
0

If you Getting a list of Users, I would put the method in the Users class, so it reads naturally, like:

Users.GetAllByUserGroup()
Mark Redman
  • 24,079
  • 20
  • 92
  • 147
  • Thanks. But I guess I didn't explain my question very well. I tried to be more clear about my question. Please see the update. – Kamyar Jun 08 '11 at 07:59