1

我有类似的功能

class Chainable {
    public Chainable doStuff(String test) {
        return doSomething(test, true);
    }

    public Chainable doStuff(String test, String test2) {
        String toUse = test + test2;
        return doSomething(toUse, false);
    }

    private Chainable doSomething(String test, boolean version) {
        // do something
        if (somethingBadHappened) {
            throw SpecialException.generate();
        }

        return this;
    }
}

SpecialException是用户应该看到的异常。异常消息故意包含引发此异常的方法。用户会打电话doSomething("x"),如果它失败了,它会显示"Method 'doSomething' failed with the parameters: 'test = x | version = true'"

但是用户并不关心方法doSomething(String, boolean)及其参数。他使用doStuff(String)并希望看到该功能的消息。

所以我要做的是:

public Chainable doStuff(String test) {
    try {
        return doSomething(test, true);
    } catch (SpecialException e) {
        throw SpecialException.generate(e);
    }
}

它将 e 设置为新异常的原因并正确显示"Method 'doStuff' failed with the parameters: 'test = x'"(用户看不到堆栈跟踪,但如果我需要调试,我可以看到到底发生了什么)。

现在,它可以工作了,但是每次我编写一个将其工作委托给辅助函数的新函数时,我都必须重复一遍。问题是,我不知道我应该如何使用辅助函数,因为SpecialException它会根据生成的位置找到方法名称......

还有另一种更好的方法吗?

4

2 回答 2

0

这是您应该做的:向用户显示堆栈跟踪。然后你可以使用

throw new SpecialException();

不用担心会出现什么方法。

于 2013-07-26T09:52:05.240 回答
0

据我所知,据我所知,这可能是使用面向方面编程或 AOP 处理的好情况。在 Java 中,您可以为此使用AspectJ

您将从定义“切入点”开始- 执行代码的特定时刻,例如方法调用。接下来,您将编写一个“建议”,这是在切入点被命中时需要完成的事情。您将这两者放在一个“方面”中,并在构建期间将它们编织到您的字节码中。

在这种情况下,您需要一个切入点来拦截对您的公共方法Chainable的调用,但不应从内部进行调用Chainable

pointcut publicChainableMethod()      :    target(Chainable)
                                        && call(public * *(..))
pointcut firstPublicChainableMethod() :    target(Chainable)
                                        && call(* *(..))
                                        && !cflowbelow(publicChainableMethod());

第一个切入点定义对 上的公共方法的任何调用Chainable,第二个切入点定义对 内的方法的调用Chainable除非它在第一个切入点的控制流中时不应被调用。

接下来,您需要一个SpecialException为您生成新建议的建议:

after() throwing (SpecialException e): firstPublicChainableMethod() {
    throw SpecialException.generate(e);
}

免责声明:我不是 AOP 或 AspectJ 专家,因此这种方法可能无法开箱即用。

于 2013-07-26T10:27:19.393 回答