Mar*_*ers 11 model-view-controller domain-driven-design
在许多领先的DDD项目中,特别是MVC样式,我看到UI使用镜像域实体的显示对象,而不是直接使用这些域对象.这种风格显然是为了解决和分离问题,我个人更喜欢这种风格.
但我不确定的是,这是否是DDD的严格原则,还是这不仅仅是开发人员对它的不同解释.
您是否可以直接在UI中使用域对象,并且仍然遵循该行为中的DDD方法?
或者,总是使用显示对象是DDD最佳实践吗?
注意:当我提到MVC时,我真的很感兴趣是否必须在DDD项目中的几乎所有DDD兼容的UI模式中使用显示对象.
如果你正在做一个MVC模式,你需要查看对象; DDD只是你的模特.这并不意味着你必须始终使用MVC; 例如,可以构建DDD作为模拟器,您所看到的就是发出的日志消息.但是在MVC中你真的应该有单独的视图对象.
现在,问问自己为什么会这样?答案是视图可以改变,即使业务模型没有.DDD模型应该以业务的术语表达对业务至关重要的内容.
在我开始关注Greg Young和Udi Dahan(通过Martin Fowler)的工作之前,我并没有真正开始理解为什么或如何将领域模型与表达问题分离.
他们一直在教导一种称为命令和查询责任隔离(CQRS)的原则.
我对CQRS的解释是,有两组责任可以将域模型拉向不同的方向,从而形成一个两者平庸的模型.这两个职责是命令(即可能导致写入数据库的行为)和查询(即从数据库读取以获取用于UI消费的数据).一个示例是向实体添加getter和setter以支持UI中的数据绑定.如果您的模型具有getter和setter,那么它可能在建模需要在事务上发生的状态更改或封装业务逻辑方面做得很差.它也无法对状态变化的业务环境建模(参见事件采购).
在DDD术语中,您可能会说域模型和表示模型通常位于单独的有界上下文中.
CQRS规定的解决方案是为命令创建一个模型,为查询创建另一个模型.如果您当前的模型具有更改状态的方法(即模型中的行为),以及将状态公开给UI以进行数据绑定的getter,您可以将这两个职责重构为命令和查询的单独模型.查询模型不会映射到您的域实体,而是直接映射到数据库.如果您的数据库未捕获域模型的派生状态,请查看名为Eager Read Derivation的模式.
如果您的系统只是CRUD且没有任何行为,请尝试一个可以自动构建数据库模式的脚手架系统,如ASP.NET动态数据
在设计从域建模开始的软件时,DDD是一种思考方式.正如网页所说:
域驱动设计不是技术或方法.这是一种思考方式和一系列优先事项,旨在加速必须处理复杂域的软件项目.
从这种设计模式中自然而然的一件事是分层架构.正如在DDD模式摘要中所说的那样
将复杂程序划分为LAYERS.在每个LAYER中开发一个具有凝聚力的设计,并且仅取决于下面的层.遵循标准的建筑模式,为上面的层提供松散的耦合.在一个层中集中与域模型相关的所有代码,并将其与用户界面,应用程序和基础结构代码隔离开来.域对象不受显示自身,存储自身,管理应用程序任务等的责任,可以专注于表达域模型.这使得模型能够发展到足够丰富和清晰,以捕获必要的业务知识并使其发挥作用.
是否需要显示对象才能执行此操作?这只是实现这一点的一种方式,但可能甚至不是提供松散耦合的最佳方法.至于一个例子:也许视图层只是一个webbrowser和xlt文件来可视化业务层提取的xml文件?如果有人有更合适的例子,请添加它们.我的观点是DDD强调分层架构,但不限于此可能的解决方案.