use*_*945 25 domain-driven-design ddd-repositories repository-pattern
我刚刚开始使用DDD,所以这可能是个愚蠢的问题......
是否可以让实体访问存储库(通过某个IRepository接口)在运行时获取值?例如,我想对属性强制执行"默认"选择:
class Person {
private Company _employer;
public Company Employer {
get { return _employer; }
set {
if(value != null) {
_employer = value;
} else {
_employer = employerRepository.GetDefaultEmployer();
}
}
}
...
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,做这样的事情是对DDD原则的可怕违反.如果不是,我的下一个问题是提供存储库使用的最佳方式是什么?是否应该在创建Person对象时提供?
谢谢,P
lom*_*axx 23
这不是对DDD的可怕违反,这是一个可怕的违反......好吧......它只是简单可怕(我说这个舌头在脸颊):).
首先,您的实体变得依赖于拥有存储库......这并不理想.理想情况下,您希望让您的存储库创建Person,然后为其分配在当前域上下文中有效的所有内容.
所以当你需要一个Person时,你会去personRepository.GetPersonWithDefaultEmployer()并找回一个拥有默认雇主的人.personRepository将依赖employeeRepository,并在返回之前使用它来填充此人.
PersonReposotory : IPersonRepository
{
private readonly IEmployerRepository employerRepository;
//use constructor injection to populate the EmployerRepository
public PersonRepository(IEmployerRepository employerRepository)
{
this.employerRepository = employerRepository;
}
public person GetPersonWithDefaultEmployer(int personId)
{
Person person = GetPerson(personId);
person.Employer = employerRepository.GetDefaultEmployer(personId);
return person;
}
}
Run Code Online (Sandbox Code Playgroud)
你问的答案是标准的依赖.
根据经验,不要这样做.保持您的实体不引用存储库.[ 戴上实用的帽子 ]在一些罕见的,非常罕见的情况下,你有一个非常非常好的理由这样做,而不是添加一个大的评论解释你为什么这样做并做 - 添加参考或使用Double Dispatch传递存储库[ 帽子关闭 ]
此外,如果您希望遵循DDD原则,强烈建议您访问领域专家和迭代开发过程(请参阅Eric Evans - 自本书以来我学到了什么 ).
使用域专家,您应该定义边界上下文,最重要的是聚合及其聚合根及其实体和值对象.一开始沿着DDD路走下去并不容易,但是rewords是滔滔不绝的.
关于您发布的代码的一些事项:
不建议在您的实体上安装公共设置器.使用方法代替更好地表达意图.
如果在未初始化_employer字段的情况下创建了person实例,则Employer属性的getter将返回null.如果然后将Employer属性的值设置为null,则对getter的下一次调用将返回非null值.这可能是您班级用户的意外.
设置人员雇主的呼叫者(通过公共设置者或公共方法)应该知道它要设置的确切公司实例,即使它是默认设置.也许调用者可以拥有对存储库的引用.
根据您的具体域,公司可能是一个价值对象.在这种情况下,不是使用null初始化_employer,而是可以使用值对象的默认值对其进行初始化.如果你只有很少的公司(1-2)并且它们是不可变的并且没有特定的行为,情况可能就是这种情况.
我认为很容易说一个实体不应该知道存储库,但很难将其付诸实践。尤其是当一个聚合在其中包含大量 vo 集合时,我们必须重构它并委托操作,例如添加到一些实际充当存储库的域服务,以避免将整个集合加载到内存中的开销。
但我认为让实体知道存储库是不合理的。如果一定要,然后使用 域名服务instead.We也应该考虑如果存储库违反了单一职责原则-它应该有被认为是一个集总根,而不是一个正常的工厂。
归档时间: |
|
查看次数: |
7401 次 |
最近记录: |