i've build an application using grails, logically the system is separating into some of modules. at first i was separate the logic by implementing a package that represent modules.
But the problem is occurred when i need to "decoupled" the application. Because some client doesn't need all modules, they just need some modules, and the combination is vary on every client.
The technical problem is to separating code between grails modules. The domain class is really tightly coupled. I want to rewrite my application just to make the separating is not only logically, but every modules have separate code base. So a different team that develop a different modules, working on different code base.
The example of the real problem is like this :
Modules : user (core), calendar, academic
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]
}
Because that dependency on the level code, i can't separate the user, calendar, academic domain class, even some client doesn't need the academic module. The application is tightly coupled, because the domain class can't be separated.
There some alternative that come in my mind :
- Implement dynamic domain plugin to make domain class is more portable (http://burtbeckwith.com/blog/?p=364), but i still confuse how to integrate this in application
- Make each modules as plugin (with complete domains, controllers, and views), but this doesn't solve the problem, the dependence domain still needed on the same code base.
The question is, how to create an "adapter" object between domain class in grails? the "adapter" object maybe a service class. With that adapter, relation between domain not necessarily check at compile time
maybe the solution like this :
class Student {
//dependency to other modules
//checked at runtime
def hasManyOnOtherModules = ["exams:academic.ExamResult"]
}
The ideal implementation is every module can be running and tested separately.