目前,当我需要processParams(params)
在不同控制器之间共享方法时,我使用继承或服务。这两种解决方案都有一些不便之处:
- 使用继承,您不能使用多重继承,这意味着您需要将所有控制器实用程序方法放在一个地方。此外,grails 中存在一个错误,在开发模式下未检测到 Base Controller 类中的任何代码更改(您需要重新启动应用程序)
- 使用服务,您无法访问所有注入的属性,如参数、会话、刷新......
所以我的问题是:有没有其他方法可以使用多个控制器可以访问的一些常用方法?
目前,当我需要processParams(params)
在不同控制器之间共享方法时,我使用继承或服务。这两种解决方案都有一些不便之处:
所以我的问题是:有没有其他方法可以使用多个控制器可以访问的一些常用方法?
我喜欢的一个选择是将常用方法编写为一个类别,然后根据需要将其混合到控制器中。它比继承提供了更多的灵活性,可以访问参数之类的东西,并且代码简单易懂。
这是一个小例子:
@Category(Object)
class MyControllerCategory {
def printParams() {
println params
}
}
@Mixin(MyControllerCategory)
class SomethingController {
def create = {
printParams()
...
}
def save = {
printParams()
}
}
通用功能是对新类的调用,不一定是共同祖先。问题提法缺少责任声明。不用说,我们创建一个新类是一个单一的职责。我会根据班级责任做出进一步的决定。
我更喜欢robbbert和Jared的混合答案:我构造了额外的类,将必要的控制器内部作为参数传递给它们。有时类是从方法对象发展而来的。喜欢:
def action = {
def doer = SomeResponsibilityDoer(this.request, this.response)
render doer.action()
}
不是那么简短,但可以让您在测试中获取代码并保持低耦合。
因为SomeResponsibilityDoer
只有几个字段 - 请求响应 - 每个请求都构建它并不是什么大问题。
没有在开发中重新加载控制器更改也没什么大不了的SomeResponsibilityDoer
,因为:
src/groovy
.这无助于您在开发模式下重新启动的问题,但这是我解决此问题的方式。这是丑陋的,可能不是好的做法,但我将通用代码作为闭包放入类中。然后我可以做类似的事情:
new ControllerClosures().action(this)
并从控制器闭包类中
def action={
it.response.something
return [allYourData]
}
您可以使用委托设计模式:
class Swimmer {
def swim() { "swimming" }
}
class Runner {
def run() { "running" }
}
class Biker {
def bike() { "biking" }
}
class Triathlete {
@Delegate Swimmer swimmer
@Delegate Runner runner
@Delegate Biker biker
}
def triathlete = new Triathlete(
swimmer: new Swimmer(),
runner: new Runner(),
biker: new Biker()
)
triathlete.swim()
triathlete.run()
triathlete.bike()
在控制器的情况下,直接在实例字段(或在 nullary 构造函数中)分配帮助类:
class HelperClass {
def renderFoo() { render 'foo' }
}
class FooController {
private @Delegate HelperClass helperClass = new HelperClass()
def index = { this.renderFoo() }
}
委托的类型信息被编译到包含类中。
您可以在 commonService 中编写所有常用方法并使用该服务来调用常用方法