Grails でコントローラーを生成すると、コントローラーはドメイン層のメソッドを直接呼び出します。これはまったく理解できません。バックエンドとフロントエンドを緊密に結合しているため、これは一種の間違いだと私はいつも言っています。これはサービス層に属すると思います。
ドメイン オブジェクトで定義されたすべてのメソッドに対して、サービス レイヤーで同等のメソッド セットを作成するのはかなり見苦しいので、これを作成してAbstractService
、サービス レイヤーからドメイン レイヤーにすべての (不足している) メソッド呼び出しを委譲します。
abstract class AbstractService {
def entityType
/**
* By default, this method takes the name of the service that extends this
* class, removes the suffix 'Service' and tries to create the Class object
* from the resulting name. Override at will.
*/
protected Class getEntityType() {
if (!entityType) {
try {
entityType = Class.forName(this.class.name[0..-8], false, Thread.currentThread().contextClassLoader)
} catch (ClassNotFoundException e) {
throw new ClassNotFoundException("Class ${this.class.name[0..-8]} could not be found. Please "
+ "override AbstractService#getEntityType() for ${this.class}.")
}
}
entityType
}
def methodMissing(String name, args) {
try {
if (getEntityType()?.metaClass?.getStaticMetaMethod(name)) {
getEntityType().invokeMethod(name, args)
} else if (args?.last()?.metaClass?.getMetaMethod(name)) {
args.last().invokeMethod(name, args.take(args.size() - 1))
} else {
throw new MissingMethodException(name, this.class, args)
}
} catch (MissingMethodException e) {
throw new MissingMethodException(name, this.class, args)
}
}
}
次に、このサービスを次のように拡張します。
class UserService extends AbstractService {
}
そして、私のコントローラーは、たとえば次のようになります。
class UserController {
def userService
def create() {
userService.save(new User(params))
}
def list() {
userService.list(params)
}
// et cetera...
}
このほうがいいと思いませんか?依存性注入のおかげで、たとえば、コントローラーのコードを変更する必要なく、ビジネス レイヤー全体を書き直すことができます。
ご回答ありがとうございます。できるだけ多くの意見をお聞きしたいと思います。