Skip to content

Instantly share code, notes, and snippets.

@sgyyz
Last active May 7, 2019 03:43
Show Gist options
  • Save sgyyz/190d4518d735680e87775ef01b31d5a6 to your computer and use it in GitHub Desktop.
Save sgyyz/190d4518d735680e87775ef01b31d5a6 to your computer and use it in GitHub Desktop.
Elixir Abstract and Extends
defmodule BaseCalculator do
@moduledoc """
Define the base calculator and provide public API.
Define the callback to implement specific logic in child module.
"""
# it should be implemented by child module
@callback do_calculate(num1 :: Integer.t(), num2 :: Integer.t()) :: {:ok, Integer.t()} | {:error, any()}
defmacro __using__(_opts) do
quote do
@behaviour BaseCalculator
@doc """
Public API
"""
def calcualte(num1, num2) do
__MODULE__.do_calculate(num1, num2)
end
end
end
end
defmodule DivideCalculator do
@moduledoc """
Implement divide calculation logic
"""
use BaseCalculator
@impl true
def do_calculate(num1, num2) do
case num2 do
0 -> {:error, :invalid_param}
_ -> {:ok, num1 / num2}
end
end
end
defmodule PlusCalculator do
@moduledoc """
Implement plus calculation logic
"""
use BaseCalculator
@impl true
def do_calculate(num1, num2) do
{:ok, num1 + num2}
end
end
defmodule SubCalculator do
@moduledoc """
Implement substract calculation logic
"""
use BaseCalculator
@impl true
def do_calculate(num1, num2) do
{:ok, num1 * num2}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment