C# 创造相关实体的责任

C# 创造相关实体的责任,c#,domain-driven-design,aggregation,C#,Domain Driven Design,Aggregation,我有一个名为“Task”的实体。对于这个实体,我可以创建多个实体,称为“注释”。我还想要一个名为“CreateComment”的方法。根据领域驱动的设计,实体“注释”如果不创建“任务”类的实例就不可能存在。我的问题是:这个方法应该放在哪里:在Task类中还是在Comment类中?它应该类似于Comment.CreateComment或Task.CreateComment。如果我将此方法放入Task类,是否会违反单一责任原则?根据,原则 如果以下一项或多项适用,B类应负责创建A类实例: B的实例

我有一个名为“Task”的实体。对于这个实体,我可以创建多个实体,称为“注释”。我还想要一个名为“CreateComment”的方法。根据领域驱动的设计,实体“注释”如果不创建“任务”类的实例就不可能存在。我的问题是:这个方法应该放在哪里:在Task类中还是在Comment类中?它应该类似于Comment.CreateComment或Task.CreateComment。如果我将此方法放入Task类,是否会违反单一责任原则?

根据,原则

如果以下一项或多项适用,B类应负责创建A类实例:

  • B的实例包含或合成聚合A的实例
  • B的实例记录A的实例
  • B的实例紧密地使用A的实例
  • B实例具有A实例的初始化信息,并在创建时传递该信息

从你的描述来看,其中至少有三点是相关的。因此,我想说
任务
负责创建
注释

我认为方法应该在
任务
实体上。但是,尽管如此,该方法不应该是
Create
,而应该是
Add
,因为我不认为
任务
对象有责任创建注释。相反,我会使用类似的东西,这是一种过分的做法,但主要是因为我喜欢progress fluent界面和对象生成器模式:)

任务类,非常不言自明

public class Task
{
    private readonly IList<Comment> Comments = new List<Comment>();

    public void AddComment(ICommentBuilderFinalization commentBuilder)
    {
        Comments.Add(commentBuilder.MakeComment());
    }
}
对象生成器和progressive fluent接口

// First progressive interface
public interface ICommentBuilder
{
    ICommentBuilderPostBy PostWasMadeNow();
    ICommentBuilderPostBy PostWasMadeSpecificallyAt(DateTime postedAt);
}

// Second progressive interface
public interface ICommentBuilderPostBy
{
    ICommentBuilderPostMessage By(string postedBy);
}

// Third progressive interfacve
public interface ICommentBuilderPostMessage
{
    ICommentBuilderFinalization About(string message);
}

// Final
public interface ICommentBuilderFinalization
{
    Comment MakeComment();
}

// implementation of the various interfaces
public class CommentBuilder : ICommentBuilder, ICommentBuilderPostBy, ICommentBuilderPostMessage, ICommentBuilderFinalization
{
    private Comment InnerComment = new Comment();

    public Comment MakeComment()
    {
        return InnerComment;
    }

    public ICommentBuilderFinalization About(string message)
    {
        InnerComment.Text = message;
        return this;
    }

    public ICommentBuilderPostMessage By(string postedBy)
    {
        InnerComment.PostedBy = postedBy;
        return this;
    }

    public ICommentBuilderPostBy PostWasMadeNow()
    {
        InnerComment.PostedAt = DateTime.Now;
        return this;
    }

    public ICommentBuilderPostBy PostWasMadeSpecificallyAt(DateTime postedAt)
    {
        InnerComment.PostedAt = postedAt;
        return this;
    }
}
将所有内容放在一起

var task = new Task();
var commentBuilder = new CommentBuilder().PostWasMadeNow().By("Some User").About("Some Comment");

task.AddComment(commentBuilder);
好的,正如我前面提到的,这个例子在大多数情况下都是过度设计的。但它应该给你一个想法,你可以做什么来保持真正的单一责任原则

“用更少的钱做更多的事是徒劳的”——奥卡姆的威廉。
var task = new Task();
var commentBuilder = new CommentBuilder().PostWasMadeNow().By("Some User").About("Some Comment");

task.AddComment(commentBuilder);