2012-03-11 12 views
16

Spędziłem trochę czasu, próbując zrozumieć multimethody Clojure. Głównym argumentem "multitetod" pro, o ile rozumiem, jest ich elastyczność, jednak mylę się z argumentacją, dlaczego multimetody są lepsze niż proste stwierdzenie, czy też przypadek. Czy ktoś mógłby, proszę, wyjaśnić, gdzie jest narysowana granica między polimorfizmem i nadlepionym przypadkiem?Dlaczego multimetody Clojure są lepsze niż stwierdzenia "jeśli" lub "case"

EDYCJA: Powinienem był wyraźniej odpowiedzieć na pytanie, że bardziej interesuje mnie porównanie z stwierdzeniem "jeśli". Wielkie dzięki za odpowiedzi!

+0

Gdzie jest linia narysowana między poleceniem if a overglorified goto? – Kevin

+1

Możesz być zainteresowany http://stackoverflow.com/q/5986120/625403, który nie jest dokładnie duplikatem, ale jest blisko spokrewniony. – amalloy

Odpowiedz

16

Różnica między multimethods a dużymi if-statement polega na tym, że musisz zmodyfikować funkcję zawierającą case-statement, aby dodać przypadki do instrukcji if. Możesz dodać nową metodę bez dotykania istniejących wcześniej metod.

Jeśli więc zdefiniujesz multimetr w bibliotece i chcesz, aby użytkownicy mogli go rozszerzyć dla swoich własnych typów danych, nie stanowi to problemu. Jeśli zamiast tego używałbyś instrukcji if, byłby to duży problem.

+0

Ahh, to jest coś, czego nie rozumiem dobrze, dzięki! Więc multimethods nie są ograniczone do przestrzeni nazw, gdzie zadeklarowano defmulti? – Iger

+0

@Iger To prawda. – sepp2k

23

Powiedzmy, że mamy typy A, B, C, D i E oraz metody m1, m2, m3 przyjmujące pojedynczy argument poprzednich typów. Możesz umieścić je w takiej tabeli:

| A | B | C | D | E | 
m1 | | | | | | 
m2 | | | | | | 
m3 | | | | | | 

Strategia "przełączania" implementuje jeden wiersz tej tabeli na raz. Załóżmy, że dodajesz nowy typ F. Będziesz musiał zmodyfikować wszystkie implementacje, aby je obsłużyć.

Polimorfizm oparty na klasach (C++, Java itp.) Pozwala zamiast tego zaimplementować całą kolumnę. Dodanie nowego typu jest więc łatwe, ponieważ nie trzeba zmieniać już zdefiniowanych klas. Ale dodanie nowej metody jest trudne, ponieważ będziesz musiał dodać ją do wszystkich innych typów.

Metody multimethod umożliwiają niezależne od siebie wprowadzanie pojedynczych komórek tabeli.

Ta elastyczność jest jeszcze większa, jeśli trzeba wysyłać wiele argumentów. Każdy nowy argument dodaje inny wymiar do tej tabeli, a zarówno wysyłki oparte na swich, jak i oparte na klasach, stają się bardzo złożone dość szybko (np. Wzorzec Odwiedzającego).

Zauważ, że multimetody są nawet bardziej ogólne niż przedstawione, ponieważ możesz wysyłać praktycznie wszystko, a nie tylko typy argumentów.

1

Powyższa odpowiedź może zostać poszerzona o this article. Dobrze się tłumaczy mocą protokołów. Pomyśl o multimetodach jako protokołach o wielu wymiarach.

Powiązane problemy