2014-10-06 8 views
28

Verhalten definieren Rückrufe & Protokolle definieren Methoden ohne Signaturen. Module, die ein Protokoll implementieren, sollten alle diese Methoden definieren. Dies gilt auch für Module, die ein Verhalten verwenden. Was ist der semantische Unterschied?Unterschied zwischen Protokoll und Verhalten in Elixir

Ein Unterschied, den ich mir vorstellen kann, ist, dass ein Protokoll für einen einzigen Typ nur einmal implementiert werden kann, da wir ein Verhalten für ein Modul basierend auf unseren Anforderungen mehrfach implementieren können. Mir ist klar, wann ich was benutzen soll. Gibt es noch einen anderen Unterschied als diesen?

+4

Darüber hinaus starten Verhaltensweisen neue Prozesse, bei denen die Callbacks ausgeführt werden, während die Protokollfunktionen im selben Prozess ausgeführt werden. Dies ist der gleiche Kommentar wie unten, aber es wird oft übersehen. Verhalten verbergen die Nebenläufigkeit und Nachrichtenübergabe, aber sie sind immer noch da und die Clientaufrufe und Rückrufaufrufe werden in verschiedenen Prozessen ausgeführt. – rvirding

+1

@rvirding Ich wusste es nicht und ich kann mich nicht daran erinnern, das in irgendeinem Buch oder Tutorial gesehen zu haben. Gibt es einen Teil der Dokumentation oder einen anderen Artikel darüber, wie Verhaltensweisen neue Prozesse implizit auslösen? –

+0

@KrzysztofWende Es wird implizit in http://erlang.org/doc/design_principles/des_princ.html angegeben. Grundsätzlich ist der Begriff "Verhalten" eng mit OTP-Anwendungen und damit mit Supervision-Bäumen verbunden, bei denen es um die Aufrechterhaltung von Prozessen geht. In Erlang abstrahiert ein Verhalten gängige Muster (Client-Server, State-Machine usw.), so dass Sie 'spawn *' nicht aufrufen müssen und Match-Nachrichten nicht manuell anordnen müssen (was fehleranfällig ist). Das Online-Tutorial von Fred Hebert hat mir dabei geholfen, dies zu verstehen: http://learnyousomeerlang.com/what-is-otp#the-common-process-abstracted –

Antwort

30

Protokoll ist Typ/Daten basierte Polymorphie. Wenn ich Enum.each(foo, ...) aufrufen, wird die konkrete Aufzählung aus dem Typ foo bestimmt.

Verhalten ist ein typenloser Plug-in-Mechanismus. Wenn ich GenServer.start(MyModule) rufe, übergebe ich explizit MyModule als ein Plug-in, und der generische Code von GenServer ruft bei Bedarf dieses Modul auf.

+5

Am wichtigsten ist, dass Verhaltensweisen neue Prozesse starten, in denen Callbacks ausgeführt werden Protokollfunktionen werden im selben Prozess ausgeführt. – rvirding

+6

@rvirding Sie liegen falsch. Verhaltensweisen beschreiben nur, welche Funktionen in Ihrem Modul vorhanden sein müssen. Sie machen nichts mit Prozessen. – rightfold

+1

@rightfold ok, dann hat Elixier eine andere Bedeutung als in Erlang, was verwirrend sein könnte, da sie auch Erlang-Verhaltensweisen verwenden. Man könnte sagen, dass ein Erlang-Verhalten die Schnittstellenfunktionen beschreibt, aber es gibt viel mehr, da die Basis für alle die Eigenschaften der Prozesse sind, mit denen die Funktionen interagieren. Dass es Prozesse gibt, darum geht es bei Erlang-Verhalten. – rvirding

13

von José Valim zum gleichen Thema Beantwortet (von Google-Thread, https://groups.google.com/forum/#!msg/elixir-lang-talk/S0NlOoc4ThM/J2aD2hKrtuoJ)

Ein Protokoll ist in der Tat ein Verhalten Dispatching logic +.

Allerdings denke ich, dass Sie den Punkt des Verhaltens fehlen. Verhalten sind sehr nützlich. Zum Beispiel definiert ein GenServer ein Verhalten. Ein Verhalten ist eine Möglichkeit zu sagen: Gib mir ein Modul als Argument und ich werde rufen Sie die folgenden Rückrufe auf, die diese Argumente und so weiter. Ein komplexeres Beispiel für Verhaltensweisen neben einem GenServer sind die Ecto Adapter.

Dies funktioniert jedoch nicht, wenn Sie eine Datenstruktur haben und basierend auf der Datenstruktur versenden möchten. Daher Protokolle.

Verwandte Themen