我已经使用 grails 构建了一个应用程序,从逻辑上讲,系统正在分成一些模块。起初我通过实现一个代表模块的包来分离逻辑。
但是当我需要“解耦”应用程序时就会出现问题。因为有些客户端不需要所有模块,他们只需要一些模块,并且每个客户端的组合都不同。
技术问题是在 grails 模块之间分离代码。领域类确实是紧密耦合的。我想重写我的应用程序只是为了使分离不仅在逻辑上,而且每个模块都有单独的代码库。所以一个不同的团队开发不同的模块,在不同的代码库上工作。
真正问题的例子是这样的:
模块:用户(核心)、日历、学术
package user.group
import academic.RaportSummary
import academic.examResult
class Student {
static hasMany = [exams:ExamResult,raports:RaportSummary]
}
package calendar
class Semester {
}
package academic
import calendar.Semester
import user.group.Student
class SubjectSummary {
static belongsTo = [student:Student, semester:Semester]
}
class RaportSummary {
static belongsTo = [student:Student]
}
因为对级别代码的依赖,我无法分离用户、日历、学术领域类,甚至某些客户端不需要学术模块。应用程序是紧耦合的,因为域类不能分离。
我想到了一些替代方案:
问题是,如何在 grails 中的域类之间创建一个“适配器”对象? “适配器”对象可能是一个服务类。使用该适配器,域之间的关系不必在编译时检查
也许这样的解决方案:
class Student {
//dependency to other modules
//checked at runtime
def hasManyOnOtherModules = ["exams:academic.ExamResult"]
}
理想的实现是每个模块都可以单独运行和测试。
最佳答案
您的问题非常具有挑战性,您将不得不重新设计,但是……没有什么是不可能的。
1 - 删除循环依赖
如果不删除这些依赖项,您就没有机会模块化您的应用程序。
由于 user 是您的基础包,因此您需要从此包中删除任何外部依赖项。在您的示例中,这意味着 Student
域必须删除对 ExamResult
的引用和 RaportSummary
IE。
class Student {
} //no hasMany
和
class ExamResult {
Student student
}
class RaportSummary {
Student student
}
然后你可以创建一些方法,如
RaportService.getRaports(student) { Raports.findAllbyStudent(student)}
2 - 将你的包作为插件
满足您的要求的最佳方法是为用户、日历和学术创建 grails 插件,并具有以下依赖项:
user
插件是独立的calendar
插件是独立的(或者可能取决于用户插件)academic
插件依赖于 user
和 calendar
插件 3 - 构建您的应用程序
最后,根据您的客户,您可以单独使用学生插件或使用所有插件构建您的应用程序
等等。
关于design-patterns - 如何打破 Grails 域类之间的硬依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5188334/