Behaviours in Elixir (and Erlang) are a way to separate and abstract
the generic part of a component (which becomes the behaviour module)
from the specific part (which becomes the callback module). Behaviours
provide a way to:
- Define a set of functions that have to be implemented by a module.
- Ensure that a module implements all the functions in that set.
If you have to, you can think of behaviours like interfaces in object
oriented languages like Java: a set of function signatures that a
module has to implement.
Defining a behaviour
Let us look at an example to create our own behaviour and then use
this generic behaviour to create a module. We'll define a behaviour that
greets people hello and goodbye in different languages.
defmodule GreetBehaviour do
@callback say_hello(name :: string) :: nil
@callback say_bye(name :: string) :: nil
end
The
@callback directive is used to list the functions that
adopting modules will need to define. It also specifies the no. of
arguments, their type and their return values.
Adopting a behaviour
We have successfully defined a behaviour. Now we will adopt and
implement it in multiple modules. Let us create 2 modules implementing
this behaviour in English and Spanish.
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")
When running above program, it produces following result:
Hello Ayush
Goodbye, Ayush
Hola Ayush
Adios Ayush
As you have already seen, we
adopt a behaviour using the
@behaviour directive in the module. We have to define all the functions implemented in the behaviour for all the
child modules. This can roughly be considered equivalent to interfaces in OOP languages.
No comments:
Post a Comment