I'm implementing a type of Repository
for a framework/library that has (roughly) the following:
public interface FooRepository {
boolean contains(String id);
Foo fetch(String id);
void commit(Foo foo):
}
We can implement it several different ways, depending on what storage medium we're using; for example
public class FileFooRepositiory implements FooRepository {
public boolean contains(String id) {
return fileExistsInFileSystem(id);
}
public Foo fetch(final String id) {
return parseFooFromFile(id);
}
public void commit(final Foo foo) {
writeFooToFile(foo);
}
}
But we can also have
public class SQLFooRepositiory implements FooRepository {
public SQLFooRepository(Connection connection) {
// ...
}
public boolean contains(String id) {
return fooExistsInDatabase(id);
}
public Foo fetch(final String id) {
return parseFooFromDatabase(id);
}
public void commit(final Foo foo) {
writeFooToDatabase(foo);
}
}
There can also be implementations that store Foo
objects in a Map<String, Foo>
or ones that use external storage systems (appfabric, redis, etc).
However, there are things that can prevent each of these implementation from doing what they are supposed to do. They would each throw a different type of Exception
. For SQLException
, most things that could happen would use this one exception. For the file-based, it would be some sort of IOException
, more specifically, FileNotFoundException
, AccessDeniedException
, etc.
My question is this: How can I change the contract of the FooRepository
interface to allow these types of Exception
s being thrown, without using the throws Exception
clause. My initial thought was to have a RepositoryException
that would extend RuntimeException
and wrap the actual exceptions
try {
// ...
}
catch (SQLException sqle) {
throw new RepositoryException(sqle);
}
but I'm not sure if this is the proper strategy I should be using.