Sto implementando un tipo di Repository per un framework / libreria che ha (approssimativamente) il seguente:
public interface FooRepository {
boolean contains(String id);
Foo fetch(String id);
void commit(Foo foo):
}
Possiamo implementarlo in molti modi diversi, a seconda del supporto di archiviazione che stiamo usando; per esempio
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);
}
}
Ma possiamo anche avere
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);
}
}
Possono esserci anche implementazioni che memorizzano Foo oggetti in Map<String, Foo> o quelli che usano sistemi di archiviazione esterni (appfabric, redis, ecc.)
Tuttavia, ci sono cose che possono impedire a ciascuna di queste implementazioni di fare ciò che dovrebbero fare. Ognuno di loro lancia un diverso tipo di Exception . Per SQLException , la maggior parte delle cose che potrebbero accadere userebbe questa unica eccezione. Per i file, sarebbe una sorta di IOException , in particolare, FileNotFoundException , AccessDeniedException , ecc.
La mia domanda è questa: come posso modificare il contratto dell'interfaccia FooRepository per consentire il lancio di questi tipi di Exception s, senza utilizzare la clausola throws Exception . Il mio pensiero iniziale era di avere un RepositoryException che sarebbe extend RuntimeException e avvolgere le eccezioni reali
try {
// ...
}
catch (SQLException sqle) {
throw new RepositoryException(sqle);
}
ma non sono sicuro che questa sia la strategia corretta che dovrei usare.