Metody zwracające obiekt który usunęły

0

Hej, czasami zdarza mi się spotkać kod który usuwa obiekt np z bazy danych(wiadomo zmiana flagi) i jednocześnie zwraca ten obiekt lub jego ID.

public Model removeModelById(ModelId id);

Zawsze zastanawiam się skąd bierze się taki pomysł.
Osobiście preferuje zwracanie optionala z błędem w sytuacji kiedy coś poszło nie tak (Nie można usunąć/ Model nie istnieje).

public Optional<ModelServiceError> removeModelById(ModelId id);

Dlaczego metoda remove(Id id) miała by zwracać obiekt który usunęła i który już nie istnieje.

W jakich przypadkach lub jaki jest sens zwracanie usuniętego obiektu lub jego id?

1

Jeśli ten Model byłby w oparciu o jakiś Optional<> ...

Generalnie spójrz szerzej, jest napięcie pomiedzy ujęciem obiektowym a relacyjnym, to jest teoretycznie analizowane itd, ze względów zasadniczych tego nie da się idealnie skonstruować.
To, co podnosisz, jest jakby jeszcze innym aspektem, mniej analizowany a BARDZO ciekawym

(Tak, o dobrym/złym kasowaniu w złożonym systemie można mówić sto lat)

0

@ZrobieDobrze: taaak taaak też o tym czytałem xd.

1

ja bym wolał booleana zwracać

2
krancki napisał(a):

Dlaczego metoda remove(Id id) miała by zwracać obiekt który usunęła i który już nie istnieje.

może ktoś się niepotrzebnie wzoruje na metodach ze standardowych kolekcji, np: https://docs.oracle.com/javase/8/docs/api/java/util/List.html#remove-int- ?

1

Po co remove miałoby zwracać cokolwiek? To chyba użytkownik powinien najpierw się upewnić czy coś istnieje i dopiero usuwać. Przy dzieleniu też miałbym zwracać optionala za każdym razem bo ktoś może podać 0? Sprawdzanie i usuwanie to dwie różne czynności. Jak już iść w tym kierunku to chociaż nazwać metodę removeIfExists która usuwa coś jeśli istnieje i nie robi nic w przypadku przeciwnym.

Jak mam metodę do usuwania to raczej chce wiedzieć że po jej wykonaniu nie będzie rekordu w bazie, a nie obsługiwać sytuację kiedy go nie ma.
Jak chce wiedzieć czy coś istnieje w bazie to wywołałbym metodę exists i obsłużył sytuację gdy czegoś nie ma w bazie.

2

To be clear. Jeżeli ktoś usuwa obiekt który już nie istnieje i dostaje ten obiekt - to jest błąd.

Jeżeli remove usuwa obiekt i go zwraca to nie ma tu separacji mutacja/odczyt, ale wykonujesz jedno zapytanie a nie 2. Argument optymalizacyjny, pytanie ile requestow na sekundę oszczędzisz. Jeżeli milion to może warto.

Ważne żeby zrobić CDD i umówić sie miedzy dwoma stronami jak pracujemy.

1
DKN napisał(a):

To be clear. Jeżeli ktoś usuwa obiekt który już nie istnieje i dostaje ten obiekt - to jest błąd.

Jeżeli remove usuwa obiekt i go zwraca to nie ma tu separacji mutacja/odczyt, ale wykonujesz jedno zapytanie a nie 2. Argument optymalizacyjny, pytanie ile requestow na sekundę oszczędzisz. Jeżeli milion to może warto.

Ważne żeby zrobić CDD i umówić sie miedzy dwoma stronami jak pracujemy.

Czekaj czekaj. Usuwasz obiekt i zwracasz co? Obiekt sprzed usunięcia? Po co takie coś zwracać w ogóle skoro wcześniej już go masz? Referencje, id? Przecież to wszystko masz przed usunięciem. Nie rozuiem po co ktoś miałby usuwać coś z bazy i próbować to od razu odczytywać więc o jaką optymalizacje chodzi :D

JEŚLI usunięcie polega na zmianie statusu to chyba jak rozumiem jest to update obiektu a nie usunięcie? Wtedy jak mniemam metoda nie powinna nazywać się remove przynajmniej nie na poziomie jakiegoś repo gdzie leci sql tylko update.

1

