我是DDD + TDD世界的新手.但我已经编程了将近9年.
有人可以解释我坚持不懈的好处吗?典型的nHibernate应用程序只是将类和数据库之间的依赖关系推送到映射文件.
如果我更改类文件或数据库,我必须更改映射文件.那么是不是只是通过添加一个抽象层来推动依赖?在我看来,到目前为止,我认为这不是革命性的.但我不确定我是否遗漏了什么.
最后,我如何测试映射文件?映射文件中可能会出现错误,我该如何测试它们?
我们如何使用CQRS/DDD模拟经典的多对多关系?
我知道DDD和CQRS实现和解决方案都倾向于特定于域,因此可能很难对这个问题提出一般性答案.
但是,我们假设我们在Book和Author之间有熟悉的关系.这是一种经典的多对多关系.
对我来说,Book and Author似乎是两个不同的实体,每个实体都属于它们自己的Aggregate Root.因此,明确地模拟它们之间的多对多关系并不是一种可行的方法.
我们如何建模AddBookCommand?我们希望能够在我们的图书馆中添加一本书,并以某种方式说明某位作者撰写本书.我们如何建模(并坚持)这种关系?
无论是书还是作者似乎是不错的候选值对象 ...
我一直在阅读使用Command对象来表示我们的域公开的用例,以及Command Handler对象来处理这些命令.
例如:
RegisterUserCommandRegisterUserCommandHandler但它看起来与a具有完全相同RegisterUserService,其中命令对象将表示registerUser()方法的参数.
当然,如果方法有太多的参数,我最终会创建一个对象来包装它们,并且该对象与它相同RegisterUserCommand.
那么为什么有不同的模式来表示同样的事情呢?服务很普遍,而不是命令(根据我的经验); 我错过了什么区别?简而言之,为什么我会使用一个而不是另一个?
我一直在探索BDD/DDD,因此试图找到Repository模式的正确实现.到目前为止,很难就实现这一点的最佳方式达成共识.我试图将其归结为以下变化,但我不确定哪种方法最好.
作为参考,我正在构建一个以NHibernate作为后端的ASP.MVC应用程序.
public interface IRepository<T> {
// 1) Thin facade over LINQ
T GetById(int id);
void Add(T entity);
void Update(T entity);
void Remove(T entity);
IQueryable<T> Find();
// or possibly even
T Get(Expression<Func<T, bool>> query);
List<T> Find(Expression<Func<T, bool>> query);
}
public interface IRepository<T> {
// 2) Custom methods for each query
T GetById(int id);
void Add(T entity);
void Update(T entity);
void Remove(T entity);
IList<T> FindAll();
IList<T> FindBySku(string sku);
IList<T> FindByName(string name);
IList<T> FindByPrice(decimal price);
// ... and so on
}
public …Run Code Online (Sandbox Code Playgroud) 我在工作中讨论过"域模型中的继承使开发人员生活变得复杂".我是OO程序员,所以我开始寻找在域模型中具有继承性的论据,这样可以简化开发人员的生活,而不是让交换机遍布整个地方.
我想看到的是:
class Animal {
}
class Cat : Animal {
}
class Dog : Animal {
}
Run Code Online (Sandbox Code Playgroud)
另一位同事说的是:
public enum AnimalType {
Unknown,
Cat,
Dog
}
public class Animal {
public AnimalType Type { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我如何说服他(链接是欢迎的)一个类层次结构比在这种情况下具有枚举属性更好?
谢谢!
假设我们拥有受CQRS启发的架构,其中包括命令,域模型,域事件,读取模型DTO等组件.
当然,我们可以在域模型中使用值对象.我的问题是,它们是否也应用于:
我没有看到任何在上述组件中使用Value Objects(VO)的示例.相反,使用原始类型.也许这只是简单的例子.毕竟,我对DDD中使用VO的理解是它们可以作为整个应用程序的粘合剂.
我的动机:
命令.
假设用户提交包含地址字段的表单.我们有Address Value Object来表示这个概念.在客户端构造命令时,我们应该验证用户输入,当它格式正确时,我们可以在那里创建Address对象并用它初始化Command.我认为不需要将Address对象的创建委托给命令处理程序.
域事件.
域模型已经在值对象方面运行,因此通过使用VO发布事件而不是将它们转换为基本类型,我们可以避免使用某些映射代码.我很确定在这种情况下使用VO是可以的.
DTO的.
如果我们的查询端DTO可以包含值对象,则可以提供更多灵活性.例如,如果我们有Money对象,我们可以选择是以EUR还是USD显示,不需要更改Read Model.
域驱动设计已成为我的首选架构.我已经能够在ASP.net框架中找到大量的书籍和教程来应用DDD原理.它似乎主要来自Java开发人员现在所做的一段时间.
对于我的个人项目,我开始更倾向于Python,即使我发现很难放弃静态类型.我希望能够找到使用动态语言应用DDD的大量帮助.关于Python和DDD似乎没有什么.这是为什么?显然DDD可以很好地应用于Python.人们不会在Python中承担大量项目吗?或者在动态类型中使用DDD简单地应用DDD因此减少了所需的学习量?
也许我的问题是由于我缺乏Python经验.您可能对我提出的任何建议将不胜感激.
我仍然对存储库模式有些困惑.我想要使用此模式的主要原因是避免从域调用EF 4.1特定数据访问操作.我宁愿从IRepository接口调用泛型CRUD操作.这将使测试更容易,如果我将来必须更改数据访问框架,我将能够这样做,而无需重构大量代码.
这是我的情况的一个例子:
我在数据库中有3个表:Group,Person,和GroupPersonMap.GroupPersonMap是一个链接表,只包含主键Group和Person主键.我用VS 2010设计器创建了3个表的EF模型.EF很聪明,可以假设它GroupPersonMap是一个链接表,因此它不会在设计器中显示它.我想使用我现有的域对象而不是EF生成的类,所以我关闭了模型的代码生成.
我与EF模型匹配的现有类如下:
public class Group
{
public int GroupId { get; set; }
public string Name { get; set; }
public virtual ICollection<Person> People { get; set; }
}
public class Person
{
public int PersonId {get; set; }
public string FirstName { get; set; }
public virtual ICollection<Group> Groups { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我有一个通用的存储库接口,如下所示:
public interface IRepository<T> where T: class …Run Code Online (Sandbox Code Playgroud) c# domain-driven-design aggregateroot repository-pattern entity-framework-4.1
我想了解基于CQRS的系统中命令处理程序,聚合,存储库和事件存储之间关系的一些细节.
到目前为止我所理解的:
到现在为止还挺好.现在有一些我还没有得到的问题:
cqrs ×4
c# ×3
architecture ×2
bdd ×1
dddd ×1
domain-model ×1
dto ×1
enums ×1
events ×1
inheritance ×1
java ×1
oop ×1
python ×1