2010-04-21 9 views
6

Interfejs (lub klasa abstrakcyjna ze wszystkimi metodami abstrakcyjnymi) jest potężną bronią w języku statycznym, takim jak C#, JAVA. Pozwala na stosowanie różnych typów pochodnych w sposób umundurowany. Wzorce projektowe zachęcają nas do korzystania z interfejsu w jak największym stopniu.Interfejs w dynamicznym języku?

Jednak w języku z dynamicznym typem wszystkie obiekty nie są sprawdzane pod względem typu podczas kompilacji. Nie muszą implementować interfejsu, który będzie używany w określony sposób. Trzeba tylko upewnić się, że mają określone metody (atrybuty) zdefiniowane. Dzięki temu interfejs nie jest konieczny lub przynajmniej nie jest tak użyteczny, jak w języku statycznym.

Czy typowy język dynamiczny (np. Rubinowy) ma interfejs? Jeśli tak, to jakie są zalety posiadania go? Jeśli tak nie jest, to czy tracimy wiele pięknych wzorów, które wymagają interfejsu?

Dzięki.

Odpowiedz

2

Podejrzewam, że nie ma jednej odpowiedzi dla wszystkich języków dynamicznych. W Pythonie na przykład nie ma interfejsów, ale istnieje wiele dziedziczenia. Korzystanie z klas podobnych do interfejsu jest nadal przydatne:

  • Klasy podobne do interfejsu mogą zapewnić domyślną implementację metod;
  • Pisanie kaczkami jest dobre, ale w pewnym stopniu; czasami przydatne jest pisanie isinstance(x, SomeType), szczególnie gdy SomeType zawiera wiele metod.
+0

Lubię drugi punkt! :) – Shuo

+2

Jeśli klasa udostępnia domyślne implementacje, nie ma ona charakteru interfejsu, ponieważ interfejsy różnią się od klas abstrakcyjnych tym, że nie mogą zawierać żadnych implementacji. – sepp2k

+0

@ sepp2k, zgadzam się. To nie jest to, co nazywam interfejsem. – Shuo

1

Interfejsy w językach dynamicznych są przydatne jako dokumentacja interfejsów API, które mogą być sprawdzane automatycznie, np. przez narzędzia programistyczne lub zapewnienia w czasie wykonywania.

Jako przykład, zope.interface jest de facto standardem dla interfejsów w Pythonie. Projekty takie jak Zope i Twisted, które eksponują ogromne interfejsy API do konsumpcji, są użyteczne, ale z tego, co wiem, nie są wykorzystywane zbytnio poza tego typu projektami.

0

W języku Ruby, który jest językiem napisanym dynamicznie i pozwala tylko na pojedyncze dziedziczenie, można naśladować "interfejs" poprzez mixiny, zamiast zanieczyszczać klasę metodami "interfejsu".

Mieszanki częściowo naśladują dziedziczenie wielokrotne, pozwalając obiektowi "dziedziczyć" z wielu źródeł, ale bez dwuznaczności i złożoności faktycznego posiadania wielu rodziców. Jest tylko jeden prawdziwy rodzic.

Aby zaimplementować interfejs (w znaczeniu abstrakcyjnym, a nie rzeczywisty typ interfejsu, jak w językach ze statycznymi typami), definiujesz moduł tak, jakby był interfejsem w języku statycznym. Następnie umieść go w klasie. Voila! Zbierz typ kaczki w zasadniczo interfejs.

bardzo uproszczony przykład:

module Equippable 
    def weapon 
    "broadsword" 
    end 
end 


class Hero 
    include Equippable 

    def hero_method_1 
    end 

    def hero_method_2 
    end 
end 


class Mount 
    include Equippable 

    def mount_method_1 
    end 
end 


h = Hero.new 
h.weapon # outputs "broadsword" 


m = Mount.new 
m.weapon # outputs "broadsword" 

Equippable jest interfejsem dla Hero, mount, a każda inna klasa lub model, który obejmuje go.

(Oczywiście, broń najprawdopodobniej będzie dynamicznie ustawiony przez inicjatora, który został uproszczony daleko w tym przykładzie).

Powiązane problemy