请原谅我的英语不好。
好的,我现在正在考虑DDD方法,听起来不错但是......有一个小问题。 DDD表示,域模型层与数据访问层(以及所有其他层)完全分离。因此,当DAL将保存一些业务对象时,它将只能访问此对象的公共属性。现在的问题是:
我们如何保证(通常)一组对象的公共数据 我们需要在以后恢复该对象吗?
示例
我们有以下业务规则:
这是一个描述这些规则的纯POCO:
public class BusinessObject
{
private string _user;
private string _domain;
public BusinessObject(string user, string domain)
{
_user = user;
_domain = domain;
}
public string Email
{
get { return _user + "@" + _domain; }
}
}
因此,在某个时刻,DAL会将此对象保存到外部存储(即SQL数据库)。显然,DAL会将“Email”属性保存到DB中的关联字段。一切都会正常工作,直到我们要求DAL恢复对象。 DAL如何做到这一点?对象必须至少具有“电子邮件”字段的公共设置器。像
这样的东西public string Email
{
set
{
string[] s = value.Split("@");
_user = s[0];
_domain = s[1];
}
}
实际上,该对象将为“User”和“Domain”字段以及方法GetEmail()提供公共getter / setter。但是停下来。我不希望我的POCO拥有这样的功能!它没有业务规则。必须这样才能保存/恢复对象。
我看到另一种选择。可以要求作为DAL一部分的ORM存储恢复对象所需的所有私有字段。但是,如果我们想要将域模型与DAL分开,则这是不可能的。 DAL不能依赖业务对象的某些私有成员。
我能看到的唯一解决方法是使用一些系统级工具,可以为我们创建对象的转储,并且可以随时从此转储中恢复对象。除了对象的公共属性之外,DAL必须将此转储放入存储。因此,当DAL需要从存储中恢复对象时,它将使用转储。当DAL执行不需要实例化对象的操作时(即大多数link2sql查询),可以使用保存到存储的公共属性。
我做错了吗?我需要阅读更多内容吗?关于某些模式,ORM可能?
答案 0 :(得分:5)
我认为你错了这个部分:
我看到另一种选择。作为DAL一部分的ORM可以是 要求存储恢复对象所需的所有私有字段。 但如果我们想要保持域模型分离,这是不可能的 来自DAL。 DAL不能依赖某些私人成员 业务对象。
域模型不依赖于DAL。相反,DAL依赖于Domain模型。 ORM熟悉Domain Objects,包括私有领域。这绝对没有错。实际上,这是在DDD中实现持久无知的最佳方式。这就是Domain类的外观。注意
DAL / ORM唯一需要的是私有无参数构造器:
public class BusinessObject {
private readonly string _user;
private readonly string _domain;
private BusinessObject(){}
public BusinessObject(string user, string domain) {
_user = user;
_domain = domain;
}
public string Email {
get { return _user + "@" + _domain; }
}
}
魔法发生在ORM中。 Hibernate可以使用此映射文件从数据库恢复此对象:
<class name="BusinessObject" table="BusinessObjects">
...
<property name="_user" column="User" />
<property name="_domain" column="Domain" />
...
</class>
持久性无知域代码的另一个方面是DDD Repository:
定义:存储库是一种封装存储的机制, 检索和模拟对象集合的搜索行为。
存储库接口属于Domain,应尽可能基于Ubiquitous Language。另一方面,存储库实现属于DAL(Dependency Inversion Principle)。
答案 1 :(得分:1)
public class BusinessObject
{
private string _user;
private string _domain;
public BusinessObject(string email)
{
string[] s = value.Split("@");
_user = s[0];
_domain = s[1];
}
public BusinessObject(string user, string domain)
{
_user = user;
_domain = domain;
}
public string Email
{
get { return _user + "@" + _domain; }
}
}
一个简单的解决方案就是让你的DAL调用新的BusinessObject(电子邮件)