Hiya Christian, Peter, everyone,
I've seen mention of the following interface relationships:
Then the client uses it something like this:
This is fine as long as all possible databases only throw RemoteException and DatabaseException; but it causes problems when you create a different type of database. For an example, take a MonkeyDatabase that uses intelligent monkeys to remember and share data. Each method in MonkeyDatabase throws MonkeyException, which includes such categories as SleepingMonkeyException or DrunkenMonkeyException. If I want my clients to use this database class, I now have to alter the Database interface to have all of its methods throw DatabaseException, RemoteException, and MonkeyException. Worse yet, all of my client code now has to be rewritten to catch MonkeyException.
There are several alternatives that I can think of:
1)
You can have the Database superinterface throw Exception, to cover every type of database you will ever come across. Now all of your client code has to be rewritten to catch Exception. Yech! If you are catching Exception all over the place, you can forget recovering from recoverable Exceptions -- recovery code would have to be added to each client method call.
2)
You can have your clients only make use of one particular type of Database. For instance, Program A knows it's only going to use a RemoteDatabase so it only has to catch RemoteException and DatabaseException. If it wants to use MonkeyDatabase, it will specifically create a MonkeyDatabase and not make use of the Database interface. In this case, is there really any benefit to having a Database superinterface? A bit, in that you know its subclasses are going to implement certain methods. But you can't actually make use of it in your clients.
3)
(It's the last one so you know this is the one I like
) You can create a Database superinterface in which all the methods throw only DatabaseException. All of your clients will use this interface and only have to catch DatabaseException. You then create a MonkeyDatabaseClient that implements Database, delegates all calls to a MonkeyDatabase, and handles all MonkeyExceptions.
Something like this:
You get the idea. The Database interface stands on its own independent of any subclass, clients can enjoy a consistent unchanging interface, and there is a possibility of a consistent error recovery mechanism for each individual database implementation.
There must be a pattern for this -- facade or adapter or something -- help me out? Then the class would be called MonkeyDatabaseAdapter.
You can extrapolate this example to say, a SqlDatabase that throws SqlExceptions or something, but I can't imagine why you would ever need one of those.
- Nicole.
Disclaimer: No animals were harmed or forced to imbibe alcoholic beverages in the making of this post.
[ January 19, 2003: Message edited by: Nicole Gustavson ]
Fixing code and such
[ January 19, 2003: Message edited by: Nicole Gustavson ]