Chyba się nie spotkałem z takim rozwiązaniem, na myśl przychodzą mi 2 kejsy:

  1. Zamiast fizycznego usunięcia obiektu przestawiamy mu jakiś status/flagę i taki zmieniony obiekt zwracamy. Może ktoś potem gdzieś potrzebuje tego statusu 🤷🏻‍♂️
  2. Zwracanie metadanych o usunięciu, np. ile rekordów usunęło query.
2

Optimistic delete - usuwasz, sprawdzasz czy to jest to co chciałeś usunąć i jak nie to dodajesz z powrotem 😎

1

Jestem w stanie sobie wyobrazić system, który zwraca usuwaną encję - np. po to, żeby informację o encji wrzucić na jakąś kolejkę z eventami. Natomiast w większości systemów, które pisałem jakaś informacja zwrotna wystarczy.

4

Dlaczego metoda remove(Id id) miała by zwracać obiekt który usunęła i który już nie istnieje.

To zdanie nie ma sensu. Skoro masz referencję do obiektu to on jak najbardziej istnieje.
Być może jego zapis w bazie danych został usunięty. Ale obiekt istnieje mimo to.

0

"To zdanie nie ma sensu. Skoro masz referencję do obiektu to on jak najbardziej istnieje.
Być może jego zapis w bazie danych został usunięty. Ale obiekt istnieje mimo to."

Ogólnie to nie chodzi mi o typowo techniczny aspekty istnienia obiektu tylko o sens modelowania takiej metody.
Jeżeli usuwamy obiekt z Bazy-danych/Listy/Pliku to jaka jest sensowna przesłanka aby metoda zwracała usunięty obiekt(Wiem wiem obiekt istnieje bo mamy referencje ŁAŁ). Mając model biznesowy w której mamy warstwę z metodą usuwającą produkt nie widzę sensu zwracania referencji usuniętego obiektu. Dlatego pytam czy jest jakaś sensowna przesłanka aby zwracać taki obiekt. Osobiście uważam że to jest głupie modelowanie i zawsze staram się to zamieniać na Optionala<JakiśError>. Jeżeli się udało usunąć no to empty, a jak jakiś błąd wystąpi to go zwracamy.

"W jakich przypadkach lub jaki jest sens zwracanie usuniętego obiektu lub jego id?" - Nie zadawał bym takiego pytania jeżeli spotkał bym się tylko raz z taką metodą. Przeglądając kod w różnych projektach, kilkanaście razy zauważyłem taką metodę która usuwa coś jednocześnie zwracając referencje do usuniętego obiektu i tu się pojawia pytanie. Po co?

0

Ja zwykle zwracam boolean, enuma, obiekt/null pointer lub wyjątek.

Można czasem tworzyć odzielną klasę do danej odpowiedzalności lub zwrócić dany obiekt lub w razie niepowodzenia jego brak.
null pointer wtedy oznacza, że nic nie zostało usunięte, funkcja zawiodła lub element nie istniał, metadane nie są zbyt jasne, w drugim przypadku wiadomo że obiekt taki i taki został usunięty lub zostały jakieś operacje na nim podjęte.

Mi się w sumie żadne podejście nie podoba, bo albo trzeba specjalnie headery do danych struktur importować, albo łapać wyjątki.
Jakiś kompromis musi być, w języku C błędy są liczbami poniżej zera, zwykle jako enum.
W wyższych językach błędy jako wyjątki są najczęściej, ale te atomowe, na które musi zwracać uwagę programista, te na które musi zwracać uwagę użytkownik już powinny być normalne i logicznie obsłużone.

0
krancki napisał(a):

"To zdanie nie ma sensu. Skoro masz referencję do obiektu to on jak najbardziej istnieje.
Być może jego zapis w bazie danych został usunięty. Ale obiekt istnieje mimo to."

Ogólnie to nie chodzi mi o typowo techniczny aspekty istnienia obiektu tylko o sens modelowania takiej metody. ... i tu się pojawia pytanie. Po co?

Powiem jako advocatus diaboli:

  1. w jakimś korpo-projekcie rozpropagować skutki tego co się stało. Załóżmy, że nie są to skutki banalne, do załatwienia w repo "jedną adnotacją". Akademicki przykład: przeliczyć po nowemu odsetki / różnice kursowe /whatever (nie brutalnie je skasować)

  2. środowiska jak JPA flushują ostateczną zmianę do bazy np nieco później, w momencie finalziacji transakcji. Nie mówię, że to zdrowe, ale kolejny argument za jakimiś operacjami "ubrać zwłoki do trumny"

0 użytkowników online, w tym zalogowanych: 0, gości: 0