如何在Grails中拆分域逻辑和数据访问(这是一个好主意)?
我们编写的许多软件应用程序都以数据(基础)为中心,而在Grails中,通常会将服务类或控制器直接保存到DataSource.groovy中配置的数据库。更改数据库很容易,但我们并没有真正独立于代码中的持久性实现。
我正在尝试编写一个为不同的持久性和数据源(不仅是数据库)实现打开的应用程序,并专注于业务域而不是数据库实体。测试时这也是一个加分(易于编写假/模拟持久性) 最初我只有一个持久性实现 - Grails域类,使用GORM。但是我将来可能希望拥有除数据库之外的其他数据源,例如休息服务或其他东西。
目前,我只有数据库作为数据源,并且主要做的是粗略的东西(以及一些域逻辑)。我想我仍然处于困境中。#34; old"思考,专注于数据库持久性,因为我的大多数业务领域类都有一个Grails域类等效的副本。当要保留域类时,我只需将属性复制到Grails域类。
我对这个解决方案不太满意。我可以想到至少两种可能的改进/变化:
我看过一些关于Grails架构的有趣讨论,包括干净的架构,六边形架构和ddd,但我还没有找到任何例子。有没有?
此时,正如我所说,许多功能都是CRUD的东西,但不是一切。此外,应用程序可能有更多的业务逻辑,所以我宁愿不使用"默认" Grails的架构,包含视图,控制器,服务,域。我想要一个"核心"应用程序,其方式独立于grails视图/控制器和域/ GORM
答案 0 :(得分:0)
你发布问题已经有一段时间了,但对我来说这是一个非常有趣的话题......
我目前在大型Java8项目中工作,这些项目实现了清洁架构,ddd,cqrs和六边形架构等原则。我对Grails 1.x项目的经验也很有限,我记得和你现在问的问题一样。
现在我有了更广阔的视野,老实说,我认为强迫Grails进入一个干净的架构是没有意义的。你将有一个非常痛苦的时间试图实现它,你可能不会对结果感到满意。
Grails中的所有内容都旨在以固定的,基于约定的方式使用。从GORM开始是一个ActiveRecord实现,并遵循他们对目录结构,你需要定义的工件(控制器,服务,模型......)等所做的每一个小决定。我不是说这个不好。事实上,当你开发适合这种模式的东西时,这很好。
您的工件之间的这种耦合和隐式行为使您的业务逻辑非常难以模拟您的数据访问(或您的http交互,或与此相关的任何其他与第三方的交互)。
从DDD的角度来看,您应该支持基于ActiveRecord实现的数据或基于集合的存储库。然后,您可以开始将持久性逻辑与域模型分开。尝试在保持与持久层的类似ActiveRecord交互的同时执行此操作将产生非常“脏”的适应层,并且需要大量重复。
例如,在尝试使用应该进入不同数据库表的聚合对象来调整复杂域时,您将非常困难。
现在,针对您建议的两项改进,我可以告诉您这些改进:
- 我的Grails域类可以与业务域类的组织方式更加不同,因此我不只是将属性从一个类复制到另一个类。在读取或写入数据库时,这仍将涉及从一个类到另一个类的大量属性映射。
醇>
你的确可以做你说的话。只需在src / groovy文件夹上放置一些代码即可。你将面临的主要问题是依赖注入。当Grails在标准目录中定义时,Grails会自动为您的服务和控制器注入依赖项。对于其他一切,您需要明确tell Grails how to take dependencies and pass them to your custom artifacts。
- 也许有一种方法可以使用业务领域类,从常规的src / main / groovy包中用GORM东西装饰?或者以其他方式拆分域逻辑和持久性?我已经看到可以通过在域类上使用hibernate conf来实现这一点。这是唯一的方法吗?
醇>
如果使用GORM修饰src / groovy中定义的Domain对象(如果可能的话),则会遇到同样的问题。您的任务是将域与持久性逻辑隔离开来。通过在其中包含任何GORM来实现此目的。
我在这里考虑的一切都是:
有一个非常全面的库列表,您可以浏览它们的灵感:Awesome Java