Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何在Grails中拆分域逻辑和数据访问

如何在Grails中拆分域逻辑和数据访问
EN

Stack Overflow用户
提问于 2015-01-11 00:56:20
回答 1查看 934关注 0票数 0

如何在Grails中拆分域逻辑和数据访问(这是一个好主意)?

我们编写的许多软件应用程序都是以数据(基)为中心的,在Grails中,经常会从服务类或控制器直接持久化到DataSource.groovy中配置的数据库。更改数据库很容易,但我们并不完全独立于代码中的持久性实现。

我试图编写一个为不同的持久性和数据源(不仅仅是数据库)实现打开的应用程序,并将重点放在业务域而不是数据库实体上。在测试时(容易编写假/模拟持久性),这也是一个好处--最初我只有一个持久性实现--使用GORM的Grails域类。但是,将来我可能希望拥有数据库以外的其他数据源,例如rest服务或其他什么。

目前,我只将数据库作为数据源,并且主要做crud操作(以及一些域逻辑)。我认为我仍然停留在“旧”思维中,专注于数据库持久性,因为我的大部分业务域类都有一个Grails域类,即它的副本。当要持久化域类时,我只需将属性复制到Grails域类。

我对这个解决办法不太满意。我至少可以想到两种可能的改进/改变:

  1. 我的Grails域类可以与业务域类更不同的组织方式,所以我不只是将属性从一个类复制到另一个类。不过,在从/写入数据库时,这仍然需要从一个类到另一个类的大量属性映射。
  2. 也许有一种方法可以使用业务域类,从常规的src/main/groovy包中使用GORM之类的东西来装饰?还是以其他方式分割域逻辑和持久化?我已经看到,通过在域类上使用hibernate conf是可以做到这一点的。这是唯一的办法吗?

我看到了一些关于Grails体系结构的有趣的讨论,包括干净的体系结构、六边形的体系结构和ddd,但是我还没有找到任何例子。有吗?

在这一点上,正如我所说的,大部分功能都是CRUD功能,但不是所有功能。而且,应用程序可能具有更多的业务逻辑,因此我不希望使用带有视图、控制器、服务、域的Grails“默认”体系结构。我需要一个“核心”应用程序,它在某种程度上独立于grails视图/控制器和域/GORM。

EN

回答 1

Stack Overflow用户

发布于 2015-06-14 03:36:02

你写问题已经有一段时间了,但这对我来说是个很有趣的话题.

我目前在大型Java8项目中工作,这些项目实现清洁架构、ddd、cqr和六角形体系结构等原则。我在Grails1.x项目方面的经验也很有限,我记得我问过的问题和你现在一样。

现在我有了更广阔的视角,我真诚地认为,强迫Grails进入一个干净的体系结构是没有意义的。你会有一个非常痛苦的时间,试图实现它,你可能会不满意的结果。

Grails中的所有东西都被设计成以一种固执己见、基于约定的方式使用。从GORM是一个ActiveRecord实现开始,然后是他们就目录结构、您需要定义的工件(控制器、服务、模型.)的语义所做的每一个小小的决定。我不是说这很糟糕。事实上,当您正在开发适合于这种事物模式的东西时,这是很棒的。

工件之间的这种耦合和隐式行为使得除了数据访问(或http交互,或与第三方的任何其他交互)之外,很难建模您的业务逻辑。

从DDD的角度来看,您应该倾向于数据或基于集合的存储库,而不是ActiveRecord实现。然后,您可以开始将持久化逻辑与域模型分离。尝试这样做,同时保持ActiveRecord与持久化层的交互,将会产生一个非常“脏”的适应性层,并且会有大量的重复。

您将遇到一段非常困难的时间,特别是在尝试使用聚合对象来调整复杂域时,例如,这些对象应该进入不同的数据库表。

现在,针对您建议的两个改进,我可以告诉您:

  1. 我的Grails域类可以与业务域类更不同的组织方式,所以我不只是将属性从一个类复制到另一个类。不过,在从/写入数据库时,这仍然需要从一个类到另一个类的大量属性映射。

