debugjavaMinor
Allowing "plugin" programmers to subscribe to messages
Viewed 0 times
allowingprogrammerspluginmessagessubscribe
Problem
I am having difficulty deciding how to implement an exception handling strategy.
I am using an observer pattern to allow "plugin" programmers to subscribe to
What irks me is that the catch block has become very redundant code, copied throughout 95% of the ~50 existing listeners. Can we come up with something better?
A good solution should:
There is a subtle requirement needed for the solution. The
If the
I am using an observer pattern to allow "plugin" programmers to subscribe to
Messages. These subscribers generally log a unique error (and do some other stuff) under an exceptional circumstance during handling the message. The code snippet below is an example of what a common implementation (and its interface) looks like:// API interface
interface IMessageListener {
void onMessage(Message m);
}
class StuffMessageListener implements IMessageListener {
...
@Override void onMessage(Message m) {
try {
Stuff s = stuffDAO.getStuff(..); // throws SQLException
...
m.reply(true);
} catch (SQLException e) {
// if an exception happens, log it, and reply to the message
log.error(A_UNIQUE_ERROR_CODE, e);
m.reply(false);
}
}
}What irks me is that the catch block has become very redundant code, copied throughout 95% of the ~50 existing listeners. Can we come up with something better?
A good solution should:
- be easy to use/understand for an amateur programmer
- keep the programmer aware of the existence/potential of exceptions
- minimize the chance of a programmer accidentally "swallowing" an exception
- reduce the amount of "boilerplate" code
There is a subtle requirement needed for the solution. The
UNIQUE_ERROR_CODE should be unique across all declarations of the listeners. That way, I could gain statistics based upon where the error was caught across all listeners.If the
UNIQUE_ERROR_CODE is buried underneath an abstract class, or is used outside onMessage(..), I will lose the needed "uniqueness."Solution
Allow throwing exceptions
Do you really think your user is capable of handling all the exceptions?
Of course if some plugin wants to handle the exception, nothing prevents he/she of using
Give your user a simplified adapter
Do you really think your user is capable of handling all the exceptions?
interface IMessageListener {
void onMessage(Message m) throws Exception;
}Of course if some plugin wants to handle the exception, nothing prevents he/she of using
try/catch. But no one is forced to do so and if, according to your knowledge, the catch block is almost always the same, put it outside in the code calling onMessage().Give your user a simplified adapter
abstract class ThrowingMessageListenerAdapter implements IMessageListener {
@Override
public void onMessage(Message m) {
try {
doOnMessage(m);
} catch (SQLException e) {
// if an exception happens, log it, and reply to the message
log.error(A_UNIQUE_ERROR_CODE, e);
m.reply(false);
}
}
protected abstract void doOnMessage(Message m) throws Exception;
}Code Snippets
interface IMessageListener {
void onMessage(Message m) throws Exception;
}abstract class ThrowingMessageListenerAdapter implements IMessageListener {
@Override
public void onMessage(Message m) {
try {
doOnMessage(m);
} catch (SQLException e) {
// if an exception happens, log it, and reply to the message
log.error(A_UNIQUE_ERROR_CODE, e);
m.reply(false);
}
}
protected abstract void doOnMessage(Message m) throws Exception;
}Context
StackExchange Code Review Q#14217, answer score: 9
Revisions (0)
No revisions yet.