W tym filmie Richa Hickeya , twórcy Clojure, zaleca się używanie mapy do reprezentowania danych zamiast używania klasy do ich reprezentowania, jak ma to miejsce w Javie. Nie rozumiem, jak może być lepiej, skoro użytkownik interfejsu API może wiedzieć, jakie są klucze wejściowe, jeśli są po prostu reprezentowane jako mapy.
Przykład :
PersonAPI {
Person addPerson(Person obj);
Map<String, Object> addPerson(Map<String, Object> personMap);
}
W drugiej funkcji, w jaki sposób użytkownik API może wiedzieć, jakie są dane wejściowe do stworzenia osoby?
Odpowiedzi:
Exagg'itive Podsumowanie (TM)
Dostajesz kilka rzeczy.
Jest jedna poważna wada.
Chodzi o to, że można uzyskać introspekcję, używając, um, introspekcji. Tak zwykle się dzieje:
Innymi słowy, jeśli nigdy nie potrzebujesz interfejsu z FP, nie musisz brać rady Richa Hickeya.
Na koniec, ale nie najmniej (ani najładniejszy), chociaż użycie
String
jako klucza właściwości ma najprostszy sens, nie musisz używaćString
s. Wiele starszych systemów, w tym Android ™, intensywnie wykorzystuje identyfikatory liczb całkowitych w całej strukturze w odniesieniu do klas, właściwości, zasobów itp.Android jest znakiem towarowym firmy Google Inc.
Możesz także uszczęśliwić oba światy.
W świecie Java zaimplementuj metody pobierające i ustawiające jak zwykle.
Dla świata FP zaimplementuj
Object getPropertyByName(String name)
void setPropertyByName(String name, Object value) throws IllegalPropertyChangeException
List<String> getPropertyNames()
Class<?> getPropertyValueClass(String name)
Wewnątrz tych funkcji, tak, brzydki kod, ale istnieją wtyczki IDE, które wypełnią to za Ciebie, używając ... uh, inteligentnej wtyczki, która odczytuje twój kod.
Strona Java będzie tak samo wydajna jak zwykle. Nigdy nie użyją tej brzydkiej części kodu. Możesz nawet chcieć ukryć to przed Javadoc.
Strona FP na świecie może napisać dowolny kod „leet”, jaki chce, i zazwyczaj nie krzyczy na ciebie, że kod jest powolny.
Ogólnie rzecz biorąc, używanie mapy (torby właściwości) zamiast obiektu jest powszechne w programowaniu. Nie jest on unikalny dla programowania funkcjonalnego ani żadnego konkretnego rodzaju języków. To może nie być podejście idiomatyczne dla danego języka, ale są sytuacje, które tego wymagają.
W szczególności serializacja / deserializacja często wymaga podobnej techniki.
Kilka ogólnych przemyśleń na temat „mapy jako obiektu”.
źródło
commonplace
wydaje mi się trochę silny. Mam na myśli, że jest używany tak, jak to opisujesz, ale jest także jedną z tych notorycznie niestabilnych / kruchych rzeczy (takich jak tablice bajtów lub odsłonięte wskaźniki), które biblioteki starają się jak najdalej ukryć.To doskonała rozmowa kogoś, kto naprawdę wie, o czym mówi. Polecam czytelnikom obejrzenie całości. To tylko 36 minut.
Jednym z jego głównych punktów jest to, że prostota otwiera możliwości późniejszych zmian. Wybór klasy, która ma reprezentować,
Person
zapewnia natychmiastową korzyść z utworzenia statystycznie weryfikowalnego interfejsu API, jak wskazano, ale wiąże się to z kosztem ograniczenia możliwości lub zwiększenia kosztów zmian i ponownego wykorzystania w późniejszym terminie.Chodzi mu o to, że korzystanie z klasy może być rozsądnym wyborem, ale powinien być świadomym wyborem z pełną świadomością jego kosztów, a programiści zwykle bardzo słabo zauważają te koszty, nie mówiąc już o ich uwzględnieniu. Ten wybór powinien zostać ponownie oceniony w miarę wzrostu wymagań.
Oto niektóre zmiany kodu (z których jedna lub dwie zostały wspomniane w dyskusji), które są potencjalnie łatwiejsze przy użyciu listy map niż przy użyciu listy
Person
obiektów:Map
prymitywów w formacie, który można przesłać, nadaje się do wielokrotnego użytku i może nawet być udostępniana w bibliotece.Person
Obiekt prawdopodobnie potrzebuje niestandardowego kodu do wykonania tego samego zadania).Cały czas rozwiązujemy tego rodzaju problemy, dysponujemy wzorcami i narzędziami, ale rzadko zastanawiamy się, czy wybór prostszej, bardziej elastycznej reprezentacji danych na początku ułatwiłby nam pracę.
źródło
Choosing a class to represent a Person provides the immediate benefit of creating a statically-verifiable API... but that comes with the cost of limiting opportunities or increasing costs for change and reuse later on.
Źle i niezwykle nieuczciwie. To zwiększa swoją szansę na zmianę w przyszłości, ponieważ po dokonaniu zmiany na rozerwanie, kompilator automatycznie znaleźć i wskazać dla Ciebie każde miejsce, które musi zostać zaktualizowana, aby przynieść cały codebase do prędkości. Jest w kodzie dynamicznym, gdzie nie możesz tego zrobić, że naprawdę łączysz się z poprzednimi wyborami!Jeśli dane zachowują się słabo lub nie zachowują się przy elastycznych treściach, które mogą ulec zmianie, skorzystaj z mapy. IMO, typowy „javabean” lub „obiekt danych”, który składa się z modelu domeny anemicznej z N polami, N ustawiającymi i N pobierającymi, jest stratą czasu. Nie próbuj zaimponować innym swoją chwalebną strukturą, zawijając ją w fantazyjną klasę smancy. Bądź szczery, wyraź swoje intencje i użyj mapy. (Lub, jeśli ma to jakiś sens dla Twojej domeny, obiektu JSON lub XML)
Jeśli dane mają znaczące rzeczywiste zachowanie, czyli metody ( Tell, Don't Ask ), użyj klasy. I poklep się po plecach za używanie prawdziwego programowania obiektowego :-).
Jeśli dane mają wiele zasadniczych zachowań związanych z weryfikacją i wymagane pola, użyj klasy.
Jeśli dane mają umiarkowaną liczbę operacji sprawdzania poprawności, jest to granica.
Jeśli dane wyzwalają zmiany właściwości nieruchomości, jest to w rzeczywistości łatwiejsze i znacznie mniej uciążliwe dzięki Mapie. Po prostu napisz małą podklasę.
Jedną z głównych wad korzystania z mapy jest to, że użytkownik musi rzucić wartości na ciągi, ints, foos itp. Jeśli jest to bardzo denerwujące i podatne na błędy, rozważ klasę. Lub rozważ klasę pomocnika, która otacza mapę odpowiednimi pobierającymi.
źródło
Interfejs API dla
map
ma dwa poziomy.Interfejs API można opisać na mapie zgodnie z konwencją. Na przykład para
:api api-validate
może być umieszczona na mapie lub:api-foo validate-foo
może być konwencją. Mapa może nawet przechowywaćapi api-documentation-link
.Korzystanie z konwencji pozwala programiście stworzyć język specyficzny dla domeny, który standaryzuje dostęp do „typów” zaimplementowanych jako mapy. Użycie
(keys map)
pozwala na określenie właściwości w czasie wykonywania.Nie ma nic magicznego w mapach i nie ma nic magicznego w obiektach. To wszystko jest wysyłka.
źródło