Wyobraźmy sobie sytuację, w której korzystamy z biblioteki, która pozwala tworzyć Circle
obiekty, w których można określić promień i środek okręgu, aby je zdefiniować. Jednak z jakiegoś powodu wymaga również wymaganego flavour
parametru. Powiedzmy teraz, że naprawdę muszę korzystać Circle
z własnej aplikacji, ale na potrzeby mojej aplikacji mogę ustawić smak za Flavours.Cardboard
każdym razem.
Aby to „rozwiązać”, tworzę własną Circle
klasę w innej przestrzeni nazw, która przyjmuje tylko radius
i center
jako parametry, ale ma niejawny konwerter na Circle
klasę biblioteki zewnętrznej, która po prostu tworzy Circle(this.radius, this.center, Flavours.Cardboard)
obiekt. Wszędzie, gdzie potrzebuję innego rodzaju Circle
, pozwalam na automatyczną konwersję.
Jakie są konsekwencje stworzenia takiej klasy? Czy są jakieś lepsze rozwiązania? Czy miałoby to jakąkolwiek różnicę, gdyby moja aplikacja była interfejsem API zbudowanym na tej zewnętrznej bibliotece, przeznaczonym do użytku przez innych programistów?
źródło
MakeCircle
funkcji ?makePlayer
tym, że sama akceptuje tylko współrzędne, aby umieścić gracza, ale deleguje do znacznie bardziej złożonego konstruktora.Odpowiedzi:
Chociaż nie zawsze jest tak źle, zdarza się, że konwersje niejawne są najlepszą opcją.
Są problemy.
Ogólnie rzecz biorąc, istnieją lepsze rozwiązania.
Osobiście uważam, że # 2 jest najprostszy do wdrożenia i najmniej uciążliwy dla projektu. Inne mogą być w porządku, biorąc pod uwagę sytuację i co jeszcze próbujesz zrobić z tymi klasami.
Niejawna konwersja jest ostatecznością i wydaje mi się, że naprawdę warto, gdy mam funktory w stylu C ++, które próbuję wykonać - obiekty strategii, które domyślnie przekonwertowałem na typy delegowane.
źródło
Biorąc pod uwagę opisywany scenariusz, można o tym pomyśleć w kategoriach zastosowania funkcji częściowej.
Konstruktor jest funkcją (przynajmniej teoretycznie; w języku C # można utworzyć „funkcję fabryczną”, która wywołuje konstruktor):
w przypadku częściowego zastosowania wystarczą:
Możesz teraz uzyskać konstruktor, który wymaga tylko 2 parametrów:
Teraz masz funkcję fabryczną z żądanymi parametrami
BTW, jest to wyraźnie równoważne z opcją 2 powyżej, tylko z bardziej funkcjonalnej perspektywy.
źródło