Skip to content

Instantly share code, notes, and snippets.

@meadsteve
Forked from CrowdHailer/clock.ex
Created September 30, 2015 19:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save meadsteve/ad494cafe4756fc816d4 to your computer and use it in GitHub Desktop.
Save meadsteve/ad494cafe4756fc816d4 to your computer and use it in GitHub Desktop.
Creating boundary modules for elixir applications. These have their implementation set during the configuration step. In this example we switch clock between system clock and a dummy clock
# This module represents a behaviour and when used picks from the Application configuration which implementation will be used
defmodule Clock do
@callback now() :: Integer.t
defmacro __using__([]) do
module = Application.get_env(:my_app, :Clock)
quote do
alias unquote(module), as: Clock
end
end
end
# In config/dev.ex and in config/prod.ex we set up the module that we would like to use as the implementation for the Clock boundary
use Mix.Config
config :my_app, Clock: SystemClock
# In config/test.ex we use a Dummy Clock implementation
use Mix.Config
config :my_app, Clock: DummyClock
# Returns a constant value for testing purposes.
defmodule DummyClock do
def now do
# Time at 15:42 on 30th September 2015
14436241340007622
end
end
# All production code just uses the Clock module and has no knowledge of the possible change in implementation
defmodule MyApp do
use Application
use Clock
def time do
Clock.now
end
end
# This is an implementation for the Clock boundary that asks the operating system for the current time.
defmodule SystemClock do
@behaviour Clock
def now do
round(:erlang.system_time(:nano_seconds))
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment