Elixir执行横切关注点的方式是什么?假设我想检查一个用户是否已经取消订阅电子邮件 - 是否可以在任何电子邮件发送功能执行之前这样做?在Elixir文档中找不到交错其他功能的任何内容......就像rails中的before_filter,但是在独立的Elixir应用程序中。可能会发送多个电子邮件 - 通知,市场营销,交易等。添加每个未订阅?手动检查每个功能是非常必要的。 Elixir有更好的方法吗?Elixir - 横切关注点
1
A
回答
0
在Rails中,使用before_filter
实际上导致了糟糕的设计。我知道用这种方式编写代码更容易,但是过了一段时间,代码库会不断增加,在这些回调中添加更多的逻辑,并且开始放松对它们的控制。
您可以在不使用回调的情况下使用简单的函数来执行相同的操作,并且可以通过一种必要的方式保持控制(更容易推理和调试)。
假设你有一个具有多个电子邮件功能
defmodule Mailer do
def send_email1(params) do
# do work
end
def send_email2(params) do
end
# ...
end
取而代之的模块添加某种可以简单的代码添加到每个这些功能正确的before_filter
?这很简单,很容易理解发生了什么。
defmodule Mailer do
def send_email1(params) do
if can_send?(params) do
# do work
end
end
# ...
end
现在你发现你有重复的逻辑。那么......您可以将检查逻辑移动到一个更新的功能,并至少从这些功能中删除if
。但是你也可以创建一个新的抽象,并保持共享逻辑。
defmodule Mailer do
def send_email(email_name, params) do
if can_send?(params) do
do_send_email(email_name, params)
end
end
defp do_send_email("email1", params) do
# do work
end
# ...
end
这比任何带回调的替代方法都简单得多。你保持对它的控制。如果需要,添加或更改共享逻辑并添加条件逻辑很容易。
0
我喜欢使用Elixir的module attributes来启动一连串的tail-call优化函数调用。这可以很容易地在一个地方声明你的回调。
defmodule MyMod do
@before_filter [:check_email]
def check_email(1), do: true
def check_email(state), do: false
def save(state) do
save(state, @before_filter)
end
defp save(state, []) do
# do actual save
{:ok, state}
end
defp save(state, [callback|tail]) do
if :erlang.apply(__MODULE__, callback, [state]) do
save(state, tail)
else
{:error, callback, state}
end
end
end
相关问题
- 1. 安全横切关注点
- 2. 横切关注
- 3. 关于横切关注的好策略
- 4. 分页在CQRS横切关注点与simpleinjector
- 5. 安全可能不是一个横切关注?
- 6. C全局变量中的横切关注
- 7. 横切jQuery中
- 8. @AspectJ切入点与注释
- 9. 分层应用程序中的共享层中的实体(横切关注)?
- 10. JButton.setText横向切割
- 11. 重点关注Div
- 12. Bash脚本横切目录
- 13. 横跨关系
- 14. 在spring中使用批注切入点
- 15. Spring AOP的:获取切入点注解
- 16. 与注释AspectJ切入点参数
- 17. SceneKit节点关注相机
- 18. WordPress的多点关注
- 19. D3 js多线图切换点开/关
- 20. 对外界关闭切换点击
- 21. jquery切换将不会关闭点击
- 22. Boostrap侧切换菜单,点击关闭
- 23. 获取关键焦点之前的clutter_actor关注焦点clutter_actor
- 24. iPad切断横向和纵向内容
- 25. 如何从JS横幅剪切形状?
- 26. 纵向和横向之间切换
- 27. 在滑动横幅中切断文本
- 28. 如何横切父类的方法?
- 29. 使用“纵横适应”切断图像
- 30. 在Wordpress中使用切片横幅
这只是我的意见,但我认为你可以只写有一个功能,比方说,一个特殊的模块,接受用户,检查他是否有订阅,如果他这样做,发送电子邮件。然后你可以在需要它的地方使用这个模块。这样做会更加明确,不会给你带来一些回调魔术。 – JustMichael
@JustMichael - 这不重复吗?我也在考虑一个模块,但由于该电子邮件模块中的每个功能都需要执行相同的操作,因此在每个函数中检查相同的内容都不符合DRY原则。此外,我正在寻找Elixir在尝试学习语言时提供的不同替代方案 – sat
DRY原则不是一项法律 - 只是一个很好的指导方针。有时候不可能避免重复。虽然不重复代码是一个伟大的目标,但可读和可维护的代码也很重要。另外,你认为AOP如何实现这一点?你认为他们不重复代码来做到这一点?它只是隐藏在视野之外。 –