Last active
April 11, 2019 00:36
-
-
Save sleepiecappy/fb20eb696108ca10c98235078059248a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule App.Implementations do | |
def of(key) do | |
with impls when is_list(impls) <- Application.get_env(:app, :impls), | |
{:ok, module} <- Keyword.fetch(impls, key) do | |
module | |
else | |
:error -> | |
raise KeyError, | |
message: """ | |
:#{key} key is not defined in the implementations for application :app | |
configure it as: | |
config :app, impls: [#{key}: MyImplmentation] | |
""" | |
_ -> | |
raise KeyError, | |
message: ":impls key is not defined in the current environment for application :app" | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule App.MyService do | |
alias App.Twitter | |
def average_tweet_length(handle) do | |
# testable using different implementation for tests | |
# matching on special handlers returns different cases for tests | |
twitter = Twitter.client() | |
handle | |
|> twitter.tweets() | |
|> Enum.map(fn tweet -> String.length(tweet.text) end) | |
|> avg() | |
end | |
def avg(lengths) when lengths != [] do | |
Enum.sum(lengths) / Enum.count(lengths) | |
end | |
def avg(_), do: 0 | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule App.Twitter do | |
@callback tweets(handle :: String.t()) :: list(map()) | |
@doc """ | |
Provides a client implementing this behaviour | |
configure it per env: | |
config :app, impls: [twitter: App.Twitter] | |
""" | |
def client do | |
App.Implementations.of(:twitter) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule App.TwitterAPI do | |
@behaviour App.Twitter | |
def tweets(handle) do | |
# do call to twitter api using HTTP | |
[%{handle: handle, text: "elixir is awesome"}] | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment