使用aspect作为从应用程序逻辑中删除防御性检查的方法是一个好主意吗?

时间:2012-02-17 13:06:21

标签: java coding-style aop spring-aop

有点长标题,但这通常是个问题。

我想知道您是否认为执行以下操作是个好主意。

而不是:

public void buyItem(int itemId, int buyerId) {
    if (itemId <= 0) {

        throw new IlleglArgumentException("itemId must be positive");
    }
    if (buyerId <= 0) {

        throw new IlleglArgumentException("buyerId must be positive");
    }
    // buy logic
}

我希望有类似的东西:

@Defensive("isPositive(#itemId, #buyerId)")
public void buyItem(int itemId, int buyerId) {
    // buy logic
}

你认为这是好/可怕/太花哨/太慢? 如果你真的认为它很好我想用SpEL来实现它,那么有没有人有更好/更轻/更快的东西?

谢谢,

5 个答案:

答案 0 :(得分:3)

这不一定是坏事,但是你的简单案例可以用 exception 语句(我最初提到的rather than assertions)来解决。

您似乎正在引入自己的一组注释,项目中的其他开发人员必须接受并适应这些注释。但是,一旦你引入了注释,看起来常规Proxy方法似乎是解决问题的更好的候选者。

总结一下:您所描述的问题可以使用标准的Java备选方案轻松解决,但在更复杂的情况下,它可能是合理的(例如,在spring-security中考虑@Secured),尤其是如果你是开发自己的框架

答案 1 :(得分:2)

我认为是

  • 过度设计
  • 通过依赖外部方面(可能存在或不存在)来破坏封装,以维护对象的不变量
  • 混淆
  • 效率不高
  • 不添加任何值

我喜欢使用Guava's Preconditions类进行此类检查。此外,此类检查是业务逻辑的一部分,恕我直言。

答案 2 :(得分:2)

我认为你的意思是注释,而不是方面。方面通常在他们建议的代码之外。在任何情况下,您都可以使用JSR 303完成帖子中突出显示的验证类型。一个很好的例子:

public void buyItem(@Min(value = 1) int itemId, @Min(value = 1) int buyerId) {
    // buy logic
}

目前有两个众所周知的JSR 303实现:

答案 3 :(得分:1)

看起来像验证。仅供参考,已有几个框架,例如,请查看this questionOVal

我不知道表演,但对我而言,这不是过度工程:你只保留逻辑代码。我喜欢与之合作。

答案 4 :(得分:0)

我更喜欢Java assertion方法。

  1. 这是一种标准方法,所以所有(大多数?)Java程序员都会理解它。自动化工具等也可以解析它。
  2. 你不必自己开发任何东西。我知道它看起来微不足道,但这些东西有升级的习惯。
  3. 除非你能证明你的方法明显更好或做了不同的事情,否则我会使用Java提供的工具和API作为标准。