Czy istnieją obiektywne argumenty przemawiające za lub przeciw używaniu obiektów vs unikalny identyfikator jako parametry metody / funkcji? (i członkowie innych przedmiotów?). Specjalnie w kontekście języków o typie statycznym (C # / Java / Scala)
Plusy samego obiektu:
- Więcej bezpiecznych połączeń. W przypadku identyfikatorów istnieje ryzyko niewłaściwego uporządkowania argumentów. Można to jednak złagodzić, utrzymując klasę „mini” dla każdej klasy, która przechowuje tylko identyfikator tej klasy.
- Zdobądź raz z wytrwałości, nie musisz więcej
- Z identyfikatorem, jeśli typ identyfikatora zmienia się, powiedzmy int -> long, wówczas wymagałoby to zmiany z możliwością wystąpienia błędów .. (courtsey: https://softwareengineering.stackexchange.com/a/284734/145808 )
Plusy używania identyfikatora:
- Przez większość czasu nie potrzeba rzeczywistego obiektu, wystarczyłoby tylko uniqueid, więc posiadanie identyfikatora oszczędza czas od uzyskania go z trwałości.
Mieszanka tych technik, o ile widzę, miałaby tylko wady obu i zalety obu.
Biorąc pod uwagę, że jest to konkretnie określony problem, mam nadzieję, że istnieją obiektywne odpowiedzi, a nie typy „myślę” lub „lubię”… :-).
EDYCJA: Kontekst sugestii komentatora - Jedynym ograniczeniem są języki o typie statycznym. Ta aplikacja jest aplikacją ogólnego przeznaczenia, chociaż chętnie otrzymuje odpowiedzi na podstawie konkretnych scenariuszy użytkowania.
EDYCJA: Więcej kontekstu. Powiedz, że mam system zarządzania książkami. Mój model to:
Book: { id: Int, isbn: String, donatedBy: Member, borrowedBy: Member }
Member: {id: Int, name: String}
Table- wishlist: { isbn: String, memberId: Int}
Table- borrows: { id: Int, memberId: Int}
Method:
isInWishList( book: Book, member: Member ) vs isInWishList( bookId: Int, memberId: Int)
handleBorrowRequest( memberId: Int, book: Book ){
//the login system doesn't actually get the entire member structure, only the member id. I don't need the full member yet. can run a query to verify that the memberId has less than max allowed books for borrowing.
}
Dlaczego miałbym chcieć zachować tylko identyfikator, a nie pełnego członka? Powiedz, kiedy otrzymuję informacje o książce, rzadko muszę wiedzieć, kto ją podarował lub pożyczył. Uzyskanie pełnych informacji w celu wypełnienia pól darowanych i pożyczonych to przesada.
Oczywiście, to tylko moje punkty. Jestem pewien, że brakuje mi rzeczy, więc chciałem wiedzieć, jakie są punkty za / przeciw.
Odpowiedzi:
W zależności od środowiska i kontekstu problemu, potrzeba przejścia do bazy danych może zostać złagodzona, w wyniku czego (IMO) argument za używaniem tylko identyfikatora zostaje utracony.
Na przykład PHP Doctrine2 ORM,
EntityManager::getReference
który tworzy leniwie załadowane proxy do encji przy użyciu podanego identyfikatora; Nie wiem, ilu innych ORM to robi, ale w przybliżeniu pasuje to do pojęcia „mini-klasy”, o której wspominasz. Dla większości celów i celów jest to w pełni uwodniona istota, więc możesz ją przekazywać i używać jak jakikolwiek inny.Jedyny przypadek, w którym tak się nie dzieje, to podanie niepoprawnego identyfikatora, w którym to przypadku i tak chcesz przejść do bazy danych, aby sprawdzić; ponadto, aby obniżyć koszty uzyskania encji, większość ORM ma funkcję buforowania (pierwszego i drugiego poziomu) w jakiejś formie.
Gdy zmniejszymy potrzebę i koszt przejścia do bazy danych, w dużej mierze jesteśmy za tym, aby użyć encji jako parametru:
Oczywiście zdarzają się przypadki, w których można chcieć przekazać tylko identyfikator: na przykład podczas przekraczania ograniczonej granicy kontekstu (w projektowaniu sterowanym domeną). Jeśli weźmiemy pod uwagę dwa ograniczone konteksty z różnymi wyobrażeniami o tym, co składa się na konto (np. Finanse vs. relacje z klientami), nie możemy przekazać konta kontekstu A do kontekstu B. Zamiast tego identyfikator konta (w języku domeny) może być przekazywanym.
źródło
W przypadku tego rodzaju pytań deleguję do dowolnego rozwiązania, które najlepiej komunikuje moją intencję programisty i sprawia, że praca w „Future Greg” jest najłatwiejsza.
Używanie obiektu jako argumentu ułatwia prawidłowe wywołanie metody za 6 miesięcy i zapomniałem o drobnych szczegółach tej aplikacji. Opierając się na „jest to książka na przykładzie listy życzeń tej osoby”, powiedzmy, że
isInWishList
metoda naprawdę wymaga jedynie porównania liczb całkowitych książek i członków. W rzeczywistości ta jedna metoda wymaga tylko dwóch fragmentów danych, aby wykonać swoje zadanie. Cofnijmy się teraz od tej jednej metody i spójrzmy na cały system oprogramowania. Wątpię, aby do działania potrzebował tylko identyfikatora książki i identyfikatora członka. W każdym razie będziesz wyciągać pełną książkę i członka z bazy danych, zanim nawet zadzwonisz,isInWishList
ponieważ prawdopodobnie będziesz musiał zrobić coś więcej niż tylko wywołać tę jedną metodę. Może i tak, ale w większości przypadków musisz zrobić więcej.Biorąc to pod uwagę, realistycznie nie poniesiesz kary za wydajność, pobierając i mapując oba obiekty w całości z bazy danych. Teoretycznie będziesz potrzebować mniej wywołań bazy danych, ale w praktyce przekonasz się, że to po prostu nieprawda. Jeśli przekażesz te identyfikatory jako parametry w ciągu zapytania z powrotem na serwer, to tak, wystarczy pobrać listę życzeń z bazy danych. Jest to jednak bardzo wąski widok całej aplikacji. Będą scenariusze, gdy wykonujesz inne operacje oprócz sprawdzania listy życzeń --- na przykład dodając książkę do listy życzeń. Nie chcesz dodawać duplikatów.
Wybierz rozwiązanie, które jest najłatwiejsze dla nowego programisty lub Twojego Future Self do zrozumienia, a mianowicie przekazywanie obiektów
Book
iMember
. Dopiero po znalezieniu rzeczywistego problemu z wydajnością powinieneś naprawdę zająć się samym przekazywaniem ID.Możemy też pamiętać, że statycznie pisane języki, takie jak Java, oferują przeciążanie metod, więc możesz mieć swoje ciasto i je zjeść:
Prawdziwą odpowiedzią na to pytanie jest napisanie obu metod, wywołanie wersji z liczbą całkowitą z mocno wpisanej wersji, a Bob jest twoim wujem.
źródło