Учебники

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

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

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

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

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

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

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

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

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

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

Live Demo

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 в модуле. Мы должны определить все функции, реализованные в поведении для всех дочерних модулей. Это можно грубо считать эквивалентным интерфейсам на языках ООП.