- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这主要是一个函数式编程问题而不是 Elixir 问题,但由于我正在学习 Elixir,所以如果有人可以使用该语言回答它会很好。即便如此,如果有人想给出更笼统的答案,我们将不胜感激。
我自己是一名 OO 程序员,我无法全神贯注于如何根据配置文件更改组件的行为(例如)。
例子:我有一个从数据库加载/保存用户的应用程序。在生产环境中,我希望在 MongoDB 数据库中保存和检索我的用户,而在开发和测试中,我想使用内存映射。如果我使用 OO 语言(比方说 Java)对给定系统进行编程,我会简单地创建一个名为“UserRepository”的接口(interface),其中包含 2 个实现:“MemoryUserRepository”和“MongoDBUserRepository”。然后我会在启动时基于配置文件(或对其进行硬编码,这无关紧要)实例化相应的存储库,并且在启动之后,所有与存储库交互的对象将永远不知道它的实现(它们将使用存储库,但永远不会关心它是在内存中还是在 mongo 中)。这使我能够根据需要创建尽可能多的实现,而要更改系统的行为,我唯一需要做的就是实例化我想要使用的实现。
我想要相同的行为,但在 Elixir 中(让我们使用相同的示例)。因为它不是面向对象的语言,所以我不能使用上述方法。显然我希望它是可扩展的(我可以轻松地传递一个字符串,其中包含我想在每次调用中使用的存储库类型,并使用模式匹配来确定要使用的行为,但这不能很好地扩展,因为每次我都会想要添加一个实现我将不得不查看我模式匹配类型的每一段代码并添加新的实现)。实现这一目标的最佳方法是什么?
提前致谢!
最佳答案
假设您有这两个(或更多)存储库实现,它们实现了相同的接口(interface):
defmodule MyApp.Repository.Memory do
def get(key) do
# ...
end
def put(key, value) do
# ...
end
end
defmodule MyApp.Repository.Disk do
def get(key) do
# ...
end
def put(key, value) do
# ...
end
end
然后您可以编写一个通用存储库模块,该模块将根据 config/config.exs 文件中的配置值将函数调用转发到存储库后端之一:
defmodule MyApp.Repository do
@backend Application.get_env(:my_app, :repository_backend)
defdelegate [get(key), put(key, value)], to: @backend
end
可以进行配置,使其特定于环境(只需查看使用 mix new my_app
新创建的 mix 项目中的默认 config.exs):
# config/config.exs
import_config "#{Mix.env}.exs"
# config/dev.exs
config :my_app, repository_backend: MyApp.Repository.Memory
# config/prod.exs
config :my_app, repository_backend: MyApp.Repository.Disk
在整个代码中,您可以只使用 MyApp.Repository
模块,而无需明确引用其中一个特定实现:
MyApp.Repository.put(:foo, "Hello world!")
value = MyApp.Repository.get(:foo)
关于functional-programming - Elixir - 改变行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34969616/
在 ruby 脚本中,我可以简单地执行以下操作: require 'some-gem' SomeGem.do_something! 如何在 elixir exs 脚本中做类似的事情而不创建一个全新
我正在尝试与 Elixir 中的字符串位进行比较 - 如果它们相等,则 if block 触发或 else block 应该触发。 def show(conn, %{"id" => id}) do
我需要转换这个字符串 "/{foo}/{bar}.{format}" 在 "/#{a["foo"]}/#{a["bar"]}.#{a["format"]}" 因为我有一个包含这些属性的列表。例如 a[
我想在我的 Phoenix 应用程序中注册 2 个根主管,有什么理由不这样做吗? 例子如下 defmodule MyApp.Application do use Application imp
在一个 Elixir 项目中 mix.exs文件,我们像这样包含依赖项 defp deps(_) do [ {:phoenix, "~> 0.6.1"}, {:ecto,
我定义了一个与 guide-started 相关的环境变量,我的 mix.exs 是 defmodule Basic.Mixfile do use Mix.Project def projec
我正在使用 elixir lang getting started 学习 Elixir 编程,而我堆满了 record brace syntax . 这是示例: defrecord FileInfo,
我在谷歌上搜索了很多,但找不到任何关于这个主题的东西——要么 Elixir 的语言太年轻,要么我用错误的术语搜索。 我正在学习 Jose Valim 的 Elixir Portal 教程 (https
Elixir 是否支持类似于 Clojure 的命名匿名函数? 例如,我想做这样的事情: fib_fun = fn fib n -> if n fun = fn (n, _) when
我刚开始学习 Elixir,但有几种 OOP 语言的编程背景,主要是 Ruby。我找到了如何在模块内定义结构的示例: defmodule Example.User do defstruct nam
我定义了一个 Foo像这样的模块: defmodule Foo do def hello(x = %{name: name}) do IO.inspect [x, name] end
有人可以提出一个建议,如何一次用一批x迭代列表BUT吗? 例如: 如果功能存在: ["1","2","3","4","5","6","7","8","9","10"].step(5)|> IO.put
我正在开发 ubuntu 14.04 LTS。我按照 offical website 中给出的说明安装了 elixir在控制台中运行以下行,一切正常 Add Erlang Solutions repo
嗨,Elixir 程序员。 我有大约 2.500 首音乐轨道的列表,我想按不同的参数对其进行排序,例如轨道的标题。 排序应该不区分大小写。 下面的代码有效,但需要大约 100 毫秒到 130 毫秒来对
Elixir 有语言规范文档吗?如果是,它在哪里? Elixir 网站有 library documentation ,我在 guards 上找到了一些文档和 operators ,但我没有找到语言规
阅读有关 Elixir 不变性以及它如何尽可能避免内存复制的文章,这似乎是唯一可能的解释,但我还没有在任何地方看到它的明确说明。例如,当将一个新元素附加到列表时,它被描述为该操作恰好需要 n 个步骤,
我想知道是否有一种方法可以捕获绝对光标位置 在 Elixir 的命令行中。 我知道我必须使用以下 ansi 转义序列\033[6n, 并在执行后: echo -en "\033[6n" 打印出我正在寻
在 Elixir 文档中,他们一直使用带有斜线的奇怪符号,例如: is_boolean/1 IO.puts/1 String.length/1 is_function/2 ++/2 我只是猜测,但我认
我已经开始阅读有关 Elixir 编程语言的信息。 我明白那个: 它是功能性的 它是动态的,但支持@spec 它基于 Erlang VM 我的问题是:它是否有某种 GC? 最佳答案 是的,Erlang
我写了这个测试用例: assert_raise ArgumentError, myFn(a,b) 但它并没有达到我期望的效果。 myFn引发ArgumentError(do: raise Argume
我是一名优秀的程序员,十分优秀!