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. 關於橫切關注的好策略
- 5. 循環依賴與橫切關注
- 6. CQRS應用橫切關注,如安全
- 7. 分頁在CQRS橫切關注點與simpleinjector
- 8. C全局變量中的橫切關注
- 9. 安全可能不是一個橫切關注?
- 10. 橫切jQuery中
- 11. @AspectJ切入點與註釋
- 12. 分層應用程序中的共享層中的實體(橫切關注)?
- 13. 如何結束Singleton對象隊列,如果我使用Spring AOP橫切關注點+ log4net進行日誌記錄
- 14. JButton.setText橫向切割
- 15. 橫向切割div
- 16. 重點關注Div
- 17. 與註釋屬性匹配的切點切入點
- 18. Bash腳本橫切目錄
- 19. 橫跨關係
- 20. 如何關注切換按鈕?
- 21. jQuery切換同級關注/模糊
- 22. Spring AOP的:獲取切入點註解
- 23. 在spring中使用批註切入點
- 24. 與註釋AspectJ切入點參數
- 25. SceneKit節點關注相機
- 26. WordPress的多點關注
- 27. 如何基於註釋參數編寫切面切入點
- 28. ejabberd 16.03與Elixir,節點在第一個節點關閉時卡住
- 29. 如何防止從WiFi接入點注入橫幅?
- 30. Aspectj匹配切入點,但不關心方法級別的註釋參數
這只是我的意見,但我認爲你可以只寫有一個功能,比方說,一個特殊的模塊,接受用戶,檢查他是否有訂閱,如果他這樣做,發送電子郵件。然後你可以在需要它的地方使用這個模塊。這樣做會更加明確,不會給你帶來一些回調魔術。 – JustMichael
@JustMichael - 這不重複嗎?我也在考慮一個模塊,但由於該電子郵件模塊中的每個功能都需要執行相同的操作,因此在每個函數中檢查相同的內容都不符合DRY原則。此外,我正在尋找Elixir在嘗試學習語言時提供的不同替代方案 – sat
DRY原則不是一項法律 - 只是一個很好的指導方針。有時候不可能避免重複。雖然不重複代碼是一個偉大的目標,但可讀和可維護的代碼也很重要。另外,你認爲AOP如何實現這一點?你認爲他們不重複代碼來做到這一點?它只是隱藏在視野之外。 –