Skip to content

Instantly share code, notes, and snippets.

@Odaeus
Last active April 15, 2021 15:32
Show Gist options
  • Save Odaeus/290848e21209f03584de8d2639a2bfd5 to your computer and use it in GitHub Desktop.
Save Odaeus/290848e21209f03584de8d2639a2bfd5 to your computer and use it in GitHub Desktop.
Elixir module refactoring pattern
# Original
defmodule Service.WebhookHandler do
def register_webhook(name) do
case Registry.register(webhook_id(name), __MODULE__) do
{:ok, _pid} -> :ok
error -> error
end
end
def webhook_id(name), do: "wb-#{name}"
end
defmodule WebhookHandler do
@callback webhook_id(name :: String.t()) :: String.t()
@spec register_webhook(module(), String.t()) :: :ok | {:error, any()}
def register_webhook(module, name) do
case Registry.register(module.webhook_id(name), module) do
{:ok, _pid} -> :ok
error -> error
end
end
end
# New
defmodule Service.WebhookHandler do
@behaviour WebhookHandler
def register_webhook(name) do
WebhookHandler.register_webhook(__MODULE__, name)
end
@impl true
def webhook_id(name), do: "wb-#{name}"
end
# Advanced with default implementation
defmodule WebhookHandler do
@callback webhook_id(name :: String.t()) :: String.t()
defmacro __using__(_opts) do
quote do
@behaviour WebhookHandler
def register_webhook(name), do: WebhookHandler.register_webhook(__MODULE__, name)
end
end
@spec register_webhook(module(), String.t()) :: :ok | {:error, any()}
def register_webhook(module, name) do
case Registry.register(module.webhook_id(name), module) do
{:ok, _pid} -> :ok
error -> error
end
end
end
defmodule Service.WebhookHandler do
use WebhookHandler
@impl true
def webhook_id(name), do: "wb-#{name}"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment