2016-08-22 25 views
4

在elixir中共享相同功能的設計模式是什麼?在elixir中共享相同功能的設計模式是什麼?

例如, 我有一個應用程序「採取」結構,「轉換」結構爲不同的格式,並「推」到某些存儲。 我有3個結構,通過這條管道,有3個轉換規則和3個存儲。

項目使用gen_stage包,它有如下結構:

(book) |producer| -> |transformer| -> |indexer| 
(article)|producer| -> |transformer| -> |indexer| 
(post) |producer| -> |transformer| -> |indexer| 

每一級是一個單獨的模塊,即Book.Producer,Book.Transformer,Book.Indexer。

階段在同一垂直線上做相同的東西但與不同的實體。即Book.Producer採取從數據庫書籍,Article.Producer採取從數據庫物品等

的「從數據庫中以」片是相當普遍的,並在所有的管道,可以重複使用,即

alias Experimental.GenStage 

defmodule Books.Producer do 
    use GenStage 

    def start_link do 
    GenStage.start_link(__MODULE__, [], name: __MODULE__) 
    end 

    def init([]) do 
    {:producer, []} 
    end 

    def handle_demand(demand, processed) when demand > 0 do 
    events = Repo.all Book 
    {:noreply, events, processed ++ events} 
    end 
end 

變換器對由數據庫產生的實體運行一個函數。索引器將變壓器記錄推入另一個存儲器。

在一個有很多重複的幼稚方法中,我可以在所有這些步驟中完成9個(書3個,文章3個,Post 3個)模塊。

我有什麼選擇來提取類似功能的位並在使用它的模塊之間共享它。

也許我可以通過在初始化階段傳遞參數來配置它,或者只是仍然有9個模塊,但重構函數到另一個模塊中。最佳做法是什麼?

+0

如果不知道9個函數/模塊之間的數據結構究竟是什麼共同的以及特定的結構,這有點難以回答。你能否包含一些實際的代碼? – Dogbert

+0

@Dogbert我試圖儘可能的明確,沒有太多真實的代碼,但我添加了一個例子來說明什麼是「常見」。謝謝! –

回答

1

您提到的情況的一個可能選項是在啓動進程時(例如從監​​督樹中)將您試圖從中提取的模式模塊(例如Book,Post等)作爲選項傳遞給該進程, 。在撥打start_link時,您會收到這些選項,然後在撥打GenStage.start_link時可以將它們作爲第二個參數傳遞。

這會導致這些選項在GenStage啓動時作爲參數傳遞給init。此時,您可以將該模塊置於該狀態(例如,與元組中的processed列表一起),以便每次調用handle_demand時都會傳遞該模塊。在那裏,您最終可以將其用作致電Repo.all的參數。

模塊可以像任何其他值一樣傳遞,有時您可以使用它來重用代碼 - 這是一個可能派上用場的例子!

您可以對您的流程的其他部分使用類似的方法 - 只需確定在啓動流程時作爲選項的變化和指定方式。例如,轉換函數將成爲您第二步選項的良好選擇。有你能夠做到這幾個方面:

  • 通實現某種功能的模塊 - 退房Behaviours的文檔以得到一些保證的功能模塊中確實存在;
  • 在現有模塊中傳遞捕獲的函數,例如&BookTransformer.transform/1;
  • 傳遞匿名函數:fn data -> transform_all_the(data) end

與模塊一樣,函數是Elixir中的一等公民。它們可以像價值一樣傳遞。這是函數式編程語言中的通用代碼重用模式。

+0

你會如何「通過」轉換功能作爲選項?是否與傳遞類似於模塊名稱的東西一樣,即'BookTransformer',並使每個'Transformer'響應'.transform'函數,類似於隱式協議。建議如何爲Transformer定義協議,然後讓您傳遞的模塊符合該協議?非常感謝! –

+0

你有一些選擇: *傳遞一個模塊,實現你想要的功能,如你所說(查看行爲來確定它_does_實現函數) *傳遞一個「捕獲」函數,即'&BookTransformer.transform/1' *傳遞一個匿名函數:'fn data - > do_something_with(data)end' 這些都是可以傳遞的所有有效值:) –

+0

Thiago,請更新原來的答案與這個額外的信息,我會把它標記爲接受,非常感謝您的意見! –

相關問題