首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >领域建模:正确处理

领域建模:正确处理
EN

Stack Overflow用户
提问于 2015-05-20 14:25:54
回答 1查看 105关注 0票数 1

在看过Jimmy出色的关于制作邪恶域的视频之后,我尝试将同样的原则应用到我现有的一个项目中,以评估我对这个概念的理解有多好。我有疑问和疑问列在下面。

域名背景:管理员可以查看公司列表。然后他批准了一家公司。数据库应该将布尔字段更新为true,并存储批准该公司的用户的id。

最初,我在服务层中编写了以下代码。它将请求传递给存储库,存储库更新db中的适当字段,然后发送邮件通知。

代码语言:javascript
运行
复制
public void ApproveCompany(int companyId, int userId)
{
    _companyRep.ApproveCompany(companyId, userId);

    //send mail to company representatives on successful approval. 
}

为了创建丰富的域并在域类中封装逻辑,我创建了下面的内容。

代码语言:javascript
运行
复制
public void ApproveCompany(int companyId, int userId)
    {
        var user = _userRep.GetById(userId);
        var company = _companyRep.GetById(companyId);
        user.Approve(company);

        _companyRep.Insert(c);

        //send mail to company representatives on successful approval. 
    }

public class AdminUser
    {
        public string Name { get; set; }

        public void Approve(MyApprovedCompany c)
        {
            c.SetIsApproved(this);
        }       
    }

public class Company 
    {
        public bool IsApproved { get; private set; }
        public AdminUser ApprovedBy { get; private set; }

        public void SetIsApproved(AdminUser user)
        {
            if (this.IsApproved)
                throw new Exception("This company has already been approved by user: " + user.Name);

            this.IsApproved = true;
            this.ApprovedBy = user;
        }
    }

查询:

  1. 我所做的完全正确/部分正确吗?
  2. 从性能的角度来看,获取这两个对象仅仅是为了创建适当的类实例,将来会成为一个问题吗?
  3. 邮件通知是否属于服务层?
  4. 我的公司存储库将如何处理与批准公司的用户相关的属性?如果我的公司存储库有对用户存储库的引用(我认为这是错误的)。

或者,我可以按下面的方式编写服务层,但我认为这也不正确。

代码语言:javascript
运行
复制
public void ApproveCompany(int companyId, int userId)
{
    var user = _userRep.GetById(userId);
    var company = _companyRep.GetById(companyId);

    if(company.IsApproved)
    {
        throw new Exception("This company has already been approved by user: " + _userRep.GetById(company.ApprovedUserId).Name);        
    }
    else
    {
        user.Approve(company);
        _companyRep.Insert(c);
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-21 16:00:08

这类问题几乎不可能得到正确的回答,但我可以从我所看到的情况告诉你:

  1. 这在某种程度上是正确的,但我通常倾向于将行为放在操作所针对的AR上,而不是在执行操作的角色上。在这种情况下,双重调度并没有带来任何有用的东西,IMHO。因此,我将简化为company.Approve(adminUser)。您可能会说,adminUser.approve(Company)更好地反映了一个用例,比如“管理用户批准了一个公司”,但是您可以把它扭转过来,说“公司是由管理用户批准的”。还请注意,您所拥有的company.SetIsApproved方法非常面向CRUD,并且肯定不能很好地反映您无处不在的语言。
  2. ARs的设计应尽可能小。只要您没有创建不必要的大型集群聚合,我就不认为这会成为一个问题。我强烈建议你读Vaughn Vernon的有效集料设计
  3. 理想情况下,您应该依靠域事件来实现操作的副作用。有大量关于如何在Web上实现域事件的信息。但是,由于缺乏发布/订阅机制,可以在应用程序服务层中完成,也可以在AR方法级别注入邮件服务。
  4. 问题是,您正在引用另一个AR中的AR。ARs通常应该通过身份来引用其他ARs。因此,Company不会只保留AdminUser,只保留用户的ID。这样做,您的问题就消失了,您就减少了AR的大小。
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30352568

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档