你真的可以按你说的做。只需在src/groovy文件夹中放置一些代码即可。这里您将面临的主要问题是依赖注入。Grails在标准目录中定义服务和控制器时自动注入它们的依赖项。对于其他方面,您需要显式地进行告诉Grails如何获取依赖项并将它们传递给您的自定义工件。

  1. 也许有一种方法可以使用业务域类,从常规的src/main/groovy包中使用GORM之类的东西来装饰?还是以其他方式分割域逻辑和持久化?我已经看到,通过在域类上使用hibernate conf是可以做到这一点的。这是唯一的办法吗?

如果您用GORM装饰在src/groovy中定义的域对象(如果可能的话),您将遇到同样的问题。这里的任务是将您的域与持久性逻辑隔离开来。这样做的方式是让任何一个戈姆都没有达到它的目的。

我在这里的建议是:

  1. 切换到其他不太耦合的库,这些库允许您设计自己的体系结构(即大鼠约克)或
  2. 如果这不是一种选择,那就完全拥抱圣杯式的事情吧。

有一个非常全面的库列表,您可以浏览它以获得灵感:超赞Java

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27885441

复制
相关文章
PHP的命名空间
命名空间用来解决在编写类库或应用程序时创建可重用的代码如类或函数时碰到的两类问题:
老雷PHP全栈开发
2020/07/02
1.9K0
PHP命名空间
概述 什么是命名空间呢? 这个概念我第一次知道是在C++中. 首先, 为什么要用到命名空间呢? 当然是为了解决重名的问题了, 其实命名空间和Java中的包有着异曲同工之妙, Java中 a包下的Tes
烟草的香味
2019/07/25
2.3K0
PHP命名空间
PHP命名空间
本文是复习所写,并不会涵盖一些基础知识点 定义 命名空间就相当于操作系统中目录的概念 主要是为了解决以下两个问题: 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突 为很
码一
2022/06/06
2.5K0
PHP命名空间
python中的命名空间和变量作用域
namespace,称之为命名空间,是名称和对象之间的映射,通常以字典的形式保存变量名和其所指代的变量值之间的映射关系。
生信修炼手册
2020/05/28
1.3K0
php命名空间详解
1、命名空间概述 从广义上来说,命名空间是一种封装事物的方法。在很多地方都可以见到这种抽象概念。例如,在操作系统中目录用来将相关文件分组,对于目录中的文件来说,它就扮演了命名空间的角色。具体举个例子,文件 foo.txt 可以同时在目录/home/greg 和 /home/other 中存在,但在同一个目录中不能存在两个 foo.txt 文件。另外,在目录 /home/greg 外访问foo.txt 文件时,我们必须将目录名以及目录分隔符放在文件名之前得到 /home/greg/foo.txt。这个原理应用
苦咖啡
2018/05/07
2.5K0
PHP 命名空间介绍
文件夹对于文件夹内的文件来说就充当了命名空间的角色,两个文件名相同的文件不同放在同一个文件夹下,但是可以放在不同的文件夹下
很酷的站长
2023/01/05
1.7K0
PHP 命名空间介绍
PHP-命名空间
在一个大的项目中,可能会遇到同名的类、函数、常量,为了区分这些元素,我们可以将这些元素分别存放到不同的命名空间中。
cwl_java
2022/11/30
1.7K0
PHP中命名空间是怎样的存在(一)?
命名空间其实早在PHP5.3就已经出现了。不过大部分同学可能在各种框架的使用中才会接触到命名空间的内容,当然,现代化的开发也都离不开这些能够快速产出的框架。这次我们不从框架的角度,仅从简单的代码角度来解析一下命名空间的概念和使用。
硬核项目经理
2020/04/08
9490
PHP中命名空间是怎样的存在?(二)
今天带来的依然是命名空间相关的内容,本身命名空间就是PHP中非常重要的一个特性。所以关于它的各种操作和使用还是非常复杂的,光使用方式就有很多种,我们一个一个的来看。
硬核项目经理
2020/04/08
9560
PHP中命名空间是怎样的存在?(三)
这是与命名空间有关的最后一篇。最后还是两个比较简单的内容,是关于命名空间和全局相关的一些类、函数、常量的使用对比。当然,最后我们还会总结一下命名空间的名称解析规则做为这三篇系列文章的结束。
硬核项目经理
2020/04/08
1K0
秒懂php的命名空间
“什么是命名空间?从广义上来说,命名空间是一种封装事物的方法。在很多地方都可以见到这种抽象概念。例如,在操作系统中目录用来将相关文件分组,对于目录中的文件来说,它就扮演了命名空间的角色。具体举个例子,文件 foo.txt 可以同时在目录/home/greg 和 /home/other 中存在,但在同一个目录中不能存在两个 foo.txt 文件。另外,在目录 /home/greg 外访问 foo.txt 文件时,我们必须将目录名以及目录分隔符放在文件名之前得到 /home/greg/foo.txt。这个原理应用到程序设计领域就是命名空间的概念。”(来自php官网)
碧海长天
2021/10/21
1.4K0
PHP命名空间学习笔记
从广义上来说,命名空间是一种封装事物的方法。在很多地方都可以见到这种抽象概念。例如,在操作系统中目录用来将相关文件分组,对于目录中的文件来说,它就扮演了命名空间的角色。具体举个例子,文件 foo.txt 可以同时在目录/home/greg 和 /home/other 中存在,但在同一个目录中不能存在两个 foo.txt 文件。另外,在目录 /home/greg 外访问 foo.txt 文件时,我们必须将目录名以及目录分隔符放在文件名之前得到 /home/greg/foo.txt。这个原理应用到程序设计领域就是命名空间的概念。
大江小浪
2019/02/22
1.6K0
Python变量的命名_python函数命名规则
变量名只有在第一次出现的时候,才是定义变量。当再次出现时,不是定义变量,而是直接使用之前定义的变量。
全栈程序员站长
2022/08/18
1.3K0
Python变量的命名_python函数命名规则
PHP命名空间(Namespace)初探
命名空间一个最明确的目的就是解决重名问题,PHP中不允许两个函数或者类出现相同的名字,否则会产生一个致命的错误。这种情况下只要避免命名重复就可以解决,最常见的一种做法是约定一个前缀。
OwenZhang
2021/12/08
1.7K0
Swift中的命名空间
命名空间namespace在C++、C#里面是一个常见概念,Swift中也引入了这样一个机制,下面来探索一下这个命名空间的来龙去脉。
YungFan
2018/12/26
2.3K0
Dom4j解析带有命名空间的XML文件
    今天我在解析KML文件的过程中,使用XPath表达式,可是返回的结果总是null,纠结了很久,后来通过查资料,发现是我的KML中有命名空间的缘故。
卡尔曼和玻尔兹曼谁曼
2019/01/25
2.2K0
Dom4j解析带有命名空间的XML文件
PHP-MVC添加命名空间
1.3 添加命名空间 通过文件目录地址做命名空间,这样获取了命名空间就能知道文件存放的地址。 Model.class.php namespace Core; class Model { ..
cwl_java
2020/03/28
1.7K0
【C++】命名空间 namespace 与 标准流 iostream ( 命名空间概念简介 | 命名空间定义 | 命名空间使用 | iostream 中的命名空间分析 )
命名空间 namespace 又称为 名字空间 , 名称空间 , 名域 , 作用域 , 是 C++ 语言 对 C 语言 的扩展 之一 ;
韩曙亮
2023/10/15
8000
【C++】命名空间 namespace 与 标准流 iostream ( 命名空间概念简介 | 命名空间定义 | 命名空间使用 | iostream 中的命名空间分析 )
点击加载更多

相似问题

带有函数的Php命名空间

10

带有命名空间的函数中的PHP函数

12

php中的命名空间函数

07

php函数命名空间

20

变量中的PHP命名空间类

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文