Często napotykam ten problem, szczególnie w Javie, nawet jeśli uważam, że jest to ogólny problem z OOP. To znaczy: zgłoszenie wyjątku ujawnia problem projektowy.
Załóżmy, że mam klasę, która ma String name
pole i String surname
pole.
Następnie używa tych pól do utworzenia pełnego imienia i nazwiska osoby w celu wyświetlenia go na jakimś dokumencie, np. Na fakturze.
public void String name;
public void String surname;
public String getCompleteName() {return name + " " + surname;}
public void displayCompleteNameOnInvoice() {
String completeName = getCompleteName();
//do something with it....
}
Teraz chcę wzmocnić zachowanie mojej klasy, zgłaszając błąd, jeśli displayCompleteNameOnInvoice
zostanie wywołany przed przypisaniem nazwy. To dobry pomysł, prawda?
Mogę dodać kod wywołujący wyjątki do getCompleteName
metody. Ale w ten sposób naruszam „niejawną” umowę z użytkownikiem klasy; ogólnie, pobierający nie powinni zgłaszać wyjątków, jeśli ich wartości nie są ustawione. Ok, to nie jest standardowy getter, ponieważ nie zwraca pojedynczego pola, ale z punktu widzenia użytkownika rozróżnienie może być zbyt subtelne, aby o tym myśleć.
Albo mogę rzucić wyjątek z wnętrza displayCompleteNameOnInvoice
. Ale żeby to zrobić, powinienem przetestować bezpośrednio name
lub surname
pola, a tym samym naruszyłbym abstrakcję reprezentowaną przez getCompleteName
. Ta metoda odpowiada za sprawdzenie i utworzenie pełnej nazwy. Może nawet zdecydować, opierając decyzję na innych danych, że w niektórych przypadkach wystarczy surname
.
Tak więc jedyną możliwością wydaje się zmienić semantyczną metodę getCompleteName
na composeCompleteName
, co sugeruje bardziej „aktywne” zachowanie, a wraz z nim zdolność do zgłaszania wyjątku.
Czy to lepsze rozwiązanie projektowe? Zawsze szukam najlepszej równowagi między prostotą a poprawnością. Czy istnieje odniesienie do projektu dla tego problemu?
displayCompleteNameOnInvoice
może po prostu rzucić wyjątek, jeśli getCompleteName
zwraca null
, prawda?