说我有这个简单的课程
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公开,因为这似乎打破了我很好的封装并弄乱了类的干净界面?该课程当然只是更普遍问题的一个例子。
我现在最接近的是不使用更多公共构造函数,而是创建一个私有构造函数,我可以通过公共静态方法访问它。
答案 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。如果这符合您项目的需求,您可以通过以下两种方式之一实现它......
private
更改为internal
。然后,创建者只需在实例化后设置属性的值。internal
构造函数,该构造函数接受所有属性的值并设置它们。无论哪种方式,您仍然可以通过公示方法进行更改,如您在示例中所示。