2014-01-08 3 views
2

В настоящее время мы разрабатываем инфраструктуру для внутреннего использования. Теперь мы находимся на том этапе, что хотим использовать стандартизованные идентификаторы исключений и сообщения. Разработчик должен просто предоставить идентификатор и сообщение по умолчанию, и инфраструктура ищет связанное сообщение (если это возможно) или использует сообщение по умолчанию (если сообщение не может быть получено). Первой идеей было создание фабрики исключений, которая заставляет разработчика предоставлять идентификатор ошибки, а затем искать сообщение в заводском методе. Проблема с этим подходом заключается в том, что в stacktrace добавлен дополнительный кадр (фабричный метод, в котором создается исключение). Это не очень красиво. Эта проблема вызывает почти все решения, которые пытаются скрыть создание. Вторая идея заключалась в том, чтобы связать поиск сообщений и наш класс исключений и написать абстрактный класс исключения, который принимает идентификатор ошибки в конструкторе и обрабатывает поиск сообщения. Но это также не очень приятно, потому что ему не хватает свободного сцепления. Третья идея позволила разработчику написать поиск сообщения каждый раз .. также плохо ..Как создать фабрику исключений в Java

У вас есть идеи?

P.S. Я думаю, вот в первый раз, мне нужно макросы в 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); 
+3

Как создать сообщение об ошибке ** ** вместо ** exception ** factory? –

ответ

0

Можно отредактировать трассировку стека, удалив ненужные элементы. Если всем конструкторам исключений нужны одни и те же данные, используйте single 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; 
} 

метод для пользовательского excepton:

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); 
} 

Этот пример основан на сети. sf.oval.internal.util.Assert из OVal framework, см. http://oval.sourceforge.net/

Смежные вопросы