善用工具
不久前,在博客中 ,我解释了Groovy中Closure的含义。 这篇博客文章将解释一个使用它们的好例子。 最近,我发现自己不得不为服务AJAX请求的大量后端Controller API编写相同的异常处理逻辑。 就像这样:
class ApiRugbyPlayerController {JSON getPlayerStats() {try {...// invoke business service method to get player stats} catch (ServiceException serviceException) {// don't care too much about this.// log and move on... } catch (SessionException sessionException) {// clear out session cookies...// send 403 to client...} catch (Exception ex) {throw new ApiException(ex)}}JSON updatePlayerStats() {try {...// invoke business service method to update player stats} catch (ServiceException serviceException) {// don't care too much about this.// log and move on... } catch (SessionException sessionException) {// clear out session cookies...// send 403 to client...} catch (Exception ex) {throw new ApiException(ex)}}JSON queryPlayerStats(){try {...// invoke business service method to query player stats} catch (ServiceException serviceException) {// don't care too much about this.// log and move on... } catch (SessionException sessionException) {// clear out session cookies...// send 403 to client...} catch (Exception ex) {throw new ApiException(ex)}}
}
可以看出,这里有一些代码重复。 本着DRY的精神(不要重复自己),最好只定义一次此异常处理逻辑,然后重新使用它。 因此,我定义了以下实用程序方法,该方法实现了异常处理模式并采取了关闭操作,该闭包将为其执行异常处理。
private JSON withExceptionHandling(Closure c) {try {...c.call();} catch (ServiceException serviceException) {// don't care too much about this. // log and move on... } catch (SessionException sessionException) {// clear out session cookies...// send 403 to client ...} catch (Exception ex) {throw new ApiException(ex)}}
我们可以使用{}将代码封闭在Groovy中,以使其成为闭包。 这意味着我可以将Controller方法中的逻辑转换为Closures,并将其传递给Utility方法。 而且当我将其传递给实用程序方法时,我甚至不需要将其传递给()内部,因为Groovy并不使您满意。 因此,这意味着我可以消除所有常见的异常处理,消除代码膨胀,而且我的Controller API更整洁。
class ApiRugbyPlayerController {JSON getPlayerStats() {withExceptionHandling {...// invoke business service method to get player stats} }JSON updatePlayerStats() {withExceptionHandling {...// invoke business service method to update player stats} }JSON queryPlayerStats(){withExceptionHandling {...// invoke business service method to query player stats} }private JSON withExceptionHandling(Closure c) {try {...c.call();} catch (ServiceException serviceException) {// don't care too much about this. // log and move on... } catch (SessionException sessionException) {// clear out session cookies...// send 403 to client ...} catch (Exception ex) {throw new ApiException(ex)}}
}
所以我们去了。 我们坚持DRY原则,避免了代码膨胀,并为我们的异常处理提供了专门的场所,确信它可以始终如一地实现。 Groovy闭包的这个例子有点像,但是就像JavaScript中的第二次调用一样。 如果我们想用Java做类似的事情,那将涉及很多代码。 我们可以使用类似命令模式的东西,并将它们的执行放入异常处理逻辑中。 您将具有更多的去耦功能,但是您将拥有更多的代码。 或者,您可以使所有AJAX API输入一个通用方法(例如Front Controller),但在该处处理通用异常。 同样,可能,但仅需更多代码。 在下一次之前,请多保重。
翻译自: https://www.javacodegeeks.com/2014/03/good-use-of-closures.html
善用工具