我有一個常見的場景,我正在尋找一些有關DDD和領域建模更有經驗的人的一些指導。如何避免貧血域模型或何時將方法從實體移動到服務中
假設我開始構建博客引擎,第一個要求是在發佈文章後,用戶可以開始發佈評論。這將啓動罰款,並導致了以下設計:
public class Article
{
public int Id { get; set; }
public void AddComment(Comment comment)
{
// Add Comment
}
}
我的MVC控制器的設計是這樣的:
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");
}
}
現在一切正常,並符合要求。接下來的迭代中,我們得到一個要求,每次發佈評論時,博客作者都應該收到一封電子郵件通知他。
在這一點上,我有兩個選擇,我可以想到。 1)修改文章要求IEmailService(在ctor?中)或從靜態引用獲取EmailService到我的DI容器
1a)看起來很醜陋。我相信它打破了我的實體知道服務的一些域模型規則?
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容器。
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()方法移動到此服務而不是文章實體本身。
我相信這個解決方案更乾淨,但添加評論現在不易發現,需要ArticleService來完成這項工作。似乎AddComment應該屬於Article類本身。
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");
}
}
所以,我基本上尋找更多領域建模經驗的人的意見。如果我錯過了一個更明顯的解決方案,請讓我知道:)
我通常不喜歡這兩種解決方案是誠實的,因爲服務選項不易發現。如果沒有可用的ArticleService,我不能再向文章的實例添加評論。它也感覺不那麼自然,因爲AddComment看起來就像是一種明顯的Article類型的方法。
無論如何,我期待閱讀輸入。提前致謝。
+1的解決方案#2 – JuanZe 2009-09-28 19:02:57
+1很好看的一個清晰的問題 – Rippo 2010-02-01 08:01:23