Wszyscy lubimy polimorfizm, definiujemy sobie interfejs, i dostarczamy tylko implementacje. Jeśli implementacje są w zgodzie z interfejsem (zwracają te same typy danych, rzucają te same wyjątki, przyjmują te same argumenty, rządzą się podobnymi prawami) to wszystko jest okej.
Sam osobiście bardzo nie lubie kiedy jakaś implementacja deklaruje jakiś interfejs, a potem nie jest w nim w zgodzie - nie da się tego normalnie używać.
Stąd pytanie.
Oczywistym złem jest, że interfejs deklaruje wyjątki A
, B
i C
jako możliwe do rzucenia, a implementacja rzuca wyjątek X
. To zło. Ale czy jest okej, że różne implementacje rzucają te same wyjątki z różnymi message'ami?
Przykład
interface FileEncrypter {
/**
* @throws FileNotFoundExceptions;
* @throws FileReadOnlyException;
* @throws AccessDeniedException;
*/
public void encryptFile(String filename, String key);
}
class RsaEncrypter implements FileEncrypter {
public void encryptFile(String filename, String key) {
if (fileInacessible(filename)) {
throw new FileReadOnlyException("Failed to encrypt file using safe RSA method - file is not writtable");
}
}
}
class Rot13Encrypter implements FileEncrypter {
public void encryptFile(String filename, String key) {
if (fileInacessible(filename)) {
throw new FileReadOnlyException("Failed to encrypt file using unsafe Rot13 method - the file is not writtable");
}
}
}
Zagwostka
Noi teraz tak, teoretycznie - message wyjątku jest dostępny dla tego kogo złapie, więc możnaby napisać kod zależny od niego, ergo zmiana message'a technicznie jest breaking change.
Ale przecież nikt normalny nie robi logiki na podstawie message'u wyjątka, więc zmiana jego nie powinna powodować problemów.
Jak myślicie?