【问题标题】:How to write an exception factory in Java如何在 Java 中编写异常工厂
【发布时间】:2014-01-08 12:36:48
【问题描述】:

我们目前正在开发一个供内部使用的框架。我们现在要使用标准化的异常 ID 和消息。开发人员只需提供一个 ID 和一条默认消息,框架就会查找关联的消息(如果可能)或使用默认消息(如果无法检索该消息)。 第一个想法是编写一个异常工厂,强制开发人员提供错误 ID,然后在工厂方法中查找消息。这种方法的问题是,在堆栈跟踪(创建异常的工厂方法)中添加了一个额外的框架。那样不是很好。几乎所有试图隐藏创作的解决方案都有这个问题。 第二个想法是将消息查找和我们的异常类结合起来,并编写一个抽象异常类,它在构造函数中获取错误 ID 并处理消息查找。但这也不是很好,因为它缺乏松散耦合。 第三个想法是让开发人员每次都编写消息的查找..也不好..

你有什么想法吗?

附:我认为那是我第一次需要 Java 中的宏..

代码中的不同方法:

1.

throw createException(new ErrorId("123"), TechnicalException.class, "defaultmsg"); //uses reflection, also not very nice but works

throw createTechnicalException(new ErrorId("123", "defaultmsg"); //write a method for every type of exception

2.

public TechnicalException(ErrorId errorId, String defaultmsg) {
    super(defaultmsg);
    //get msg here and set on a new field cause detailMessage is not accessible. Also overwrite toString();
}

throw new TechnicalException(new ErrorId("123"), "defaultmsg");

3.

ErrorId errorId = new ErrorId("123");
String msg = someProvider.getMessage(errorId);
throw new TechnicalException(errorId, msg);

【问题讨论】:

  • 创建一个 error message 工厂而不是 exception 工厂怎么样?

标签: java exception frameworks factory


【解决方案1】:

可以编辑堆栈跟踪,删除不需要的元素。如果所有异常的构造函数都需要相同的数据,则使用单个 createException,否则使用 createCustomException 方法。

这会删除不必要的堆栈跟踪元素。

public static <T extends Throwable> T adjustStackTrace(T ex, int removedElements) {
    //use an explicit constraint for removedElements
    if (removedElements < 1) {
        throw new IllegalArgumentException("removedElements may not be less than 1");
    }
    final StackTraceElement[] stack = ex.getStackTrace();
    //or an implicit constraint
    removedElements = Math.max(removedElements, stack.length);

    final StackTraceElement[] newStack = new StackTraceElement[stack.length - removedElements];
    System.arraycopy(stack, removedElements, newStack, 0, stack.length - removedElements);
    ex.setStackTrace(newStack);
    return ex;
}

自定义异常的方法:

public static TechnicalException createTechnicalException(Object... someExceptionSpecificData) {
    StringBuilder sb = new StringBuilder();
    sb.append("...").append("..."); //create a message

    //process the someExceptionSpecificData
    Object[] someNewData = someExceptionSpecificData;

    TechnicalException ex = new TechnicalException(sb.toString(), someNewData);

    ex = adjustStackTrace(ex, 1 /*remove StackTraceElement, related to this method call*/);
    return ex;
}

或者您可以使用单个方法并传递所需的异常类:

public  Exception createException(Class<?> exClass, Object... someExceptionSpecificData) {...}

用法示例:

public void useExceptionFactory() {
    throw ExceptionFactory.createTechnicalException();
}

public void adjustEvenMore() {
    //adjust even more to hide the implementation of your library
    throw ExceptionFactory.adjustStackTrace(ExceptionFactory.createTechnicalException(),1);
}

本示例基于 OVal 框架中的 net.sf.oval.internal.util.Assert,参见http://oval.sourceforge.net/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-26
    相关资源
    最近更新 更多