如何在不使用继承的情况下向控制器添加常用操作?

时间:2009-11-30 19:26:19

标签: grails groovy

我需要在不使用继承的情况下向多个控制器添加常用操作。我们所有的控制器都扩展了一个抽象控制器,我想要包含的功能在抽象控制器中没有意义。

我最初的想法是使用Mixin,但似乎动作,因为它们是闭包,不会与包含mixin的控制器“混入”,只有方法。

任何人都可以建议一种方法,我可以获得“mixin”功能,以便为控制器添加动作吗?

谢谢!

4 个答案:

答案 0 :(得分:7)

  

我们所有的控制器都扩展了一个Abstract   控制器和功能我   想要包括在内没有意义   抽象控制器。

那么为什么没有第二个抽象控制器扩展基本控制器,而只是由那些需要此功能的控制器扩展?

这听起来对我来说是最简单,最干净的解决方案 - 当然比使用元编程更好。 “首选组合继承”并不意味着继承是一个根本不可能的事情,应该不惜一切代价避免。

答案 1 :(得分:6)

执行此操作的方法是迭代控制器并使用元编程向其添加方法。

举一个例子,查看perf4j插件(文件Perf4jGrailsPlugin.groovy)。

在其中,你会看到类似的东西:

application.controllerClasses.each() {
            addPerf4jMethods(it.clazz, log)
        } 

def addPerf4jMethods(artefactClass, log) {
        log.info "Adding Per4j methods: ${artefactClass}..."


        artefactClass.metaClass.withStopwatch << { Closure callable ->
            withStopwatch("", null, callable)
        }

        artefactClass.metaClass.withStopwatch << { String tag, Closure callable ->
            withStopwatch(tag, null, callable)
        } 
}

在上面的代码中,您将遍历所有控制器并使用DockWatch添加方法,因此它们现在随处可用。如果您只需要在某些控制器中执行此操作,则显然可以进行额外的检查。

您可以将此代码放入BootStrap.groovy,以便每次应用启动时运行。

答案 2 :(得分:2)

我经常在这种情况下使用的第三个选项是静态导入。这实际上是很多人都不知道的java(不是时髦)的一部分。

因此,如果您有一个类似于您想要共享的静态方法的类:

class Foo {
    static baz = { -> 
        return "baz!"
    }
}   

在要使该方法可用的类中使用“import static”:

import static Foo.baz

class Bar {
    static void main(String[] args) {
        assert "baz!" == baz.call()
    }
}

不需要超类或mixin魔法,让编译器为你完成工作。

答案 3 :(得分:1)

根据新的grails dynamic-controller plugin,它:

  

允许您动态创建控制器并向现有控制器添加操作

使用mixins。

它似乎符合您的要求。