Passing functions between processes

Welcome to the forum!

That ceremony could overcomplicate things at least initially as I suspect that there already is a GenServer callback module implementation that does most of the work:

I’ve got a pretty generic GenServer that I’ve created that I want to use in a few contexts.

What it sounds like is that the GenServer callback module in itself needs further specialization by being bound on yet another separate callback module - within this discussion the strategy callback module.

So really the essence here is that a callback module is simply the name of a module that promises to implement certain functions that the behaviour module will invoke on it.

The name of the strategy callback module can be passed as one of the arguments to the init/1 callback and stored in the GenServer state, e.g.:

  def init(args) do
    with {:ok, strategy} <- Keyword.fetch(args, :strategy) do
      {:ok, %{strategy: strategy}}
    else
      _ ->
        {:stop, :badarg}
    end
  end

Then later the function can be called as (provided the GenServer state is bound to state):

result = state.strategy.the_fun(the_arg)

or

result = apply(state.strategy, :the_fun, [the_arg])

Kernel.apply/2

At the simplest level I would compare behaviours to the strategy pattern though there are also elements of the template method pattern.

3 Likes