首页 文章

DDD封装和存储库模式

提问于
浏览
3

说我有这个简单的课程

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 回答

  • 3

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

  • 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;
        }
    }
    
  • 1

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

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

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

    查看Memento图案,重新保湿您的物体 . 仅将构造函数用于创建新实例 .

  • 0

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

    • 将您的二传手从 private 更改为 internal . 然后,创建者只需在实例化后设置属性的值 .

    • 添加 internal 构造函数,该构造函数接受所有属性的值并进行设置 .

    无论哪种方式,您仍然可以通过示例中演示的公共方法进行更改 .

相关问题