如何避免贫血域模型,或者当从实体移动的方法进服务 [英] How to avoid anemic domain models, or when to move methods from the entities into services

查看:160
本文介绍了如何避免贫血域模型,或者当从实体移动的方法进服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我要找的人更有经验与DDD和领域建模一般一些指导一个常见的​​场景。

I have a common scenario that I am looking for some guidance from people more experienced with DDD and Domain Modeling in general.

说我开始了建立一个博客引擎和第一个要求是,一个文章发布后,用户就可以开始张贴在上面留言。这将启动罚款,并引出了如下设计:

Say I start out building a blog engine, and the first requirement is that after an Article is posted, users can start posting Comments on it. This starts fine, and leads to the following design:

public class Article
{
    public int Id { get; set; }

    public void AddComment(Comment comment)
    {
        // Add Comment
    }
}

我的MVC控制器的设计是这样的:

My MVC Controller is designed like this:

public class ArticleController
{
    private readonly IRepository _repository;

    public ArticleController(IRepository repository)
    {
        _repository = repository;
    }

    public void AddComment(int articleId, Comment comment)
    {
        var article = _repository.Get<Article>(articleId);
        article.AddComment(comment);
        _repository.Save(article);
        return RedirectToAction("Index");
    }
}

现在一切正常,并符合要求。下一个迭代,我们得到每一个评论发布时间,博客作者应该得到一封电子邮件,通知他的要求。

Now everything works fine, and it meets the requirement. Next iteration we get a requirement that every time a Comment is posted, the blog author should get an email notifying him.

在这一点上,我有2个选择,我可以想到。
1)修改文章,需要IEmailService(在构造函数?),或者从一个静态引用的EmailService我的DI容器

At this point, I have 2 choices that I can think of. 1) Modify Article to require an IEmailService (in the ctor?) or obtain an EmailService from a static reference to my DI container

1A)看起来很丑陋。我相信它打破了我的实体都知道服务的一些领域模型的规则?

1a) Seems pretty ugly. I believe it breaks some Domain model rules that my entities are aware of services?

public class Article
{
    private readonly IEmailService _emailService;

    public Article(IEmailService emailService)
    {
        _emailService = emailService;
    }

    public void AddComment(Comment comment)
    {
        // Add Comment

        // Email admin
        _emailService.SendEmail(App.Config.AdminEmail, "New comment posted!");
    }
}



1b)中似乎也是丑陋的,我现在需要一个配置DI容器,是静态访问。

1b) Also seems ugly, I now require a configured DI container which is accessed statically.

public class Article
{
    public void AddComment(Comment comment)
    {
        // Add Comment

        // Email admin
        var emailService = App.DIContainer.Resolve<IEmailService>();
        emailService.SendEmail(App.Config.AdminEmail, "New comment posted!");
    }
}



2)创建IArticleService和移动AddComment()方法这项服务,而不是在第实体本身。

2) Create an IArticleService and move the AddComment() method to this service instead of on the Article Entity itself.

这解决方案是清洁的,我相信,但添加注释是现在比较少发现的,需要一个ArticleService来执行工作。这似乎是AddComment应该属于对文章类本身。

This solution is cleaner I believe, but Adding a comment is now less discoverable and requires an ArticleService to perform the work. It seems like AddComment should belong on the Article class itself.

public class ArticleService
{
    private readonly IEmailService _emailService;

    public ArticleService(IEmailService emailService)
    {
        _emailService = emailService;
    }

    public void AddComment(Article article, Comment comment)
    {
        // Add comment

        // Email admin
        _emailService.SendEmail(App.Config.AdminEmail, "New comment posted!");
    }

}


public class ArticleController
{
    private readonly IRepository _repository;
    private readonly IArticleService _articleService;

    public ArticleController(IRepository repository, IArticleService articleService)
    {
        _repository = repository;
        _articleService = articleService;
    }

    public void AddComment(int articleId, Comment comment)
    {
        var article = _repository.Get<Article>(articleId);
        _articleService.AddComment(article, comment);
        _repository.Save(article);
        return RedirectToAction("Index");
    }
}



所以我基本上找的人越多经验丰富的咨询在域建模。如果我缺少一个比较明显的解决方案,请让我知道:)

So I am basically look for advice from people more experienced in domain modeling. If I am missing a more obvious solution please let me know :)

我不喜欢一般这两种解决方案是诚实的,因为服务选项较少发现。我不能再添加评论,一篇文章的一个实例,而无需一个ArticleService可用。它也觉得不太自然,因为AddComment好像对文章类型这样一个显而易见的方法。

I generally dislike both solutions to be honest, because the Service option is less discoverable. I can no longer add a Comment to an instance of an Article without having an ArticleService available. It also feels less natural, since AddComment seems like such an obvious method on the Article type.

无论如何,我期待着阅读的投入。 。在此先感谢

Anyway I look forward to reading the input. Thanks in advance.

推荐答案

我认为这一具体问题可以典雅,的域名事件

I think this particular issue can be solved elegantly with a Domain Event.

这篇关于如何避免贫血域模型,或者当从实体移动的方法进服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