将两个相关对象的业务逻辑放在哪里?

Posted

技术标签:

【中文标题】将两个相关对象的业务逻辑放在哪里?【英文标题】:Where to put business logic for two related objects? 【发布时间】:2011-09-10 15:49:09 【问题描述】:

假设我有两个实体:UserUserGroup。 它们具有一对多的关系 => 每个 UserGroup 实际上包含 0 到 n 个用户。

如果我想检索UserGroup 的用户,那么在我的业务层中放置该方法的哪个类会更好?

    UserManager中,添加方法:GetAllUsersForUserGroupUserGroupManager中添加上述方法。

猜猜2更好。但我不确定。 谢谢。

更新 我想我无法完全解释我的意思。 是的,我们可以有UserUsersGroupGroups 等。

但我并不是想找出可以应用哪些不同的模式等来实施业务。我的问题是:您将GetAllUsersForUserGroup(int UserGroupID) 放入UserManager 还是GroupManager?您认为应该在管理用户的类中还是在管理用户组的类中定义GetAllUsersForUserGroup(int UserGroupID)

【问题讨论】:

【参考方案1】:

当然,如果不确切了解经理和经理的客户的结构以及他们已经提供了哪些方法,就很难发表意见。

假设管理器是简单的 DAO,具有基本实体操作的 CRUD 操作,我会考虑使用更高级别的 UserRepository 或 UserService 对象来提供更多类似“业务”的功能,例如

IList<User> FindUsersByGroup( UserGroup group );

不过,总而言之,无论哪种方式,从逻辑上讲,都没有正确的答案 - 我的决定是让管理器尽可能简单,避免对象膨胀,密切关注您如何看待应用程序在不久的将来并在必要时进行重构,可维护性成为一个问题。

【讨论】:

谢谢。我知道你的建议,我已经在我的层中实现了它。我想知道的是:你会把FindUsersByGroup方法放在哪里?在UserBLLUserGroupBLL?您认为这种方法与哪个实体更相关? @Kamyar - 不太确定您的要求是什么 - 如果 UserBLL/UserGroupBLL 是包含业务逻辑的域对象,那么它们都不应该负责查找功能 - 将该任务委托给存储库对象。如果 UserBLL 和 UserGroupBLL 实际上只是 DAO,那么就像我在回答中所说的那样,您可以争论任何一个 - 我个人的选择是 UserGroup 假设用户不知道 UserGroups 他们是 DAO。正如您所确认的,我将在UserGroupManager 中定义它。谢谢,抱歉这个雄心勃勃的问题。【参考方案2】:

您也可以使用工厂模式。

例如:

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)
 
 

如果用户组表有用户和组ID,我把它放在用户组工厂中。

【讨论】:

【参考方案3】:

正如@Tom Carter 所说,很难准确地找出最适合您的答案,因为缺少很多细节。我认为大多数“管理器”类实际上可以使用良好的 OOP 删除。

您的 UserGroup 类可能如下所示:

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> ();
    

这有助于构建一个丰富的对象,并将业务逻辑保留在您的对象中,并使您不必求助于创建一堆“管理器”类。

【讨论】:

【参考方案4】:

您认为应该在管理用户的类中还是在管理用户组的类中定义GetAllUsersForUserGroup(int UserGroupID)

此方法应在UserManager / UserRepository 类中定义。

    Manager / Repository 类通常设计为具有一组类似的方法来处理具体类的对象,例如 User 类。

    这些方法包括通过某些规范创建/请求/从数据库/缓存/本地集合中检索一个或多个类对象的方法。

    Get Users by UserGroup 规范的方法是其中一种方法。

如果所有用户都存储在组内,最简单的实现:

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

或者如果所有用户都存储在一个集合中:

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

【讨论】:

【参考方案5】:

如果您获取用户列表,我会将方法放在用户类中,因此它的读取方式很自然,例如:

Users.GetAllByUserGroup()

【讨论】:

谢谢。但我想我没有很好地解释我的问题。我试图更清楚我的问题。请查看更新。

以上是关于将两个相关对象的业务逻辑放在哪里?的主要内容,如果未能解决你的问题,请参考以下文章

Lumen 中的业务逻辑应该放在哪里?

使用实体框架时对将业务逻辑放在哪里感到困惑

MVC:把业务逻辑放在哪里? [关闭]

在哪里放置业务逻辑,在控制器或服务中? [复制]

MVC 4 - 在哪里保留业务逻辑

业务逻辑和规则——如何将它们与领域模型解耦