DDD与Grails

Pau*_*aul 14 grails domain-driven-design

我找不到任何关于使用Grails 进行域驱动设计(DDD)的信息.

我正在寻找任何最佳实践,经验笔记甚至开源项目,这些都是使用Grails的DDD的好例子.

Dan*_*ski 35

Grails是以领域驱动设计风格实现应用程序的卓越平台.Grails方法的核心是域类,它们驱动整个开发过程.正如你可能在猜测的那样,在Grails中选择字域并不仅仅是巧合.

首先定义域类,然后您可以使用Grails在提供持久性和生成GUI时完成所有繁重工作.值得注意的是,在编写DDD书籍时,它是在Grails或其他类似框架创建之前,因此书中处理的许多问题与框架解决或大大减少的问题有关.

一些DDD概念由Grails解决

我将使用DDD模式摘要来解决不同的DDD元素.(引用下文中的斜体).

领域模型

域模型通过域类,服务,存储库和其他DDD模式构建.让我们详细了解每一个.

实体

"当一个对象通过它的身份而不是它的属性来区分时,将它的主要属性设置为它在模型中的定义"

这些是Grails中的域类.他们通过GORM解决了持久性问题.可以使用GORM DSL对模型进行微调.看看hasOne与belongsTo属性.它可用于定义实体的生命周期及其关系.belongsTo将导致对相关实体的级联删除,而其他不会.所以,如果你有一个Car对象,你可以说Motor"belongsTo"是一辆Car,在这种情况下,Car是一个Aggregate Root和Motor一个聚合.请注意,我在这里谈论实体之间的生命周期关系而不是持久性.

价值对象

"当您只关心模型元素的属性时,将其归类为VALUE OBJECT.使它表达它传达的属性的含义并赋予它相关的功能.将VALUE OBJECT视为不可变.不要给它任何身份......"

在Grails中,您可以使用GORM字段中的"embedded"属性来管理值对象.值对象只能通过它所属的实体访问,没有自己的ID,并且映射到与其所属的实体相同的表.Groovy也支持 @Immutable注释,但我不确定它是如何与Grails一起使用的.

服务

"当域中的重要流程或转换不是ENTITY或VALUE OBJECT的自然责任时,请将模型操作添加为声明为SERVICE的独立接口.使服务无国籍."

就像实体一样,Grails本身也支持服务.您将Grails服务放在Grails项目的services目录中.服务随附开箱即用:

  • 依赖注入
  • 交易支持
  • 一种将服务公开为Web服务的简单机制,以便可以远程访问它们.

模块

"选择讲述系统故事的模块,并包含一组紧密结合的概念."

Grails 插件机制提供了以下功能:一种非常简单的安装和创建插件的方法,定义了应用程序如何覆盖插件等.

骨料

"将ENTITIES和VALUE OBJECTS聚类为AGGREGATES并定义每个对象的边界.选择一个ENTITY作为每个AGGREGATE的根,并通过根控制对边界内对象的所有访问.允许外部对象仅保留对根的引用."

我已经提到了一些生命周期控制机制.您可以使用Grails服务和语言访问控制机制来强制实施访问控制.您可以让Grails服务扮演DDD存储库的角色,只允许访问聚合根.虽然Grails中的控制器可以直接访问实体上的GORM操作,但我认为为了更好的分层设计,控制器应该注入委托给GORM Active Record操作的服务.

工厂

"将创建复杂对象和AGGREGATES实例的责任转移到一个单独的对象,这个对象本身在域模型中没有责任,但仍然是域设计的一部分."

Groovy构建器是通过丰富的DSL构建复杂对象的绝佳选择.在DDD中,工厂是更宽松的术语,不直接转换为GoF抽象工厂或工厂方法.Groovy构建器是GoF Builder模式的DSL实现.

"对于需要全局访问的每种类型的对象,创建一个对象,该对象可以提供该类型的所有对象的内存中集合的错觉.通过众所周知的全局界面设置访问权限.提供添加和删除对象的方法,这些方法将封装数据存储中的实际数据插入或删除.提供基于某些条件选择对象的方法,并返回完全实例化的对象或属性值满足条件的对象集合,从而封装实际的存储和查询技术.仅为实际需要直接访问的AGGREGATE根提供存储库.让客户专注于模型,委托所有对象存储和访问存储库."

Grails Service可用于实现专用的Repository对象,该对象只是将其操作委托给Grails GORM.使用GORM魔法解决持久性问题.每个Domain类都提供了一组动态方法,可以解决典型的CRUD操作,包括ad-hock查询.

断言

"国家的运作后状况以及班级和集体的不变量.如果ASSERTIONS不能直接用您的编程语言编写,请为它们编写自动单元测试."

  • 看一下Groovy @Invariant,@ Requires,@ Ennsures注释,这些可以用来声明DbC样式的不变量和前后条件
  • 使用Grails命令行创建域类时,会自动创建测试类,这些是在域中表达断言的另一种机制.

陈述式设计风格

"灵活的设计可以使客户端代码使用声明式设计.为了说明,下一节将汇总本章中的一些模式,使规范更加灵活和具有说服力."

这是Grails擅长的地方,因为Groovy语言的动态特性和Builder模式支持创建自定义DSL.

分层架构

通过以基于分层MVC的实现形式提出的" 约定优于配置 "应用程序结构,与Grails"开箱即用" .


lun*_*dov 7

目前我不知道任何与Grails和DDD相关的书籍.就个人而言,我不会只专注于Grails.领域驱动设计是一种思维方式,一种组织应用程序和代码的方式.因此,它不受技术的约束.

MVC范例不将模型视为数据访问对象.事实上,它甚至没有提到数据访问层,因为它被理解为在模型下面/封装.当尝试将DDD与基于ActiveRecord模式的MVC技术结合使用时,这会引入一些陷阱,ActiveRecord模式将域逻辑和数据访问代码合并到模型中.它工作得非常好......尤其是在具有很少域逻辑的简单应用程序中,没有真正的区别.但是当事情变得更复杂时,应该记住模型!=数据访问.

就个人而言,我会考虑提高我对DDD的理解:

干杯!