Nasze zespoły prowadzą następującą dyskusję:
Powiedzmy, że mamy dwie następujące metody:
public Response Withdraw(int clubId, int terminalId,int cardId, string invoice, decimal amount);
public Response Withdraw(Club club, Terminal terminal,Card card, string invoice, decimal amount);
to, co jest przesyłane przez sieć, to tylko identyfikatory.
jedna strona mówi, że pierwsza metoda jest poprawna, ponieważ mamy tylko identyfikatory terminala i klubu i powinno być jasne, że nie mamy nic innego, takie jest moje podejście.
druga strona twierdzi, że druga metoda jest poprawna, ponieważ jest bardziej elastyczna.
Znamy ideę parametru obiektu, druga strona uważa również, że parametr obiektu powinien mieć obiekty jako właściwości.
Jakie jest właściwe podejście?
Może istnieje trzecie, jeszcze lepsze podejście?
Odpowiedzi:
Odpowiedź zależy od kontekstu.
Jeśli klient ma mieć wszystkie te obiekty już dostępne , użyłbym parametrów obiektu. W przeciwnym razie ich kod będzie wyglądał na bardziej skomplikowany niż powinien. (Np. Będą mieli
club.getId()
np. Połączenia ).Jeśli klient będzie miał łatwy dostęp do identyfikatorów , być może drugie podejście jest lepsze, ponieważ nie chcesz, aby klient musiał składać / ładować wszystkie te obiekty, jeśli naprawdę potrzebujesz tylko identyfikatorów.
Opcją jest podanie obu metod , aby klient mógł wybrać, która z nich ma zostać użyta (pod warunkiem, że nie zaśmieca to interfejsu API)
Zasadniczo parametry obiektu są bardziej rozszerzalne, ponieważ jeśli w przyszłości potrzebujesz innej części danych do wykonania pracy, nie musisz wprowadzać innej metody, która pobiera te dodatkowe informacje.
Wreszcie, sygnatury metod nie powinny być podyktowane specyfiką tego, co robi metoda (w twoim przypadku, co dokładnie przechodzi przez drut). Interfejs API powinien abstrakcyjnie mieć sens, więc jeśli zmiany w implementacji nie zostaną wkręcone.
źródło
Pierwsze podejście wskazuje na pierwotną obsesję . Ponieważ przekazujesz liczby int i ciągi znaków, programiście bardzo łatwo popełni błąd (np. Przekazując wartość clubId do parametru terminalId). Spowoduje to trudne do znalezienia błędy.
W drugim przykładzie nie można przejść do klubu, gdy oczekuje się terminala - dałoby to błąd czasu kompilacji.
Mimo to nadal bym na to patrzył
string invoice
. Czy faktura jest naprawdę ciągiem? Coamount
znaczy Jest to bardziej prawdopodobna wartość pieniężna.Wspomniałeś w swoim pytaniu, że „przesyłane przez sieć to tylko identyfikatory”. Jest to poprawne, ale nie pozwól, aby to wymaganie zamazało Twoją domenę.
Najlepszym wytłumaczeniem, jakie widziałem na korzyść tego podejścia, była reguła 3 obiektu Calisthenics :
źródło
Nie ma właściwej odpowiedzi na to pytanie. Każda z opcji może być odpowiednia do pracy. Cóż, prawie w każdym razie, argument faktury podniósł bruzdę na moim czole, nie mam pojęcia, co to jest po przeczytaniu kodu.
Jeśli wyślesz identyfikator, oba systemy muszą być ściśle powiązane z tym, co reprezentuje. ClubID jest kluczem w tabeli klubów. Co więcej, zarówno osoba wywołująca, jak i osoba odbierająca muszą uzgodnić, jak nazywa się tabela Clubs i w której bazie danych się znajduje. Jeśli nie chcesz lub nie możesz narzucić tego ograniczenia, możesz przekazać obiekt przy użyciu wspólnego opisu, natywny, serializowany, xml, name = wartość cokolwiek, plik ini :)
To, jak zidentyfikowałeś, będzie cię kosztować „za drut”. Uniknięcie tego, wysyłając identyfikator kosztuje cię gdzie indziej. Więc który z nich najbardziej Cię boli, teraz (lub może być później ...) jest wskaźnikiem dobra kontra zła.
źródło