DDD封装和存储库模式

时间:2012-08-03 13:06:57

标签: c# domain-driven-design

说我有这个简单的课程

public class MyEntity
{
    public DateTime DateUpdated { get; private set; }
    public string Author { get; private set; }
    public string Comment { get; private set; }

    public void AddComment(string comment, string author)
    {
        Author = author;
        Comment = comment;
        DateUpdated = DateTime.Now;
    }
}

我已将setter设为私有来封装该类,并添加了AddComment方法以向我的类添加一些行为。这在创建新对象时非常正常,但是当我想从db加载Entity时,DateUpdated当然设置为我想要避免的当前日期。

我是否可以使用任何模式来避免将DateUpdated setter公开,因为这似乎打破了我很好的封装并弄乱了类的干净界面?该课程当然只是更普遍问题的一个例子。

我现在最接近的是不使用更多公共构造函数,而是创建一个私有构造函数,我可以通过公共静态方法访问它。

5 个答案:

答案 0 :(得分:4)

使用带有与对象字段匹配的参数的构造函数。

这将允许您在启动时填充对象并使它们保持不变。

public MyEntity(DateTime dateUpdated, string author, string comment)
{
  DateUpdated = dateUpdated;
  Author = author;
  Comment = comment;
}

答案 1 :(得分:3)

查看Memento图案,为您的物品重新补水。仅使用构造函数创建新实例。

答案 2 :(得分:1)

您可以像这样重载AddComment方法:

public class MyEntity
{
    public DateTime DateUpdated { get; private set; }
    public string Author { get; private set; }
    public string Comment { get; private set; }

    public void AddComment(string comment, string author)
    {
        Author = author;
        Comment = comment;
        DateUpdated = DateTime.Now;
    }

    public void AddComment(string comment, string author, DateTime dateUpdated)
    {
        Author = author;
        Comment = comment;
        DateUpdated = dateUpdated;
    }
}

答案 3 :(得分:1)

如果您使用NHM等ORM来实现存储库,那么即使属性是私有集,它也会根据数据库中的数据为属性赋值。换句话说,它绕过AddComment方法并直接注入数据。这是有道理的,因为在重构实体时,行为不会重复,只需要复制数据。 NHibernate确实要求实体包含受保护的无参数构造函数。如果使用自己的ORM实现,那么您可以使用Oded建议的构造函数模式,因为在这种情况下,您的实体可以真正保持持久性无知。

答案 4 :(得分:0)

如果负责创建这些对象的存储库位于同一个程序集中,则应该查看internal access modifier。如果这符合您项目的需求,您可以通过以下两种方式之一实现它......

  1. 将您的二传手从private更改为internal。然后,创建者只需在实例化后设置属性的值。
  2. 添加一个internal构造函数,该构造函数接受所有属性的值并设置它们。
  3. 无论哪种方式,您仍然可以通过公示方法进行更改,如您在示例中所示。