Jest to połączenie trzech różnych czynników:
- Konkretny system typów jvm
- Potrzeba nieco innej semantyki dla różnych przypadków użycia podczas definiowania typów
- Fakt, że niektóre z nich zostały opracowane wcześniej, a inne później, w miarę rozwoju języka.
Więc najpierw zastanówmy się, co to robi. deftype i gen-class są podobne, ponieważ obie definiują nazwaną klasę do kompilacji z wyprzedzeniem. Klasa Gen zajęła pierwsze miejsce, a następnie deftype w clojure 1.2. Deftype jest preferowany i ma lepszą charakterystykę wydajności, ale jest bardziej restrykcyjny. Klasa deftype może być zgodna z interfejsem, ale nie może dziedziczyć z innej klasy.
Reify i proxy są używane do dynamicznego tworzenia instancji klasy anonimowej w czasie wykonywania. Proxy był pierwszy, reify pojawiło się wraz z deftype i defrecord w clojure 1.2. Preferowana jest reify, podobnie jak deftype, gdzie semantyka nie jest zbyt restrykcyjna.
Pozostaje pytanie, dlaczego zarówno deftype, jak i defrecord, skoro pojawiły się w tym samym czasie i mają podobną rolę. Do większości celów będziemy chcieli użyć defrecord: ma wszystkie różne dobro, które znamy i kochamy, sekwencjonowanie i tak dalej. Deftype jest przeznaczony do wykorzystania jako element składowy niskiego poziomu do wdrażania innych struktur danych. Nie zawiera zwykłych interfejsów clojure, ale ma opcję zmiennych pól (chociaż nie jest to ustawienie domyślne).
Aby przeczytać więcej, sprawdź:
Strona z typami danych clojure.org
Wątek grupy Google, w którym wprowadzono deftype i reify
proxy
jest czasami preferowany, ponieważ umożliwia modyfikację metod w czasie wykonywania. (np. The Joy of Clojure , wyd. 2, sugeruje, że może to być przydatne do modyfikowania wywołań zwrotnych w module obsługi sieci).Krótka odpowiedź jest taka, że wszystkie mają różne i przydatne cele. Złożoność wynika z potrzeby efektywnej współpracy z różnymi funkcjami podstawowej maszyny JVM.
Jeśli nie potrzebujesz żadnej współpracy z Javą, to w 99% najlepiej jest trzymać się defrecord lub prostej mapy Clojure.
Jeśli Twoje potrzeby są bardziej złożone, poniższy schemat blokowy jest doskonałym narzędziem do wyjaśnienia, dlaczego wybrałbyś jedną z tych opcji zamiast innych:
http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/
źródło