Mam kilka metod, które wykonują pewne zmiany danych w bazie danych (wstawianie, aktualizowanie i usuwanie). ORM używam powrót wiersz dotknięte wartości int dla tych rodzaju metody. Co powinienem zwrócić po „mojej metodzie”, aby wskazać stan powodzenia / niepowodzenia operacji?
Rozważ kod, który zwraca int
:
A.1
public int myLowerLevelMethod(int id) {
...
int affectedRows = myOrm.deleteById(id)
...
return affectedRows;
}
Następnie użycie:
A.2
public void myOtherMethod() {
...
int affectedRows = myLowerLevelMethod(id)
if(affectedRows > 0) {
// Success
} else {
// Fail
}
}
Porównaj z użyciem boolean:
B.1
public boolean myLowerLevelMethod(int id) {
...
int affectedRows = myOrm.deleteById(id)
...
return affectedRows > 0;
}
Następnie użycie:
B.2
public void myOtherMethod() {
...
boolean isSuccess = myLowerLevelMethod(id)
if(isSuccess) {
// Success
} else {
// Fail
}
}
Który (A lub B) jest lepszy? A może zalety / wady każdego z nich?
design
error-handling
methods
Hoang Tran
źródło
źródło
Odpowiedzi:
Inną opcją jest zwrócenie obiektu wynikowego zamiast podstawowych typów. Na przykład:
Dzięki temu, jeśli z jakiegoś powodu musisz zwrócić liczbę dotkniętych wierszy, możesz po prostu dodać metodę w OperationResult:
Ten projekt pozwala Twojemu systemowi rozwijać się i zawierać nowe funkcje (znajomość dotkniętych wierszy) bez modyfikowania istniejącego kodu.
źródło
Zwrócenie liczby dotkniętych wierszy jest lepsze, ponieważ daje dodatkowe informacje o przebiegu operacji.
Żaden programista nie będzie cię winił, ponieważ musi napisać to, aby sprawdzić, czy dostały jakieś zmiany podczas operacji:
ale będą cię winić, gdy będą musieli poznać liczbę dotkniętych rzędów i zdają sobie sprawę, że nie ma metody na uzyskanie tej liczby.
BTW: jeśli przez „niepowodzenie” rozumiesz błąd kwerendy składniowej (w którym to przypadku liczba dotkniętych wierszy wynosi oczywiście 0), wówczas rzucenie wyjątku byłoby bardziej odpowiednie.
źródło
update t set category = 'default' where category IS NULL
nawet 0 wierszy, których dotyczy zmiana, byłby sukcesem, ponieważ teraz nie ma elementu bez kategorii, nawet jeśli nie wpłynęło to na żadne wiersze!Nie poleciłbym żadnego z nich. Zamiast tego nie zwracaj nic (void) po sukcesie i rzucaj wyjątek w przypadku niepowodzenia.
Jest to dokładnie z tego samego powodu, dla którego zdecydowałem się ogłosić niektórych członków klasy prywatnymi. Ułatwia także korzystanie z funkcji. Bardziej operacyjny kontekst nie zawsze oznacza lepszy, ale z pewnością oznacza bardziej złożony. Im mniej obiecujesz, tym bardziej abstrahujesz, tym łatwiej jest klientowi zrozumieć i masz więcej swobody w wyborze sposobu jego realizacji.
Pytanie brzmi, jak wskazać sukces / błąd. W takim przypadku wystarczy zasygnalizować awarię, zgłaszając wyjątek i niczego nie zwracając po sukcesie. Dlaczego muszę podać więcej niż potrzebuje użytkownik?
Awarie / wyjątkowe sytuacje mogą się zdarzyć i wtedy będziesz musiał sobie z nimi poradzić. Niezależnie od tego, czy używasz metody try / catch, czy sprawdzasz kody zwrotne, jest to kwestia stylu / osobistych preferencji. Ideami try / catch są: oddzielenie normalnego przepływu od wyjątkowego przepływu i pozwolenie, by wyjątki pojawiały się aż do warstwy, w której można sobie z nimi poradzić w najbardziej odpowiedni sposób. Tak więc, jak już wielu zauważyło, zależy to od tego, czy porażka jest naprawdę wyjątkowa, czy nie.
źródło
„Czy to jest lepsze niż to?” nie jest użytecznym pytaniem, gdy dwie alternatywy nie robią tego samego.
Jeśli potrzebujesz znać liczbę wierszy, których dotyczy problem, musisz użyć wersji A. Jeśli nie musisz, możesz użyć wersji B - ale wszelkie korzyści, które możesz uzyskać w postaci mniejszego wysiłku pisania kodu, już minęły zadałeś sobie trud, aby opublikować obie wersje na forum online!
Chodzi mi o to, które rozwiązanie jest lepsze, zależy całkowicie od twoich wymagań dotyczących tej aplikacji i znasz te okoliczności znacznie lepiej niż my. Nie ma ogólno branżowej, bezpiecznej w użyciu, najlepszej praktyki, nie wymagającej zwolnienia z pracy, która byłaby ogólnie lepsza ; musisz o tym pomyśleć. A dla decyzji tak łatwej do zrewidowania jak ta, nie musisz też spędzać tyle czasu na myśleniu.
źródło
Dwie najważniejsze zasady projektowania oprogramowania, które można utrzymać, to KISS i YAGNI .
Jest to prawie nigdy nie jest dobry pomysł, aby umieścić w logice nie od razu trzeba teraz . Pośród wielu innych osób Jeff Atwood (współzałożyciel StackExchange) napisał o tym , i z mojego doświadczenia on i inni zwolennicy tych koncepcji mają całkowitą rację.
Każda złożoność, którą dodasz do programu, wiąże się z kosztami, płaconymi przez długi okres. Program staje się trudniejszy do odczytania, bardziej skomplikowany do zmiany i łatwiejsze do wkradania się błędów. Nie wpadnij w pułapkę dodawania rzeczy „na wszelki wypadek”. To fałszywe poczucie bezpieczeństwa.
Rzadko kiedy pierwszy raz dostaniesz odpowiedni kod. Zmiany są nieuniknione; dodanie logiki spekulatywnej, aby obronnie przygotować się na nieznane przyszłe nieprzewidziane zdarzenia , tak naprawdę nie ochroni Cię przed koniecznością zmiany kodu w przyszłości, gdy okaże się, że przyszłość jest inna niż się spodziewałeś. Utrzymanie niepotrzebnej / warunkowej logiki jest bardziej problemem związanym z utrzymaniem niż późniejszym refaktoryzowaniem w celu dodania brakującej funkcjonalności.
Zatem, ponieważ wydaje się, że wszystko, czego na razie potrzebuje Twój program, to wiedzieć, czy operacja się powiodła, czy nie, zaproponowane rozwiązanie B (zwrócenie pojedynczej wartości logicznej) jest poprawnym podejściem. Zawsze możesz go refaktoryzować później, jeśli zmieni się wymaganie. To rozwiązanie jest najprostsze i ma najniższą złożoność (KISS) i robi dokładnie to, czego potrzebujesz i nic więcej (YAGNI).
źródło
Całe wiersze lub status błędu
Rozważ zwrócenie całych wierszy, przynajmniej jako opcję wykonania. We wstawkach DB może być konieczne sprawdzenie danych, które zostały wstawione - ponieważ często będą się różnić od tych, które wysłałeś do DB; typowe przykłady obejmują automatycznie generowane identyfikatory wierszy (których aplikacja prawdopodobnie będzie natychmiast potrzebować), wartości domyślne określone przez DB oraz wyniki wyzwalaczy, jeśli ich użyjesz.
Z drugiej strony, jeśli nie trzeba zwróconych danych, to również nie potrzebują skażoną liczba wierszy, ponieważ nie jest pomocne w wyniku 0. Jeśli są błędy, to trzeba wrócić jaką stanowi wystąpił błąd, w sposób zgodny z zasadami obsługi błędów projektu (wyjątki, numeryczne kody błędów, cokolwiek); ale istnieją prawidłowe zapytania, które poprawnie wpłyną na 0 wierszy (tj. „usuń wszystkie wygasłe zamówienia”, jeśli w rzeczywistości ich nie ma).
źródło