Эликсир - Поведение

Поведение в Elixir (и Erlang) - это способ отделить и абстрагировать общую часть компонента (которая становится модулем поведения) от конкретной части (которая становится модулем обратного вызова). Поведение дает возможность -

  • Определите набор функций, которые должны быть реализованы модулем.
  • Убедитесь, что модуль реализует все функции в этом наборе.

Если вам нужно, вы можете думать о поведении как о интерфейсах в объектно-ориентированных языках, таких как Java: набор сигнатур функций, которые модуль должен реализовать.

Определение поведения

Давайте рассмотрим пример, чтобы создать собственное поведение, а затем использовать это общее поведение для создания модуля. Мы определим поведение, при котором люди приветствуют и прощают на разных языках.

defmodule GreetBehaviour do
   @callback say_hello(name :: string) :: nil
   @callback say_bye(name :: string) :: nil
end

В @callbackДиректива используется для перечисления функций, которые необходимо определить модулям. Также указывается номер. аргументов, их типа и возвращаемых значений.

Принятие поведения

Мы успешно определили поведение. Теперь мы примем и реализуем его в нескольких модулях. Давайте создадим два модуля, реализующих это поведение на английском и испанском языках.

defmodule GreetBehaviour do
   @callback say_hello(name :: string) :: nil
   @callback say_bye(name :: string) :: nil
end

defmodule EnglishGreet do
   @behaviour GreetBehaviour
   def say_hello(name), do: IO.puts("Hello " <> name)
   def say_bye(name), do: IO.puts("Goodbye, " <> name)
end

defmodule SpanishGreet do
   @behaviour GreetBehaviour
   def say_hello(name), do: IO.puts("Hola " <> name)
   def say_bye(name), do: IO.puts("Adios " <> name)
end

EnglishGreet.say_hello("Ayush")
EnglishGreet.say_bye("Ayush")
SpanishGreet.say_hello("Ayush")
SpanishGreet.say_bye("Ayush")

Когда вышеуказанная программа запускается, она дает следующий результат -

Hello Ayush
Goodbye, Ayush
Hola Ayush
Adios Ayush

Как вы уже видели, мы применяем поведение, используя @behaviourдиректива в модуле. Мы должны определить все функции, реализованные в поведении для всех дочерних модулей. Это можно примерно считать эквивалентом интерфейсов на языках ООП.