Groovy'with'closure重复尝试catch块?
问题描述:
我有以下的Groovy类:Groovy'with'closure重复尝试catch块?
@Slf4j
class WidgetService {
WidgetDao widgetDao = new WidgetDao()
createWidget(String name, int type) {
try {
widgetDao.createWidget(name, type)
} catch(WidgetException wexc) {
log.error(wexc)
int x = doFizz()
long y = doBuzz(x)
determineHowToHandle(y)
}
}
Widget getWidgetById(Long id) {
try {
widgetDao.getWidgetById(id)
} catch(WidgetException wexc) {
log.error(wexc)
int x = doFizz()
long y = doBuzz(x)
determineHowToHandle(y)
}
}
Widget getWidgetByName(String name) {
try {
widgetDao.getWidgetByName(name)
} catch(WidgetException wexc) {
log.error(wexc)
int x = doFizz()
long y = doBuzz(x)
determineHowToHandle(y)
}
}
def deleteWidget(Widget w) {
try {
widgetDao.deleteWidget(w)
} catch(WidgetException wexc) {
log.error(wexc)
int x = doFizz()
long y = doBuzz(x)
determineHowToHandle(y)
}
}
...dozens of more methods with *exact* same catch block
}
正如你可以看到我有很多重复的,样板代码在我的try-catch块。这将是很好,如果我可以定义一个封闭或某种基于AOP的处理程序只是通过widgetDao
方法的兴趣到关闭/处理程序作为一个lambda或类似的东西:
def createWidgetClosure = { it =>
widgetDao.createWidget(it.name, it.type)
}
def getWidgetByIdClosure = { it =>
widgetDao.getWidgetById(it.id)
}
def tryCatchClosure = { closure =>
try {
closure()
} catch(WidgetException wexc) {
log.error(wexc)
int x = doFizz()
long y = doBuzz(x)
determineHowToHandle(y)
}
}
所以,我的` WidgetService可能会看起来像这样:
@Slf4j
class WidgetService {
WidgetDao widgetDao = new WidgetDao()
createWidget(String name, int type) {
tryCatchClosure(createWidgetClosure())
}
Widget getWidgetById(Long id) {
tryCatchClosure(getWidgetByIdClosure())
}
...dozens of more methods with *exact* same catch block
}
这可能吗?如果是这样,怎么样?
答
您可以简单地通过使用tryCatchClosure
来执行下面的操作。你甚至可以制作tryCatchClosure
一种以Closure
作为参数的方法。
class WidgetService {
WidgetDao widgetDao = new WidgetDao()
def tryCatchClosure(Closure closure) {
try {
closure()
} catch(WidgetException wexc) {
log.error(wexc)
int x = doFizz()
long y = doBuzz(x)
determineHowToHandle(y)
}
}
createWidget(String name, int type) {
tryCatchClosure {
widgetDao.createWidget(name, type)
}
}
Widget getWidgetById(Long id) {
tryCatchClosure {
widgetDao.getWidgetById(id)
}
}
Widget getWidgetByName(String name) {
tryCatchClosure {
widgetDao.getWidgetByName(name)
}
}
def deleteWidget(Widget w) {
tryCatchClosure {
widgetDao.deleteWidget(w)
}
}
// ...dozens of more methods with *exact* same catch block
}
或者您也可以通过覆盖其上的metaClass invokeMethod
方法拦截上WidgetDao
每个方法调用和处理异常(try/catch语句)。 Similar to this。
和'@ Delegate'一起归结为一个oneliner和一些错误处理代码。必须爱groovy – cfrick 2014-10-16 15:18:10
谢谢@cfrick(+1) - 你能解释一下'@ Delegate'的意思吗?也许提供一个代码示例? – smeeb 2014-10-16 15:25:03
@smeeb https://gist.github.com/christoph-frick/448ae72f38e771fc67b5 – cfrick 2014-10-16 15:25:28